source: sipes/cord/includes/database.mysql-common.inc @ b354002

stableversion-3.0
Last change on this file since b354002 was b354002, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se agrego el directorio del cord

  • Propiedad mode establecida a 100755
File size: 15.0 KB
Línea 
1<?php
2
3/**
4 * @file
5 * Functions shared between mysql and mysqli database engines.
6 */
7
8/**
9 * Runs a basic query in the active database.
10 *
11 * User-supplied arguments to the query should be passed in as separate
12 * parameters so that they can be properly escaped to avoid SQL injection
13 * attacks.
14 *
15 * @param $query
16 *   A string containing an SQL query.
17 * @param ...
18 *   A variable number of arguments which are substituted into the query
19 *   using printf() syntax. Instead of a variable number of query arguments,
20 *   you may also pass a single array containing the query arguments.
21 *
22 *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
23 *   in '') and %%.
24 *
25 *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
26 *   and TRUE values to decimal 1.
27 *
28 * @return
29 *   A database query result resource, or FALSE if the query was not
30 *   executed correctly.
31 */
32function db_query($query) {
33  $args = func_get_args();
34  array_shift($args);
35  $query = db_prefix_tables($query);
36  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
37    $args = $args[0];
38  }
39  _db_query_callback($args, TRUE);
40  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
41  return _db_query($query);
42}
43
44/**
45 * @ingroup schemaapi
46 * @{
47 */
48
49/**
50 * Generate SQL to create a new table from a Drupal schema definition.
51 *
52 * @param $name
53 *   The name of the table to create.
54 * @param $table
55 *   A Schema API table definition array.
56 * @return
57 *   An array of SQL statements to create the table.
58 */
59function db_create_table_sql($name, $table) {
60
61  if (empty($table['mysql_suffix'])) {
62    $table['mysql_suffix'] = '/*!40100 DEFAULT CHARACTER SET utf8';
63    // By default, MySQL uses the default collation for new tables, which is
64    // 'utf8_general_ci' for utf8. If an alternate collation has been set, it
65    // needs to be explicitly specified.
66    // @see db_connect()
67    $collation = (!empty($table['collation']) ? $table['collation'] : (!empty($GLOBALS['db_collation']) ? $GLOBALS['db_collation'] : ''));
68    if ($collation) {
69      $table['mysql_suffix'] .= ' COLLATE ' . $collation;
70    }
71    $table['mysql_suffix'] .= ' */';
72  }
73
74  $sql = "CREATE TABLE {". $name ."} (\n";
75
76  // Add the SQL statement for each field.
77  foreach ($table['fields'] as $field_name => $field) {
78    $sql .= _db_create_field_sql($field_name, _db_process_field($field)) .", \n";
79  }
80
81  // Process keys & indexes.
82  $keys = _db_create_keys_sql($table);
83  if (count($keys)) {
84    $sql .= implode(", \n", $keys) .", \n";
85  }
86
87  // Remove the last comma and space.
88  $sql = substr($sql, 0, -3) ."\n) ";
89
90  $sql .= $table['mysql_suffix'];
91
92  return array($sql);
93}
94
95function _db_create_keys_sql($spec) {
96  $keys = array();
97
98  if (!empty($spec['primary key'])) {
99    $keys[] = 'PRIMARY KEY ('. _db_create_key_sql($spec['primary key']) .')';
100  }
101  if (!empty($spec['unique keys'])) {
102    foreach ($spec['unique keys'] as $key => $fields) {
103      $keys[] = 'UNIQUE KEY '. $key .' ('. _db_create_key_sql($fields) .')';
104    }
105  }
106  if (!empty($spec['indexes'])) {
107    foreach ($spec['indexes'] as $index => $fields) {
108      $keys[] = 'INDEX '. $index .' ('. _db_create_key_sql($fields) .')';
109    }
110  }
111
112  return $keys;
113}
114
115function _db_create_key_sql($fields) {
116  $ret = array();
117  foreach ($fields as $field) {
118    if (is_array($field)) {
119      $ret[] = $field[0] .'('. $field[1] .')';
120    }
121    else {
122      $ret[] = $field;
123    }
124  }
125  return implode(', ', $ret);
126}
127
128/**
129 * Set database-engine specific properties for a field.
130 *
131 * @param $field
132 *   A field description array, as specified in the schema documentation.
133 */
134function _db_process_field($field) {
135
136  if (!isset($field['size'])) {
137    $field['size'] = 'normal';
138  }
139
140  // Set the correct database-engine specific datatype.
141  if (!isset($field['mysql_type'])) {
142    $map = db_type_map();
143    $field['mysql_type'] = $map[$field['type'] .':'. $field['size']];
144  }
145
146  if ($field['type'] == 'serial') {
147    $field['auto_increment'] = TRUE;
148  }
149
150  return $field;
151}
152
153/**
154 * Create an SQL string for a field to be used in table creation or alteration.
155 *
156 * Before passing a field out of a schema definition into this function it has
157 * to be processed by _db_process_field().
158 *
159 * @param $name
160 *    Name of the field.
161 * @param $spec
162 *    The field specification, as per the schema data structure format.
163 */
164function _db_create_field_sql($name, $spec) {
165  $sql = "`". $name ."` ". $spec['mysql_type'];
166
167  if (in_array($spec['type'], array('varchar', 'char', 'text')) && isset($spec['length'])) {
168    $sql .= '('. $spec['length'] .')';
169  }
170  elseif (isset($spec['precision']) && isset($spec['scale'])) {
171    $sql .= '('. $spec['precision'] .', '. $spec['scale'] .')';
172  }
173
174  if (!empty($spec['unsigned'])) {
175    $sql .= ' unsigned';
176  }
177
178  if (!empty($spec['not null'])) {
179    $sql .= ' NOT NULL';
180  }
181
182  if (!empty($spec['auto_increment'])) {
183    $sql .= ' auto_increment';
184  }
185
186  if (isset($spec['default'])) {
187    if (is_string($spec['default'])) {
188      $spec['default'] = "'". $spec['default'] ."'";
189    }
190    $sql .= ' DEFAULT '. $spec['default'];
191  }
192
193  if (empty($spec['not null']) && !isset($spec['default'])) {
194    $sql .= ' DEFAULT NULL';
195  }
196
197  return $sql;
198}
199
200/**
201 * This maps a generic data type in combination with its data size
202 * to the engine-specific data type.
203 */
204function db_type_map() {
205  // Put :normal last so it gets preserved by array_flip.  This makes
206  // it much easier for modules (such as schema.module) to map
207  // database types back into schema types.
208  $map = array(
209    'varchar:normal'  => 'VARCHAR',
210    'char:normal'     => 'CHAR',
211
212    'text:tiny'       => 'TINYTEXT',
213    'text:small'      => 'TINYTEXT',
214    'text:medium'     => 'MEDIUMTEXT',
215    'text:big'        => 'LONGTEXT',
216    'text:normal'     => 'TEXT',
217
218    'serial:tiny'     => 'TINYINT',
219    'serial:small'    => 'SMALLINT',
220    'serial:medium'   => 'MEDIUMINT',
221    'serial:big'      => 'BIGINT',
222    'serial:normal'   => 'INT',
223
224    'int:tiny'        => 'TINYINT',
225    'int:small'       => 'SMALLINT',
226    'int:medium'      => 'MEDIUMINT',
227    'int:big'         => 'BIGINT',
228    'int:normal'      => 'INT',
229
230    'float:tiny'      => 'FLOAT',
231    'float:small'     => 'FLOAT',
232    'float:medium'    => 'FLOAT',
233    'float:big'       => 'DOUBLE',
234    'float:normal'    => 'FLOAT',
235
236    'numeric:normal'  => 'DECIMAL',
237
238    'blob:big'        => 'LONGBLOB',
239    'blob:normal'     => 'BLOB',
240
241    'datetime:normal' => 'DATETIME',
242  );
243  return $map;
244}
245
246/**
247 * Rename a table.
248 *
249 * @param $ret
250 *   Array to which query results will be added.
251 * @param $table
252 *   The table to be renamed.
253 * @param $new_name
254 *   The new name for the table.
255 */
256function db_rename_table(&$ret, $table, $new_name) {
257  $ret[] = update_sql('ALTER TABLE {'. $table .'} RENAME TO {'. $new_name .'}');
258}
259
260/**
261 * Drop a table.
262 *
263 * @param $ret
264 *   Array to which query results will be added.
265 * @param $table
266 *   The table to be dropped.
267 */
268function db_drop_table(&$ret, $table) {
269  $ret[] = update_sql('DROP TABLE {'. $table .'}');
270}
271
272/**
273 * Add a new field to a table.
274 *
275 * @param $ret
276 *   Array to which query results will be added.
277 * @param $table
278 *   Name of the table to be altered.
279 * @param $field
280 *   Name of the field to be added.
281 * @param $spec
282 *   The field specification array, as taken from a schema definition.
283 *   The specification may also contain the key 'initial', the newly
284 *   created field will be set to the value of the key in all rows.
285 *   This is most useful for creating NOT NULL columns with no default
286 *   value in existing tables.
287 * @param $keys_new
288 *   Optional keys and indexes specification to be created on the
289 *   table along with adding the field. The format is the same as a
290 *   table specification but without the 'fields' element.  If you are
291 *   adding a type 'serial' field, you MUST specify at least one key
292 *   or index including it in this array. See db_change_field() for more
293 *   explanation why.
294 */
295function db_add_field(&$ret, $table, $field, $spec, $keys_new = array()) {
296  $fixnull = FALSE;
297  if (!empty($spec['not null']) && !isset($spec['default'])) {
298    $fixnull = TRUE;
299    $spec['not null'] = FALSE;
300  }
301  $query = 'ALTER TABLE {'. $table .'} ADD ';
302  $query .= _db_create_field_sql($field, _db_process_field($spec));
303  if (count($keys_new)) {
304    $query .= ', ADD '. implode(', ADD ', _db_create_keys_sql($keys_new));
305  }
306  $ret[] = update_sql($query);
307  if (isset($spec['initial'])) {
308    // All this because update_sql does not support %-placeholders.
309    $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. db_type_placeholder($spec['type']);
310    $result = db_query($sql, $spec['initial']);
311    $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql .' ('. $spec['initial'] .')'));
312  }
313  if ($fixnull) {
314    $spec['not null'] = TRUE;
315    db_change_field($ret, $table, $field, $field, $spec);
316  }
317}
318
319/**
320 * Drop a field.
321 *
322 * @param $ret
323 *   Array to which query results will be added.
324 * @param $table
325 *   The table to be altered.
326 * @param $field
327 *   The field to be dropped.
328 */
329function db_drop_field(&$ret, $table, $field) {
330  $ret[] = update_sql('ALTER TABLE {'. $table .'} DROP '. $field);
331}
332
333/**
334 * Set the default value for a field.
335 *
336 * @param $ret
337 *   Array to which query results will be added.
338 * @param $table
339 *   The table to be altered.
340 * @param $field
341 *   The field to be altered.
342 * @param $default
343 *   Default value to be set. NULL for 'default NULL'.
344 */
345function db_field_set_default(&$ret, $table, $field, $default) {
346  if ($default === NULL) {
347    $default = 'NULL';
348  }
349  else {
350    $default = is_string($default) ? "'$default'" : $default;
351  }
352
353  $ret[] = update_sql('ALTER TABLE {'. $table .'} ALTER COLUMN '. $field .' SET DEFAULT '. $default);
354}
355
356/**
357 * Set a field to have no default value.
358 *
359 * @param $ret
360 *   Array to which query results will be added.
361 * @param $table
362 *   The table to be altered.
363 * @param $field
364 *   The field to be altered.
365 */
366function db_field_set_no_default(&$ret, $table, $field) {
367  $ret[] = update_sql('ALTER TABLE {'. $table .'} ALTER COLUMN '. $field .' DROP DEFAULT');
368}
369
370/**
371 * Add a primary key.
372 *
373 * @param $ret
374 *   Array to which query results will be added.
375 * @param $table
376 *   The table to be altered.
377 * @param $fields
378 *   Fields for the primary key.
379 */
380function db_add_primary_key(&$ret, $table, $fields) {
381  $ret[] = update_sql('ALTER TABLE {'. $table .'} ADD PRIMARY KEY ('.
382    _db_create_key_sql($fields) .')');
383}
384
385/**
386 * Drop the primary key.
387 *
388 * @param $ret
389 *   Array to which query results will be added.
390 * @param $table
391 *   The table to be altered.
392 */
393function db_drop_primary_key(&$ret, $table) {
394  $ret[] = update_sql('ALTER TABLE {'. $table .'} DROP PRIMARY KEY');
395}
396
397/**
398 * Add a unique key.
399 *
400 * @param $ret
401 *   Array to which query results will be added.
402 * @param $table
403 *   The table to be altered.
404 * @param $name
405 *   The name of the key.
406 * @param $fields
407 *   An array of field names.
408 */
409function db_add_unique_key(&$ret, $table, $name, $fields) {
410  $ret[] = update_sql('ALTER TABLE {'. $table .'} ADD UNIQUE KEY '.
411    $name .' ('. _db_create_key_sql($fields) .')');
412}
413
414/**
415 * Drop a unique key.
416 *
417 * @param $ret
418 *   Array to which query results will be added.
419 * @param $table
420 *   The table to be altered.
421 * @param $name
422 *   The name of the key.
423 */
424function db_drop_unique_key(&$ret, $table, $name) {
425  $ret[] = update_sql('ALTER TABLE {'. $table .'} DROP KEY '. $name);
426}
427
428/**
429 * Add an index.
430 *
431 * @param $ret
432 *   Array to which query results will be added.
433 * @param $table
434 *   The table to be altered.
435 * @param $name
436 *   The name of the index.
437 * @param $fields
438 *   An array of field names.
439 */
440function db_add_index(&$ret, $table, $name, $fields) {
441  $query = 'ALTER TABLE {'. $table .'} ADD INDEX '. $name .' ('. _db_create_key_sql($fields) .')';
442  $ret[] = update_sql($query);
443}
444
445/**
446 * Drop an index.
447 *
448 * @param $ret
449 *   Array to which query results will be added.
450 * @param $table
451 *   The table to be altered.
452 * @param $name
453 *   The name of the index.
454 */
455function db_drop_index(&$ret, $table, $name) {
456  $ret[] = update_sql('ALTER TABLE {'. $table .'} DROP INDEX '. $name);
457}
458
459/**
460 * Change a field definition.
461 *
462 * IMPORTANT NOTE: To maintain database portability, you have to explicitly
463 * recreate all indices and primary keys that are using the changed field.
464 *
465 * That means that you have to drop all affected keys and indexes with
466 * db_drop_{primary_key,unique_key,index}() before calling db_change_field().
467 * To recreate the keys and indices, pass the key definitions as the
468 * optional $keys_new argument directly to db_change_field().
469 *
470 * For example, suppose you have:
471 * @code
472 * $schema['foo'] = array(
473 *   'fields' => array(
474 *     'bar' => array('type' => 'int', 'not null' => TRUE)
475 *   ),
476 *   'primary key' => array('bar')
477 * );
478 * @endcode
479 * and you want to change foo.bar to be type serial, leaving it as the
480 * primary key.  The correct sequence is:
481 * @code
482 * db_drop_primary_key($ret, 'foo');
483 * db_change_field($ret, 'foo', 'bar', 'bar',
484 *   array('type' => 'serial', 'not null' => TRUE),
485 *   array('primary key' => array('bar')));
486 * @endcode
487 *
488 * The reasons for this are due to the different database engines:
489 *
490 * On PostgreSQL, changing a field definition involves adding a new field
491 * and dropping an old one which* causes any indices, primary keys and
492 * sequences (from serial-type fields) that use the changed field to be dropped.
493 *
494 * On MySQL, all type 'serial' fields must be part of at least one key
495 * or index as soon as they are created.  You cannot use
496 * db_add_{primary_key,unique_key,index}() for this purpose because
497 * the ALTER TABLE command will fail to add the column without a key
498 * or index specification.  The solution is to use the optional
499 * $keys_new argument to create the key or index at the same time as
500 * field.
501 *
502 * You could use db_add_{primary_key,unique_key,index}() in all cases
503 * unless you are converting a field to be type serial. You can use
504 * the $keys_new argument in all cases.
505 *
506 * @param $ret
507 *   Array to which query results will be added.
508 * @param $table
509 *   Name of the table.
510 * @param $field
511 *   Name of the field to change.
512 * @param $field_new
513 *   New name for the field (set to the same as $field if you don't want to change the name).
514 * @param $spec
515 *   The field specification for the new field.
516 * @param $keys_new
517 *   Optional keys and indexes specification to be created on the
518 *   table along with changing the field. The format is the same as a
519 *   table specification but without the 'fields' element.
520 */
521
522function db_change_field(&$ret, $table, $field, $field_new, $spec, $keys_new = array()) {
523  $sql = 'ALTER TABLE {'. $table .'} CHANGE `'. $field .'` '.
524    _db_create_field_sql($field_new, _db_process_field($spec));
525  if (count($keys_new)) {
526    $sql .= ', ADD '. implode(', ADD ', _db_create_keys_sql($keys_new));
527  }
528  $ret[] = update_sql($sql);
529}
530
531/**
532 * Returns the last insert id.
533 *
534 * @param $table
535 *   The name of the table you inserted into.
536 * @param $field
537 *   The name of the autoincrement field.
538 */
539function db_last_insert_id($table, $field) {
540  return db_result(db_query('SELECT LAST_INSERT_ID()'));
541}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.