Simpletest Coverage - includes/database/mysql/query.inc

1 <?php
2 // $Id: query.inc,v 1.13 2009/07/21 01:56:36 webchick Exp $
3
4 /**
5 * @ingroup database
6 * @{
7 */
8
9 /**
10 * @file
11 * Query code for MySQL embedded database engine.
12 */
13
14
15 class InsertQuery_mysql extends InsertQuery {
16
17 public function execute() {
18 if (!$this->preExecute()) {
19 return NULL;
20 }
21
22 // If we're selecting from a SelectQuery, finish building the query and
23 // pass it back, as any remaining options are irrelevant.
24 if (empty($this->fromQuery)) {
25 $max_placeholder = 0;
26 $values = array();
27 foreach ($this->insertValues as $insert_values) {
28 foreach ($insert_values as $value) {
29 $values[':db_insert_placeholder_' . $max_placeholder++] = $value;
30 }
31 }
32 }
33 else {
34 $values = $this->fromQuery->getArguments();
35 }
36
37 $last_insert_id = $this->connection->query((string)$this, $values, $this->queryOptions);
38
39 // Re-initialize the values array so that we can re-use this query.
40 $this->insertValues = array();
41
42 return $last_insert_id;
43 }
44
45 public function __toString() {
46
47 $delay = $this->queryOptions['delay'] ? 'DELAYED' : '';
48
49 // Default fields are always placed first for consistency.
50 $insert_fields = array_merge($this->defaultFields, $this->insertFields);
51
52 // If we're selecting from a SelectQuery, finish building the query and
53 // pass it back, as any remaining options are irrelevant.
54 if (!empty($this->fromQuery)) {
55 return "INSERT $delay INTO {" . $this->table . '} (' . implode(', ', $insert_fields) . ') ' . $this->fromQuery;
56 }
57
58 $query = "INSERT $delay INTO {" . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
59
60 $max_placeholder = 0;
61 $values = array();
62 if (count($this->insertValues)) {
63 foreach ($this->insertValues as $insert_values) {
64 $placeholders = array();
65
66 // Default fields aren't really placeholders, but this is the most convenient
67 // way to handle them.
68 $placeholders = array_pad($placeholders, count($this->defaultFields), 'default');
69
70 $new_placeholder = $max_placeholder + count($insert_values);
71 for ($i = $max_placeholder; $i < $new_placeholder; ++$i) {
72 $placeholders[] = ':db_insert_placeholder_' . $i;
73 }
74 $max_placeholder = $new_placeholder;
75 $values[] = '(' . implode(', ', $placeholders) . ')';
76 }
77 }
78 else {
79 // If there are no values, then this is a default-only query. We still need to handle that.
80 $placeholders = array_fill(0, count($this->defaultFields), 'default');
81 $values[] = '(' . implode(', ', $placeholders) . ')';
82 }
83
84 $query .= implode(', ', $values);
85
86 return $query;
87 }
88 }
89
90 class MergeQuery_mysql extends MergeQuery {
91
92 public function execute() {
93
94 // A merge query without any key field is invalid.
95 if (count($this->keyFields) == 0) {
96 throw new InvalidMergeQueryException("You need to specify key fields before executing a merge query");
97 }
98
99 // Set defaults.
100 if ($this->updateFields) {
101 $update_fields = $this->updateFields;
102 }
103 else {
104 // When update fields are derived from insert fields, we don't need
105 // placeholders since we can tell MySQL to reuse insert supplied
106 // values using the VALUES(col_name) function.
107 $update_fields = array();
108 }
109
110 $insert_fields = $this->insertFields + $this->keyFields;
111
112 $max_placeholder = 0;
113 $values = array();
114 // We assume that the order here is the same as in __toString(). If that's
115 // not the case, then we have serious problems.
116 foreach ($insert_fields as $value) {
117 $values[':db_insert_placeholder_' . $max_placeholder++] = $value;
118 }
119
120 // Expressions take priority over literal fields, so we process those first
121 // and remove any literal fields that conflict.
122 foreach ($this->expressionFields as $field => $data) {
123 if (!empty($data['arguments'])) {
124 $values += $data['arguments'];
125 }
126 unset($update_fields[$field]);
127 }
128
129 // Because we filter $fields the same way here and in __toString(), the
130 // placeholders will all match up properly.
131 $max_placeholder = 0;
132 foreach ($update_fields as $field => $value) {
133 $values[':db_update_placeholder_' . ($max_placeholder++)] = $value;
134 }
135
136 $last_insert_id = $this->connection->query((string)$this, $values, $this->queryOptions);
137
138 return $last_insert_id;
139 }
140
141
142 public function __toString() {
143
144 // Set defaults.
145 if ($this->updateFields) {
146 $update_fields = $this->updateFields;
147 }
148 else {
149 $update_fields = $this->insertFields;
150 // If there are no exclude fields, this is a no-op.
151 foreach ($this->excludeFields as $exclude_field) {
152 unset($update_fields[$exclude_field]);
153 }
154 }
155
156 // If the merge query has no fields to update, add the first key as an
157 // update field so the query will not fail if a duplicate key is found.
158 if (!$update_fields && !$this->expressionFields) {
159 $update_fields = array_slice($this->keyFields, 0, 1, TRUE);
160 }
161
162 $insert_fields = $this->insertFields + $this->keyFields;
163
164 $query = "INSERT INTO {" . $this->table . '} (' . implode(', ', array_keys($insert_fields)) . ') VALUES ';
165
166 $max_placeholder = 0;
167 $values = array();
168 // We don't need the $field, but this is a convenient way to count.
169 foreach ($insert_fields as $field) {
170 $values[] = ':db_insert_placeholder_' . $max_placeholder++;
171 }
172
173 $query .= '(' . implode(', ', $values) . ') ON DUPLICATE KEY UPDATE ';
174
175 // Expressions take priority over literal fields, so we process those first
176 // and remove any literal fields that conflict.
177 $max_placeholder = 0;
178 $update = array();
179 foreach ($this->expressionFields as $field => $data) {
180 $update[] = $field . '=' . $data['expression'];
181 unset($update_fields[$field]);
182 }
183
184 // Build update fields clauses based on caller supplied list, or derived
185 // from insert supplied values using the VALUES(col_name) function.
186 foreach ($update_fields as $field => $value) {
187 if ($this->updateFields) {
188 $update[] = ($field . '=:db_update_placeholder_' . $max_placeholder++);
189 }
190 else {
191 $update[] = ($field . '=VALUES(' . $field . ')');
192 }
193 }
194
195 $query .= implode(', ', $update);
196
197 return $query;
198 }
199 }
200
201 /**
202 * @} End of "ingroup database".
203 */
204

Legend

Missed
lines code that were not excersized during program execution.
Covered
lines code were excersized during program execution.
Comment/non executable
Comment or non-executable line of code.
Dead
lines of code that according to xdebug could not be executed. This is counted as coverage code because in almost all cases it is code that runnable.