Error message
You are browsing documentation for drupal 7.x, which is not supported anymore. Read the updated version of this page for drupal 11.x (the latest version).class InsertQuery
General class for an abstracted INSERT query.
Hierarchy
- class \Query implements \QueryPlaceholderInterface
- class \InsertQuery extends \Query
Expanded class hierarchy of InsertQuery
Related topics
- Database abstraction layer
- Allow the use of different database servers using the same code base.
1 string reference to 'InsertQuery'
- DatabaseConnection::insert in includes/
database/ database.inc - Prepares and returns an INSERT query object.
File
-
includes/
database/ query.inc, line 441
View source
class InsertQuery extends Query {
/**
* The table on which to insert.
*
* @var string
*/
protected $table;
/**
* An array of fields on which to insert.
*
* @var array
*/
protected $insertFields = array();
/**
* An array of fields that should be set to their database-defined defaults.
*
* @var array
*/
protected $defaultFields = array();
/**
* A nested array of values to insert.
*
* $insertValues is an array of arrays. Each sub-array is either an
* associative array whose keys are field names and whose values are field
* values to insert, or a non-associative array of values in the same order
* as $insertFields.
*
* Whether multiple insert sets will be run in a single query or multiple
* queries is left to individual drivers to implement in whatever manner is
* most appropriate. The order of values in each sub-array must match the
* order of fields in $insertFields.
*
* @var array
*/
protected $insertValues = array();
/**
* A SelectQuery object to fetch the rows that should be inserted.
*
* @var SelectQueryInterface
*/
protected $fromQuery;
/**
* Constructs an InsertQuery object.
*
* @param DatabaseConnection $connection
* A DatabaseConnection object.
* @param string $table
* Name of the table to associate with this query.
* @param array $options
* Array of database options.
*/
public function __construct($connection, $table, array $options = array()) {
if (!isset($options['return'])) {
$options['return'] = Database::RETURN_INSERT_ID;
}
parent ::__construct ($connection, $options);
$this->table = $table;
}
/**
* Adds a set of field->value pairs to be inserted.
*
* This method may only be called once. Calling it a second time will be
* ignored. To queue up multiple sets of values to be inserted at once,
* use the values() method.
*
* @param $fields
* An array of fields on which to insert. This array may be indexed or
* associative. If indexed, the array is taken to be the list of fields.
* If associative, the keys of the array are taken to be the fields and
* the values are taken to be corresponding values to insert. If a
* $values argument is provided, $fields must be indexed.
* @param $values
* An array of fields to insert into the database. The values must be
* specified in the same order as the $fields array.
*
* @return InsertQuery
* The called object.
*/
public function fields(array $fields, array $values = array()) {
if (empty($this->insertFields )) {
if (empty($values)) {
if (!is_numeric (key ($fields))) {
$values = array_values ($fields);
$fields = array_keys ($fields);
}
}
$this->insertFields = $fields;
if (!empty($values)) {
$this->insertValues [] = $values;
}
}
return $this;
}
/**
* Adds another set of values to the query to be inserted.
*
* If $values is a numeric-keyed array, it will be assumed to be in the same
* order as the original fields() call. If it is associative, it may be
* in any order as long as the keys of the array match the names of the
* fields.
*
* @param $values
* An array of values to add to the query.
*
* @return InsertQuery
* The called object.
*/
public function values(array $values) {
if (is_numeric (key ($values))) {
$this->insertValues [] = $values;
}
else {
// Reorder the submitted values to match the fields array.
foreach ($this->insertFields as $key) {
$insert_values[$key] = $values[$key];
}
// For consistency, the values array is always numerically indexed.
$this->insertValues [] = array_values ($insert_values);
}
return $this;
}
/**
* Specifies fields for which the database defaults should be used.
*
* If you want to force a given field to use the database-defined default,
* not NULL or undefined, use this method to instruct the database to use
* default values explicitly. In most cases this will not be necessary
* unless you are inserting a row that is all default values, as you cannot
* specify no values in an INSERT query.
*
* Specifying a field both in fields() and in useDefaults() is an error
* and will not execute.
*
* @param $fields
* An array of values for which to use the default values
* specified in the table definition.
*
* @return InsertQuery
* The called object.
*/
public function useDefaults(array $fields) {
$this->defaultFields = $fields;
return $this;
}
/**
* Sets the fromQuery on this InsertQuery object.
*
* @param SelectQueryInterface $query
* The query to fetch the rows that should be inserted.
*
* @return InsertQuery
* The called object.
*/
public function from(SelectQueryInterface $query) {
$this->fromQuery = $query;
return $this;
}
/**
* Executes the insert query.
*
* @return
* The last insert ID of the query, if one exists. If the query
* was given multiple sets of values to insert, the return value is
* undefined. If no fields are specified, this method will do nothing and
* return NULL. That makes it safe to use in multi-insert loops.
*/
public function execute() {
// If validation fails, simply return NULL. Note that validation routines
// in preExecute() may throw exceptions instead.
if (!$this->preExecute ()) {
return NULL;
}
// 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 )) {
$sql = (string) $this;
// The SelectQuery may contain arguments, load and pass them through.
return $this->connection
->query ($sql, $this->fromQuery
->getArguments (), $this->queryOptions );
}
$last_insert_id = 0;
// Each insert happens in its own query in the degenerate case. However,
// we wrap it in a transaction so that it is atomic where possible. On many
// databases, such as SQLite, this is also a notable performance boost.
$transaction = $this->connection
->startTransaction ();
try {
$sql = (string) $this;
foreach ($this->insertValues as $insert_values) {
$last_insert_id = $this->connection
->query ($sql, $insert_values, $this->queryOptions );
}
} catch (Exception $e) {
// One of the INSERTs failed, rollback the whole batch.
$transaction->rollback ();
// Rethrow the exception for the calling code.
throw $e;
}
// Re-initialize the values array so that we can re-use this query.
$this->insertValues = array();
// Transaction commits here where $transaction looses scope.
return $last_insert_id;
}
/**
* Implements PHP magic __toString method to convert the query to a string.
*
* @return string
* The prepared statement.
*/
public function __toString() {
// Create a sanitized comment string to prepend to the query.
$comments = $this->connection
->makeComment ($this->comments );
// Default fields are always placed first for consistency.
$insert_fields = array_merge ($this->defaultFields , $this->insertFields );
if (!empty($this->fromQuery )) {
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode (', ', $insert_fields) . ') ' . $this->fromQuery ;
}
// For simplicity, we will use the $placeholders array to inject
// default keywords even though they are not, strictly speaking,
// placeholders for prepared statements.
$placeholders = array();
$placeholders = array_pad ($placeholders, count ($this->defaultFields ), 'default');
$placeholders = array_pad ($placeholders, count ($this->insertFields ), '?');
return $comments . 'INSERT INTO {' . $this->table . '} (' . implode (', ', $insert_fields) . ') VALUES (' . implode (', ', $placeholders) . ')';
}
/**
* Preprocesses and validates the query.
*
* @return
* TRUE if the validation was successful, FALSE if not.
*
* @throws FieldsOverlapException
* @throws NoFieldsException
*/
public function preExecute() {
// Confirm that the user did not try to specify an identical
// field and default field.
if (array_intersect ($this->insertFields , $this->defaultFields )) {
throw new FieldsOverlapException ('You may not specify the same field to have a value and a schema-default value.');
}
if (!empty($this->fromQuery )) {
// We have to assume that the used aliases match the insert fields.
// Regular fields are added to the query before expressions, maintain the
// same order for the insert fields.
// This behavior can be overridden by calling fields() manually as only the
// first call to fields() does have an effect.
$this->fields (array_merge (array_keys ($this->fromQuery
->getFields ()), array_keys ($this->fromQuery
->getExpressions ())));
}
else {
// Don't execute query without fields.
if (count ($this->insertFields ) + count ($this->defaultFields ) == 0) {
throw new NoFieldsException ('There are no fields available to insert with.');
}
}
// If no values have been added, silently ignore this query. This can happen
// if values are added conditionally, so we don't want to throw an
// exception.
if (!isset($this->insertValues [0]) && count ($this->insertFields ) > 0 && empty($this->fromQuery )) {
return FALSE;
}
return TRUE;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
InsertQuery::$defaultFields | protected | property | An array of fields that should be set to their database-defined defaults. | ||
InsertQuery::$fromQuery | protected | property | A SelectQuery object to fetch the rows that should be inserted. | ||
InsertQuery::$insertFields | protected | property | An array of fields on which to insert. | ||
InsertQuery::$insertValues | protected | property | A nested array of values to insert. | ||
InsertQuery::$table | protected | property | The table on which to insert. | ||
InsertQuery::execute | public | function | Executes the insert query. | Overrides Query::execute | 3 |
InsertQuery::fields | public | function | Adds a set of field->value pairs to be inserted. | ||
InsertQuery::from | public | function | Sets the fromQuery on this InsertQuery object. | ||
InsertQuery::preExecute | public | function | Preprocesses and validates the query. | ||
InsertQuery::useDefaults | public | function | Specifies fields for which the database defaults should be used. | ||
InsertQuery::values | public | function | Adds another set of values to the query to be inserted. | ||
InsertQuery::__construct | public | function | Constructs an InsertQuery object. | Overrides Query::__construct | |
InsertQuery::__toString | public | function | Implements PHP magic __toString method to convert the query to a string. | Overrides Query::__toString | 3 |
Query::$comments | protected | property | An array of comments that can be prepended to a query. | ||
Query::$connection | protected | property | The connection object on which to run this query. | ||
Query::$connectionKey | protected | property | The key of the connection object. | ||
Query::$connectionTarget | protected | property | The target of the connection object. | ||
Query::$nextPlaceholder | protected | property | The placeholder counter. | ||
Query::$queryOptions | protected | property | The query options to pass on to the connection object. | ||
Query::$uniqueIdentifier | protected | property | A unique identifier for this query object. | ||
Query::comment | public | function | Adds a comment to the query. | ||
Query::getComments | public | function | Returns a reference to the comments array for the query. | ||
Query::nextPlaceholder | public | function | Gets the next placeholder value for this query object. | Overrides QueryPlaceholderInterface::nextPlaceholder | |
Query::uniqueIdentifier | public | function | Returns a unique identifier for this object. | Overrides QueryPlaceholderInterface::uniqueIdentifier | |
Query::__clone | public | function | Implements the magic __clone function. | 1 | |
Query::__sleep | public | function | Implements the magic __sleep function to disconnect from the database. | ||
Query::__wakeup | public | function | Implements the magic __wakeup function to reconnect to the database. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.