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

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

se actualizo el cord

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