3 namespace Drupal\Core\Database\Query;
6 * Provides common functionality for INSERT and UPSERT queries.
13 * The table on which to insert.
20 * An array of fields on which to insert.
24 protected $insertFields = [];
27 * An array of fields that should be set to their database-defined defaults.
31 protected $defaultFields = [];
34 * A nested array of values to insert.
36 * $insertValues is an array of arrays. Each sub-array is either an
37 * associative array whose keys are field names and whose values are field
38 * values to insert, or a non-associative array of values in the same order
41 * Whether multiple insert sets will be run in a single query or multiple
42 * queries is left to individual drivers to implement in whatever manner is
43 * most appropriate. The order of values in each sub-array must match the
44 * order of fields in $insertFields.
48 protected $insertValues = [];
51 * Adds a set of field->value pairs to be inserted.
53 * This method may only be called once. Calling it a second time will be
54 * ignored. To queue up multiple sets of values to be inserted at once,
55 * use the values() method.
57 * @param array $fields
58 * An array of fields on which to insert. This array may be indexed or
59 * associative. If indexed, the array is taken to be the list of fields.
60 * If associative, the keys of the array are taken to be the fields and
61 * the values are taken to be corresponding values to insert. If a
62 * $values argument is provided, $fields must be indexed.
63 * @param array $values
64 * (optional) An array of fields to insert into the database. The values
65 * must be specified in the same order as the $fields array.
70 public function fields(array $fields, array $values = []) {
71 if (empty($this->insertFields)) {
73 if (!is_numeric(key($fields))) {
74 $values = array_values($fields);
75 $fields = array_keys($fields);
78 $this->insertFields = $fields;
79 if (!empty($values)) {
80 $this->insertValues[] = $values;
88 * Adds another set of values to the query to be inserted.
90 * If $values is a numeric-keyed array, it will be assumed to be in the same
91 * order as the original fields() call. If it is associative, it may be
92 * in any order as long as the keys of the array match the names of the
95 * @param array $values
96 * An array of values to add to the query.
101 public function values(array $values) {
102 if (is_numeric(key($values))) {
103 $this->insertValues[] = $values;
105 elseif ($this->insertFields) {
106 // Reorder the submitted values to match the fields array.
107 foreach ($this->insertFields as $key) {
108 $insert_values[$key] = $values[$key];
110 // For consistency, the values array is always numerically indexed.
111 $this->insertValues[] = array_values($insert_values);
117 * Specifies fields for which the database defaults should be used.
119 * If you want to force a given field to use the database-defined default,
120 * not NULL or undefined, use this method to instruct the database to use
121 * default values explicitly. In most cases this will not be necessary
122 * unless you are inserting a row that is all default values, as you cannot
123 * specify no values in an INSERT query.
125 * Specifying a field both in fields() and in useDefaults() is an error
126 * and will not execute.
128 * @param array $fields
129 * An array of values for which to use the default values
130 * specified in the table definition.
135 public function useDefaults(array $fields) {
136 $this->defaultFields = $fields;
141 * Returns the query placeholders for values that will be inserted.
143 * @param array $nested_insert_values
144 * A nested array of values to insert.
145 * @param array $default_fields
146 * An array of fields that should be set to their database-defined defaults.
149 * An array of insert placeholders.
151 protected function getInsertPlaceholderFragment(array $nested_insert_values, array $default_fields) {
152 $max_placeholder = 0;
154 if ($nested_insert_values) {
155 foreach ($nested_insert_values as $insert_values) {
158 // Default fields aren't really placeholders, but this is the most convenient
159 // way to handle them.
160 $placeholders = array_pad($placeholders, count($default_fields), 'default');
162 $new_placeholder = $max_placeholder + count($insert_values);
163 for ($i = $max_placeholder; $i < $new_placeholder; ++$i) {
164 $placeholders[] = ':db_insert_placeholder_' . $i;
166 $max_placeholder = $new_placeholder;
167 $values[] = '(' . implode(', ', $placeholders) . ')';
171 // If there are no values, then this is a default-only query. We still need to handle that.
172 $placeholders = array_fill(0, count($default_fields), 'default');
173 $values[] = '(' . implode(', ', $placeholders) . ')';
182 public function count() {
183 return count($this->insertValues);