summaryrefslogtreecommitdiffstatshomepage
path: root/includes/database/sqlite/query.inc
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2008-11-23 06:06:15 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2008-11-23 06:06:15 +0000
commit9de3b9cb74fa8a3cd70fff00c7198d291f2f88b3 (patch)
tree830c233f8b2d47e68b9cfe0cff10495a6ebfa3f0 /includes/database/sqlite/query.inc
parent842a0fae20f3aec089b4d99adb540a440c67d10d (diff)
downloaddrupal-9de3b9cb74fa8a3cd70fff00c7198d291f2f88b3.tar.gz
drupal-9de3b9cb74fa8a3cd70fff00c7198d291f2f88b3.zip
#67349 by chx, Damien Tournoud, and paranojik: SQLite support in core! Yeah! :D
Diffstat (limited to 'includes/database/sqlite/query.inc')
-rw-r--r--includes/database/sqlite/query.inc131
1 files changed, 131 insertions, 0 deletions
diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc
new file mode 100644
index 000000000000..364b618b4c3e
--- /dev/null
+++ b/includes/database/sqlite/query.inc
@@ -0,0 +1,131 @@
+<?php
+// $Id $
+
+/**
+ * @ingroup database
+ * @{
+ */
+
+/**
+ * SQLite specific implementation of InsertQuery.
+ *
+ * We ignore all the default fields and use the clever SQLite syntax:
+ * INSERT INTO table DEFAULT VALUES
+ * for degenerated "default only" queries.
+ */
+class InsertQuery_sqlite extends InsertQuery {
+
+ public function execute() {
+ if (count($this->insertFields) + count($this->defaultFields) == 0) {
+ return NULL;
+ }
+ if (count($this->insertFields)) {
+ return parent::execute();
+ }
+ else {
+ return $this->connection->query('INSERT INTO {'. $this->table .'} DEFAULT VALUES', array(), $this->queryOptions);
+ }
+ }
+
+ public function __toString() {
+ // Produce as many generic placeholders as necessary.
+ $placeholders = array_fill(0, count($this->insertFields), '?');
+ return 'INSERT INTO {'. $this->table .'} ('. implode(', ', $this->insertFields) .') VALUES ('. implode(', ', $placeholders) .')';
+ }
+
+}
+
+/**
+ * SQLite specific implementation of UpdateQuery.
+ *
+ * SQLite counts all the rows that match the conditions as modified, even if they
+ * will not be affected by the query. We workaround this by ensuring that
+ * we don't select those rows.
+ *
+ * A query like this one:
+ * UPDATE test SET name = 'newname' WHERE tid = 1
+ * will become:
+ * UPDATE test SET name = 'newname' WHERE tid = 1 AND name <> 'newname'
+ */
+class UpdateQuery_sqlite extends UpdateQuery {
+
+ /**
+ * Helper function that removes the fields that are already in a condition.
+ *
+ * @param $fields
+ * The fields.
+ * @param QueryConditionInterface $condition
+ * A database condition.
+ */
+ protected function removeFieldsInCondition(&$fields, QueryConditionInterface $condition) {
+ foreach ($condition->conditions() as $child_condition) {
+ if ($child_condition['field'] instanceof QueryConditionInterface) {
+ $this->removeFieldsInCondition($fields, $child_condition['field']);
+ }
+ else {
+ unset($fields[$child_condition['field']]);
+ }
+ }
+ }
+
+ public function execute() {
+ // Get the fields used in the update query, and remove those that are already
+ // in the condition.
+ $fields = $this->expressionFields + $this->fields;
+ $this->removeFieldsInCondition($fields, $this->condition);
+
+ // Add the inverse of the fields to the condition.
+ $condition = db_or();
+ foreach ($fields as $field => $data) {
+ if (is_array($data)) {
+ // The field is an expression.
+ $condition->condition($field, $data['expression'], '<>');
+ // The IS NULL operator is badly managed by DatabaseCondition.
+ $condition->where($field . ' IS NULL');
+ }
+ else if (is_null($data)) {
+ // The field will be set to NULL.
+ // The IS NULL operator is badly managed by DatabaseCondition.
+ $condition->where($field . ' IS NOT NULL');
+ }
+ else {
+ $condition->condition($field, $data, '<>');
+ // The IS NULL operator is badly managed by DatabaseCondition.
+ $condition->where($field . ' IS NULL');
+ }
+ }
+ if (count($condition)) {
+ $condition->compile($this->connection);
+ $this->condition->where((string) $condition, $condition->arguments());
+ }
+ return parent::execute();
+ }
+
+}
+
+/**
+ * SQLite specific implementation of DeleteQuery.
+ *
+ * When the WHERE is omitted from a DELETE statement and the table being deleted
+ * has no triggers, SQLite uses an optimization to erase the entire table content
+ * without having to visit each row of the table individually.
+ *
+ * Prior to SQLite 3.6.5, SQLite does not return the actual number of rows deleted
+ * by that optimized "truncate" optimization.
+ */
+class DeleteQuery_sqlite extends DeleteQuery {
+ public function execute() {
+ if (!count($this->condition)) {
+ $total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
+ parent::execute();
+ return $total_rows;
+ }
+ else {
+ return parent::execute();
+ }
+ }
+}
+
+/**
+ * @} End of "ingroup database".
+ */