Commit 416f87f1 authored by Dries's avatar Dries

- Patch #785782 by cafuego: support comments in built queries.

parent 520d8e6e
......@@ -43,6 +43,8 @@ public function execute() {
}
public function __toString() {
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
// Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields);
......@@ -50,10 +52,10 @@ public function __toString() {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
return "INSERT INTO {" . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
}
$query = "INSERT INTO {" . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
$max_placeholder = 0;
$values = array();
......@@ -143,6 +145,8 @@ public function execute() {
public function __toString() {
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
// Set defaults.
if ($this->updateFields) {
......@@ -164,7 +168,7 @@ public function __toString() {
$insert_fields = $this->insertFields + $this->keyFields;
$query = "INSERT INTO {" . $this->table . '} (' . implode(', ', array_keys($insert_fields)) . ') VALUES ';
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', array_keys($insert_fields)) . ') VALUES ';
$max_placeholder = 0;
$values = array();
......
......@@ -71,6 +71,8 @@ public function execute() {
}
public function __toString() {
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
// Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields);
......@@ -78,10 +80,10 @@ public function __toString() {
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
return "INSERT INTO {" . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
}
$query = "INSERT INTO {" . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
$max_placeholder = 0;
$values = array();
......
......@@ -240,6 +240,13 @@ abstract class Query implements QueryPlaceholderInterface {
*/
protected $nextPlaceholder = 0;
/**
* An array of comments that can be prepended to a query.
*
* @var array
*/
protected $comments = array();
public function __construct(DatabaseConnection $connection, $options) {
$this->connection = $connection;
$this->queryOptions = $options;
......@@ -263,6 +270,44 @@ public function __construct(DatabaseConnection $connection, $options) {
public function nextPlaceholder() {
return $this->nextPlaceholder++;
}
/**
* Adds a comment to the query.
*
* By adding a comment to a query, you can more easily find it in your
* query log or the list of active queries on an sql server. This allows
* for easier debugging and allows you to more easily find where a query
* with a performance problem is being generated.
*
* @param $comment
* The comment string to be inserted into the query.
* @return Query
* The called object.
*/
public function comment($comment) {
$this->comments[] = $comment;
return $this;
}
/**
* Returns a reference to the comments array for the query.
*
* Because this method returns by reference, alter hooks may edit the comments
* array directly to make their changes. If just adding comments, however, the
* use of comment() is preferred.
*
* Note that this method must be called by reference as well:
*
* @code
* $comments =& $query->getComments();
* @endcode
*
* @return
* A reference to the comments array structure.
*/
public function &getComments() {
return $this->comments;
}
}
/**
......@@ -468,11 +513,14 @@ public function execute() {
public function __toString() {
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
// Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields);
if (!empty($this->fromQuery)) {
return "INSERT INTO {" . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
}
// For simplicity, we will use the $placeholders array to inject
......@@ -482,7 +530,7 @@ public function __toString() {
$placeholders = array_pad($placeholders, count($this->defaultFields), 'default');
$placeholders = array_pad($placeholders, count($this->insertFields), '?');
return 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES (' . implode(', ', $placeholders) . ')';
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES (' . implode(', ', $placeholders) . ')';
}
/**
......@@ -900,7 +948,11 @@ public function execute() {
}
public function __toString() {
$query = 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} ';
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
$query = $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} ';
if (count($this->condition)) {
......@@ -940,7 +992,10 @@ public function execute() {
}
public function __toString() {
return 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
}
}
......@@ -1100,6 +1155,10 @@ public function execute() {
}
public function __toString() {
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
// Expressions take priority over literal fields, so we process those first
// and remove any literal fields that conflict.
$fields = $this->fields;
......@@ -1114,7 +1173,7 @@ public function __toString() {
$update_fields[] = $field . '=:db_update_placeholder_' . ($max_placeholder++);
}
$query = 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields);
$query = $comments . 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields);
if (count($this->condition)) {
$this->condition->compile($this->connection, $this);
......
......@@ -1317,8 +1317,11 @@ public function countQuery() {
public function __toString() {
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
// SELECT
$query = 'SELECT ';
$query = $comments . 'SELECT ';
if ($this->distinct) {
$query .= 'DISTINCT ';
}
......
......@@ -33,16 +33,19 @@ public function execute() {
}
public function __toString() {
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
// Produce as many generic placeholders as necessary.
$placeholders = array_fill(0, count($this->insertFields), '?');
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
return "INSERT INTO {" . $this->table . '} (' . implode(', ', $this->insertFields) . ') ' . $this->fromQuery;
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') ' . $this->fromQuery;
}
return 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $this->insertFields) . ') VALUES (' . implode(', ', $placeholders) . ')';
}
}
......@@ -143,7 +146,10 @@ public function execute() {
*/
class TruncateQuery_sqlite extends TruncateQuery {
public function __toString() {
return 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} ';
// Create a comments string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : '';
return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} ';
}
}
......
......@@ -1015,7 +1015,6 @@ class DatabaseDeleteTruncateTestCase extends DatabaseTestCase {
$this->assertEqual($num_records_before, $num_records_after + $num_deleted, t('Deletion adds up.'));
}
/**
* Confirm that we can truncate a whole table successfully.
*/
......@@ -1274,6 +1273,27 @@ class DatabaseSelectTestCase extends DatabaseTestCase {
$this->assertEqual($num_records, 4, t('Returned the correct number of rows.'));
}
/**
* Test rudimentary SELECT statement with a COMMENT.
*/
function testSimpleComment() {
$query = db_select('test')->comment('Testing query comments');
$name_field = $query->addField('test', 'name');
$age_field = $query->addField('test', 'age', 'age');
$result = $query->execute();
$num_records = 0;
foreach ($result as $record) {
$num_records++;
}
$query = (string)$query;
$expected = "/* Testing query comments */ SELECT test.name AS name, test.age AS age\nFROM \n{test} test";
$this->assertEqual($num_records, 4, t('Returned the correct number of rows.'));
$this->assertEqual($query, $expected, t('The flattened query contains the comment string.'));
}
/**
* Test basic conditionals on SELECT statements.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment