Package base :: Package includes :: Module database_mysqli
[hide private]

Source Code for Module base.includes.database_mysqli

  1  #!/usr/bin/env python 
  2  # Id: database.mysqli.inc,v 1.57 2008/04/14 17:48:33 dries Exp $ 
  3   
  4  """ 
  5    Database interface code for MySQL database servers using the mysqli client 
  6    libraries. mysqli is included in PHP 5 by default and allows developers to 
  7    use the advanced features of MySQL 4.1.x, 5.0.x and beyond. 
  8   
  9    @package includes 
 10    @see <a href='http://drupy.net'>Drupy Homepage</a> 
 11    @see <a href='http://drupal.org'>Drupal Homepage</a> 
 12    @note Drupy is a port of the Drupal project. 
 13    @note 
 14      This file was ported from Drupal's includes/database_mysqli.inc and 
 15      includes/database-mysql_common.inc 
 16    @author Brendon Crawford 
 17    @copyright 2008 Brendon Crawford 
 18    @contact message144 at users dot sourceforge dot net 
 19    @created 2008-01-10 
 20    @version 0.1 
 21    @note License: 
 22   
 23      This program is free software; you can redistribute it and/or 
 24      modify it under the terms of the GNU General Public License 
 25      as published by the Free Software Foundation; either version 2 
 26      of the License, or (at your option) any later version. 
 27   
 28      This program is distributed in the hope that it will be useful, 
 29      but WITHOUT ANY WARRANTY; without even the implied warranty of 
 30      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 31      GNU General Public License for more details. 
 32   
 33      You should have received a copy of the GNU General Public License 
 34      along with this program; if not, write to: 
 35       
 36      The Free Software Foundation, Inc., 
 37      51 Franklin Street, Fifth Floor, 
 38      Boston, MA  02110-1301, 
 39      USA 
 40  """ 
 41   
 42  __version__ = "$Revision: 1 $" 
 43   
 44  # Maintainers of this file should consult: 
 45  # http://www.php.net/manual/en/ref.mysqli.php 
 46   
 47  from lib.drupy import DrupyPHP as php 
 48  from lib.drupy import DrupyMySQL 
 49  import appglobals as lib_appglobals 
 50  import bootstrap as lib_bootstrap 
 51  import database as lib_database 
 52   
53 -def status_report(phase):
54 """ 55 Report database status. 56 """ 57 t = get_t() 58 version = db_version() 59 form['mysql'] = { 60 'title' : t('MySQL database'), 61 'value' : (l(version, 'admin/reports/status/sql') if \ 62 (phase == 'runtime') else version), 63 } 64 if (version_compare(version, DRUPAL_MINIMUM_MYSQL) < 0): 65 form['mysql']['severity'] = REQUIREMENT_ERROR 66 form['mysql']['description'] = t(\ 67 'Your MySQL Server is too old + Drupal requires at least ' + \ 68 'MySQL %version.', {'%version' : DRUPAL_MINIMUM_MYSQL}) 69 return form
70 71 72
73 -def version():
74 """ 75 Returns the version of the database server currently in use. 76 77 @return Database server version 78 """ 79 version = php.explode('-', \ 80 DrupyMySQL.mysqli_get_server_info(lib_appglobals.active_db)) 81 return version
82 83 84
85 -def connect(url):
86 """ 87 Initialise a database connection. 88 89 Note that mysqli does not support persistent connections. 90 """ 91 # Check if MySQLi support is present in PHP 92 url = php.parse_url(url, 3306) 93 # Decode url-encoded information in the db connection string 94 url['user'] = php.urldecode(url['user']) 95 # Test if database url has a password. 96 url['pass'] = (php.urldecode(url['pass']) if php.isset(url, 'pass') else '') 97 url['host'] = php.urldecode(url['host']) 98 url['path'] = php.urldecode(url['path']) 99 if (not php.isset(url, 'port')): 100 url['port'] = None 101 connection = DrupyMySQL.mysqli_real_connect(\ 102 url['host'], url['user'], url['pass'], php.substr(url['path'], 1), \ 103 url['port'], '', DrupyMySQL.MYSQLI_CLIENT_FOUND_ROWS) 104 if (DrupyMySQL.mysqli_connect_errno() > 0): 105 _db_error_page(DrupyMySQL.mysqli_connect_error()) 106 # Force UTF-8. 107 DrupyMySQL.mysqli_query(connection, 'SET NAMES "utf8"') 108 # Require ANSI mode to improve SQL portability. 109 DrupyMySQL.mysqli_query(connection, "SET php.SESSION sql_mode='ANSI'") 110 return connection
111 112 113
114 -def _query(query_, debug = 0):
115 """ 116 Helper function for db_query(). 117 """ 118 if (lib_bootstrap.variable_get('dev_query', 0)): 119 usec,sec = php.explode(' ', php.microtime()) 120 timer = float(usec) + float(sec) 121 # If devel.plugin query logging is enabled, prepend a comment 122 # with the username and calling function 123 # to the SQL string. This is useful when running mysql's 124 # SHOW PROCESSLIST to learn what exact 125 # code is issueing the slow query. 126 bt = debug_backtrace() 127 # t() may not be available yet so we don't wrap 'Anonymous' 128 name = (lib_appglobals.user.name if (lib_appglobals.user.uid > 0) else \ 129 variable_get('anonymous', 'Anonymous')) 130 # php.str_replace() to prevent SQL injection via username 131 # or anonymous name. 132 name = php.str_replace(['*', '/'], '', name) 133 query_ = '/* ' + name + ' : ' . bt[2]['function'] + ' */ ' + query_ 134 result = DrupyMySQL.mysqli_query(lib_appglobals.active_db, query_) 135 if (lib_bootstrap.variable_get('dev_query', 0)): 136 query_ = bt[2]['function'] + "\n" + query_ 137 usec,sec = php.explode(' ', php.microtime()) 138 stop = float(usec) + float(sec) 139 diff = stop - timer 140 lib_appglobals.queries.append( [query_, diff] ) 141 if (debug): 142 print '<p>query: ' + query_ + '<br />error:' + \ 143 DrupyMySQL.mysqli_error(lib_appglobals.active_db) + '</p>' 144 if (not DrupyMySQL.mysqli_errno(lib_appglobals.active_db)): 145 return result 146 else: 147 # Indicate to drupal_error_handler that this is a database error. 148 DB_ERROR = True 149 php.trigger_error(lib_bootstrap.check_plain(\ 150 DrupyMySQL.mysqli_error(lib_appglobals.active_db) + \ 151 "\nquery: " + query_), php.E_USER_WARNING) 152 return False
153 154 155
156 -def fetch_object(result):
157 """ 158 Fetch one result row from the previous query as an object. 159 160 @param result 161 A database query result resource, as returned from db_query(). 162 @return 163 An object representing the next row of the result, 164 or False. The attributes 165 of this object are the table fields selected by the query. 166 """ 167 if (result): 168 object_ = DrupyMySQL.mysqli_fetch_object(result) 169 return (object_ if (object_ != None) else False)
170 171 172 173
174 -def fetch_array(result):
175 """ 176 Fetch one result row from the previous query as an array. 177 178 @param result 179 A database query result resource, as returned from db_query(). 180 @return 181 An associative array representing the next row of the result, or False. 182 The keys of this object are the names of the table fields selected by the 183 query, and the values are the field values for this result row. 184 """ 185 if (result): 186 array_ = DrupyMySQL.mysqli_fetch_array(result, DrupyMySQL.MYSQLI_ASSOC) 187 return (array_ if (array_ != None) else False)
188 189 190
191 -def result(result):
192 """ 193 Return an individual result field from the previous query. 194 195 Only use this function if exactly one field is being selected; otherwise, 196 use db_fetch_object() or db_fetch_array(). 197 198 @param result 199 A database query result resource, as returned from db_query(). 200 @return 201 The resulting field or False. 202 """ 203 if (result and DrupyMySQL.mysqli_num_rows(result) > 0): 204 # The DrupyMySQL.mysqli_fetch_row function has an optional second 205 # parameter row 206 # but that can't be used for compatibility with Oracle, DB2, etc. 207 array_ = DrupyMySQL.mysqli_fetch_row(result) 208 return array_[0] 209 return False
210 211 212
213 -def error():
214 """ 215 Determine whether the previous query caused an error. 216 """ 217 return DrupyMySQL.mysqli_errno(lib_appglobals.active_db)
218 219 220 221
222 -def affected_rows():
223 """ 224 Determine the number of rows changed by the preceding query. 225 """ 226 return DrupyMySQL.mysqli_affected_rows(lib_appglobals.active_db)
227 228 229
230 -def query_range(query):
231 """ 232 Runs a limited-range query in the active database. 233 234 Use this as a substitute for db_query() when a subset of the query is to be 235 returned. User-supplied arguments to the query should be passed in as 236 separate parameters so that they can be properly escaped to avoid SQL 237 injection attacks. 238 239 @param query 240 A string containing an SQL query. 241 @param ... 242 A variable number of arguments which are substituted into the query 243 using printf() syntax. The query arguments can be enclosed in one 244 array instead. 245 Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose 246 in '') and %%. 247 NOTE: using this syntax will cast None and False values to decimal 0, 248 and True values to decimal 1. 249 @param from 250 The first result row to return. 251 @param count 252 The maximum number of result rows to return. 253 @return 254 A database query result resource, or False if the query was not executed 255 correctly. 256 """ 257 args = func_get_args() 258 count = php.array_pop(args) 259 from_ = php.array_pop(args) 260 php.array_shift(args) 261 query = db_prefix_tables(query) 262 # 'All arguments in one array' syntax 263 if (php.isset(args, 0) and php.is_array(args, 0)): 264 args = args[0] 265 _db_query_callback(args, True) 266 query = php.preg_replace_callback(DB_QUERY_REGEXP, \ 267 '_db_query_callback', query) 268 query += ' LIMIT ' + int(from_) + ', ' . int(count) 269 return _db_query(query)
270 271 272 273
274 -def query_temporary(query):
275 """ 276 Runs a SELECT query and stores its results in a temporary table. 277 278 Use this as a substitute for db_query() when the results need to stored 279 in a temporary table. Temporary tables exist for the duration of the page 280 request. 281 User-supplied arguments to the query should be passed in as 282 separate parameters 283 so that they can be properly escaped to avoid SQL injection attacks. 284 285 Note that if you need to know how many results were returned, you should do 286 a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() does 287 not give consistent result across different database types in this case. 288 289 @param query 290 A string containing a normal SELECT SQL query. 291 @param ... 292 A variable number of arguments which are substituted into the query 293 using printf() syntax. The query arguments can be enclosed in one 294 array instead. 295 Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose 296 in '') and %%. 297 298 NOTE: using this syntax will cast None and False values to decimal 0, 299 and True values to decimal 1. 300 301 @param table 302 The name of the temporary table to select into. This name will not be 303 prefixed as there is no risk of collision. 304 @return 305 A database query result resource, or False if the query was not executed 306 correctly. 307 """ 308 args = func_get_args() 309 tablename = php.array_pop(args) 310 php.array_shift(args) 311 query = php.preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE ' + \ 312 tablename + ' Engine=HEAP SELECT', db_prefix_tables(query)) 313 # 'All arguments in one array' syntax 314 if (php.isset(args, 0) and php.is_array(args, 0)): 315 args = args[0] 316 _db_query_callback(args, True) 317 query = php.preg_replace_callback(DB_QUERY_REGEXP, \ 318 '_db_query_callback', query) 319 return _db_query(query)
320 321 322
323 -def encode_blob(data):
324 """ 325 Returns a properly formatted Binary Large Object value. 326 327 @param data 328 Data to encode. 329 @return 330 Encoded data. 331 """ 332 return "'" + DrupyMySQL.mysqli_real_escape_string(\ 333 lib_appglobals.active_db, data) + "'"
334 335 336
337 -def decode_blob(data):
338 """ 339 Returns text from a Binary Large OBject value. 340 341 @param data 342 Data to decode. 343 @return 344 Decoded data. 345 """ 346 return data
347 348
349 -def escape_string(text):
350 """ 351 Prepare user input for use in a database query, preventing 352 SQL injection attacks. 353 """ 354 return DrupyMySQL.mysqli_real_escape_string(lib_appglobals.active_db, text)
355 356 357
358 -def lock_table(table):
359 """ 360 Lock a table. 361 """ 362 db_query('LOCK TABLES {' + db_escape_table(table) + '} WRITE')
363 364 365 366
367 -def unlock_tables():
368 """ 369 Unlock all locked tables. 370 """ 371 db_query('UNLOCK TABLES')
372 373
374 -def table_exists(table):
375 """ 376 Check if a table exists. 377 """ 378 return bool(lib_database.fetch_object(\ 379 lib_database.query("SHOW TABLES LIKE '{" + \ 380 lib_database.escape_table(table) + "}'")))
381 382
383 -def column_exists(table, column):
384 """ 385 Check if a column exists in the given table. 386 """ 387 return bool(lib_database.fetch_object(\ 388 lib_database.query("SHOW COLUMNS FROM {" + \ 389 lib_database.escape_table(table) + "} LIKE '" + \ 390 lib_database.escape_table(column) + "'")))
391 392
393 -def distinct_field(table, field, query):
394 """ 395 Wraps the given table.field entry with a DISTINCT(). The wrapper is added to 396 the SELECT list entry of the given query and the resulting query is 397 returned. This function only applies the wrapper if a DISTINCT doesn't 398 already exist in the query. 399 400 @param table Table containing the field to set as DISTINCT 401 @param field Field to set as DISTINCT 402 @param query Query to apply the wrapper to 403 @return SQL query with the DISTINCT wrapper surrounding the given 404 table.field. 405 """ 406 field_to_select = 'DISTINCT(' + table + '.' + field + ')' 407 # (?<not text) is a negative look-behind 408 # (no need to rewrite queries that already use DISTINCT). 409 return php.preg_replace('/(SELECT.*)(?:' + table + \ 410 '\.|\s)(?<not DISTINCT\()(?<not DISTINCT\(' + table + '\.)' + field + \ 411 '(.*FROM )/AUsi', '\1 ' + field_to_select + '\2', query)
412 413 414 415 # 416 # @} End of "ingroup database". 417 # 418 419 # 420 # These functions were originally located in includes/mysql-common.inc 421 # 422 423
424 -def query(query_, *args):
425 """ 426 Runs a basic query in the active database. 427 428 User-supplied arguments to the query should be passed in as separate 429 parameters so that they can be properly escaped to avoid SQL injection 430 attacks. 431 432 @param query 433 A string containing an SQL query. 434 @param ... 435 A variable number of arguments which are substituted into the query 436 using printf() syntax. Instead of a variable number of query arguments, 437 you may also pass a single array containing the query arguments. 438 439 Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose 440 in '') and %%. 441 442 NOTE: using this syntax will cast None and False values to decimal 0, 443 and True values to decimal 1. 444 445 @return 446 A database query result resource, or False if the query was not 447 executed correctly. 448 """ 449 this_query = lib_database.prefix_tables(query_) 450 # 'All arguments in one array' syntax 451 if (php.isset(args, 0) and php.is_array(args[0])): 452 args = args[0] 453 lib_database._query_callback(args, True) 454 this_query = php.preg_replace_callback(lib_database.DB_QUERY_REGEXP, \ 455 lib_database._query_callback, this_query) 456 #print 457 #print "QUERY DEBUG:" 458 #print this_query 459 #print 460 return _query(this_query)
461 462 463 # 464 # @ingroup schemaapi 465 # @{ 466 # 467
468 -def create_table_sql(name, table):
469 """ 470 Generate SQL to create a new table from a Drupal schema definition. 471 472 @param name 473 The name of the table to create. 474 @param table 475 A Schema API table definition array. 476 @return 477 An array of SQL statements to create the table. 478 """ 479 if (php.empty(table['mysql_suffix'])): 480 table['mysql_suffix'] = "/*not 40100 DEFAULT CHARACTER SET UTF8 */" 481 sql = "CREATE TABLE {" + name + "} (\n" 482 # Add the SQL statement for each field. 483 for field_name,field in table['fields'].items(): 484 sql += _db_create_field_sql(field_name, _db_process_field(field)) + ", \n" 485 # Process keys & indexes. 486 keys = _db_create_keys_sql(table) 487 if (php.count(keys)): 488 sql += php.implode(", \n", keys) + ", \n" 489 # Remove the last comma and space. 490 sql = php.substr(sql, 0, -3) + "\n) " 491 sql += table['mysql_suffix'] 492 return array(sql)
493 494 495
496 -def _create_keys_sql(spec):
497 keys = {} 498 if (not php.empty(spec['primary key'])): 499 keys.append( 'PRIMARY KEY (' + \ 500 _db_create_key_sql(spec['primary key']) + ')' ) 501 if (not php.empty(spec['unique keys'])): 502 for key,fields in spec['unique keys'].items(): 503 keys.append( 'UNIQUE KEY ' + key + \ 504 ' (' + _db_create_key_sql(fields) + ')' ) 505 if (not php.empty(spec['indexes'])): 506 for index,fields in spec['indexes'].items(): 507 keys.append( 'INDEX ' + index + ' (' + \ 508 _db_create_key_sql(fields) + ')' ) 509 return keys
510 511 512 513
514 -def _create_key_sql(fields):
515 ret = [] 516 for field in fields: 517 if (php.is_array(field)): 518 ret.append( field[0] + '(' + field[1] + ')' ) 519 else: 520 ret.append( field ) 521 return php.implode(', ', ret)
522 523
524 -def _process_field(field):
525 """ 526 Set database-engine specific properties for a field. 527 528 @param field 529 A field description array, as specified in the schema documentation. 530 """ 531 if (not php.isset(field, 'size')): 532 field['size'] = 'normal' 533 # Set the correct database-engine specific datatype. 534 if (not php.isset(field, 'mysql_type')): 535 map_ = db_type_map() 536 field['mysql_type'] = map_[field['type'] + ':' + field['size']] 537 if (field['type'] == 'serial'): 538 field['auto_increment'] = True 539 return field
540 541 542
543 -def _create_field_sql(name, spec):
544 """ 545 Create an SQL string for a field to be used in table creation or alteration. 546 547 Before passing a field out of a schema definition into this function it has 548 to be processed by _db_process_field(). 549 550 @param name 551 Name of the field. 552 @param spec 553 The field specification, as per the schema data structure format. 554 """ 555 sql = "`" + name + "` " . spec['mysql_type'] 556 if (php.isset(spec, 'length')): 557 sql += '(' + spec['length'] + ')' 558 elif (php.isset(spec, 'precision') and php.isset(spec, 'scale')): 559 sql += '(' + spec['precision'] + ', ' + spec['scale'] + ')' 560 if (not php.empty(spec['unsigned'])): 561 sql += ' unsigned' 562 if (not php.empty(spec['not None'])): 563 sql += ' NOT None' 564 if (not php.empty(spec['auto_increment'])): 565 sql += ' auto_increment' 566 if (php.isset(spec, 'default')): 567 if (is_string(spec['default'])): 568 spec['default'] = "'" + spec['default'] + "'" 569 sql += ' DEFAULT ' + spec['default'] 570 if (php.empty(spec['not None']) and not php.isset(spec, 'default')): 571 sql += ' DEFAULT None' 572 return sql
573 574 575 576 577
578 -def type_map():
579 """ 580 This maps a generic data type in combination with its data size 581 to the engine-specific data type. 582 """ 583 # Put :normal last so it gets preserved by array_flip. This makes 584 # it much easier for plugins (such as schema.plugin) to map 585 # database types back into schema types. 586 map_ = { 587 'varchar:normal' : 'VARCHAR', 588 'char:normal' : 'CHAR', 589 'text:tiny' : 'TINYTEXT', 590 'text:small' : 'TINYTEXT', 591 'text:medium' : 'MEDIUMTEXT', 592 'text:big' : 'LONGTEXT', 593 'text:normal' : 'TEXT', 594 'serial:tiny' : 'TINYINT', 595 'serial:small' : 'SMALLINT', 596 'serial:medium' : 'MEDIUMINT', 597 'serial:big' : 'BIGINT', 598 'serial:normal' : 'INT', 599 'int:tiny' : 'TINYINT', 600 'int:small' : 'SMALLINT', 601 'int:medium' : 'MEDIUMINT', 602 'int:big' : 'BIGINT', 603 'int:normal' : 'INT', 604 'float:tiny' : 'FLOAT', 605 'float:small' : 'FLOAT', 606 'float:medium' : 'FLOAT', 607 'float:big' : 'DOUBLE', 608 'float:normal' : 'FLOAT', 609 'numeric:normal' : 'DECIMAL', 610 'blob:big' : 'LONGBLOB', 611 'blob:normal' : 'BLOB', 612 'datetime:normal' : 'DATETIME' 613 } 614 return map_
615 616 617
618 -def rename_table(ret, table, new_name):
619 """ 620 Rename a table. 621 622 @param ret 623 Array to which query results will be added. 624 @param table 625 The table to be renamed. 626 @param new_name 627 The new name for the table. 628 """ 629 php.Reference.check(ref) 630 ret.append( update_sql('ALTER TABLE {' + table + '} RENAME TO {' + \ 631 new_name + '}') )
632 633 634
635 -def drop_table(ret, table):
636 """ 637 Drop a table. 638 639 @param ret 640 Array to which query results will be added. 641 @param table 642 The table to be dropped. 643 """ 644 php.Reference.check(ref) 645 php.array_merge( update_sql('DROP TABLE {' + table + '}'), ret, True )
646 647 648
649 -def add_field(ret, table, field, spec, keys_new = []):
650 """ 651 Add a new field to a table. 652 653 @param ret 654 Array to which query results will be added. 655 @param table 656 Name of the table to be altered. 657 @param field 658 Name of the field to be added. 659 @param spec 660 The field specification array, as taken from a schema definition. 661 The specification may also contain the key 'initial', the newly 662 created field will be set to the value of the key in all rows. 663 This is most useful for creating NOT None columns with no default 664 value in existing tables. 665 @param keys_new 666 Optional keys and indexes specification to be created on the 667 table along with adding the field. The format is the same as a 668 table specification but without the 'fields' element. If you are 669 adding a type 'serial' field, you MUST specify at least one key 670 or index including it in this array. @see db_change_field for more 671 explanation why. 672 """ 673 php.Reference.check(ret) 674 fixNone = False 675 if (not php.empty(spec['not None']) and not php.isset(spec, 'default')): 676 fixNone = True 677 spec['not None'] = False 678 query = 'ALTER TABLE {' + table + '} ADD ' 679 query += _db_create_field_sql(field, _db_process_field(spec)) 680 if (php.count(keys_new)): 681 query += ', ADD ' + php.implode(', ADD ', _db_create_keys_sql(keys_new)) 682 ret.append( update_sql(query) ) 683 if (php.isset(spec, 'initial')): 684 # All this because update_sql does not support %-placeholders. 685 sql = 'UPDATE {' + table + '} SET ' + field + ' = ' + \ 686 db_type_placeholder(spec['type']) 687 result = db_query(sql, spec['initial']) 688 ret.append( {'success' : result != False, \ 689 'query' : check_plain(sql + ' (' + spec['initial'] + ')')}) 690 if (fixNone): 691 spec['not None'] = True 692 db_change_field(ret, table, field, field, spec)
693 694 695
696 -def drop_field(ret, table, field):
697 """ 698 Drop a field. 699 700 @param ret 701 Array to which query results will be added. 702 @param table 703 The table to be altered. 704 @param field 705 The field to be dropped. 706 """ 707 php.Reference.check(ret) 708 ret.append( update_sql('ALTER TABLE {' + table + '} DROP ' + field) )
709 710
711 -def field_set_default(ret, table, field, default):
712 """ 713 Set the default value for a field. 714 715 @param ret 716 Array to which query results will be added. 717 @param table 718 The table to be altered. 719 @param field 720 The field to be altered. 721 @param default 722 Default value to be set. None for 'default None'. 723 """ 724 php.Reference.check(ret) 725 if (default == None): 726 default = 'None' 727 else: 728 default = ("'default'" if is_string(default) else default) 729 ret.append( update_sql('ALTER TABLE {' + table + \ 730 '} ALTER COLUMN ' + field + ' SET DEFAULT ' + default) )
731 732 733
734 -def field_set_no_default(ret, table, field):
735 """ 736 Set a field to have no default value. 737 738 @param ret 739 Array to which query results will be added. 740 @param table 741 The table to be altered. 742 @param field 743 The field to be altered. 744 """ 745 php.Reference.check(ret) 746 ret.append( update_sql('ALTER TABLE {' + table + \ 747 '} ALTER COLUMN ' + field + ' DROP DEFAULT') )
748 749 750 751
752 -def add_primary_key(ret, table, fields):
753 """ 754 Add a primary key. 755 756 @param ret 757 Array to which query results will be added. 758 @param table 759 The table to be altered. 760 @param fields 761 Fields for the primary key. 762 """ 763 php.Reference.check(ret) 764 ret.append( update_sql('ALTER TABLE {' + table + \ 765 '} ADD PRIMARY KEY (' + _db_create_key_sql(fields) + ')') )
766 767 768
769 -def drop_primary_key(ret, table):
770 """ 771 Drop the primary key. 772 773 @param ret 774 Array to which query results will be added. 775 @param table 776 The table to be altered. 777 """ 778 php.Reference.check(ret) 779 ret.append( update_sql('ALTER TABLE {' + table + \ 780 '} DROP PRIMARY KEY') )
781 782 783
784 -def add_unique_key(ret, table, name, fields):
785 """ 786 Add a unique key. 787 788 @param ret 789 Array to which query results will be added. 790 @param table 791 The table to be altered. 792 @param name 793 The name of the key. 794 @param fields 795 An array of field names. 796 """ 797 php.Reference.check(ret) 798 ret.val.append( update_sql('ALTER TABLE {' + table + \ 799 '} ADD UNIQUE KEY ' + name + ' (' + _db_create_key_sql(fields) + ')') )
800 801 802
803 -def drop_unique_key(ret, table, name):
804 """ 805 Drop a unique key. 806 807 @param ret 808 Array to which query results will be added. 809 @param table 810 The table to be altered. 811 @param name 812 The name of the key. 813 """ 814 php.Reference.check(ret) 815 ret.append( update_sql('ALTER TABLE {' + table + \ 816 '} DROP KEY ' + name) )
817 818 819
820 -def add_index(ret, table, name, fields):
821 """ 822 Add an index. 823 824 @param ret 825 Array to which query results will be added. 826 @param table 827 The table to be altered. 828 @param name 829 The name of the index. 830 @param fields 831 An array of field names. 832 """ 833 php.Reference.check(ret) 834 query = 'ALTER TABLE {' + table + '} ADD INDEX ' + name + \ 835 ' (' + _db_create_key_sql(fields) + ')' 836 ret.append( update_sql(query) )
837 838 839
840 -def drop_index(ret, table, name):
841 """ 842 Drop an index. 843 844 @param ret 845 Array to which query results will be added. 846 @param table 847 The table to be altered. 848 @param name 849 The name of the index. 850 """ 851 php.Reference.check(ret) 852 ret.append( update_sql('ALTER TABLE {' + table + \ 853 '} DROP INDEX ' + name) )
854 855 856
857 -def change_field(ret, table, field, field_new, spec, keys_new = []):
858 """ 859 Change a field definition. 860 861 IMPORTANT NOTE: To maintain database portability, you have to explicitly 862 recreate all indices and primary keys that are using the changed field. 863 864 That means that you have to drop all affected keys and indexes with 865 db_drop_{primary_key,unique_key,index}() before calling db_change_field(). 866 To recreate the keys and indices, pass the key definitions as the 867 optional keys_new argument directly to db_change_field(). 868 869 For example, suppose you have: 870 @code 871 schema['foo'] = array( 872 'fields' : array( 873 'bar' : array('type' : 'int', 'not None' : True) 874 ), 875 'primary key' : array('bar') 876 ) 877 @endcode 878 and you want to change foo.bar to be type serial, leaving it as the 879 primary key. The correct sequence is: 880 @code 881 db_drop_primary_key(ret, 'foo') 882 db_change_field(ret, 'foo', 'bar', 'bar', 883 array('type' : 'serial', 'not None' : True), 884 array('primary key' : array('bar'))) 885 @endcode 886 887 The reasons for this are due to the different database engines: 888 889 On PostgreSQL, changing a field definition involves adding a new field 890 and dropping an old one which* causes any indices, primary keys and 891 sequences (from serial-type fields) that use the changed field to be 892 dropped. 893 894 On MySQL, all type 'serial' fields must be part of at least one key 895 or index as soon as they are created. You cannot use 896 db_add_{primary_key,unique_key,index}() for this purpose because 897 the ALTER TABLE command will fail to add the column without a key 898 or index specification. The solution is to use the optional 899 keys_new argument to create the key or index at the same time as 900 field. 901 902 You could use db_add_{primary_key,unique_key,index}() in all cases 903 unless you are converting a field to be type serial. You can use 904 the keys_new argument in all cases. 905 906 @param ret 907 Array to which query results will be added. 908 @param table 909 Name of the table. 910 @param field 911 Name of the field to change. 912 @param field_new 913 New name for the field (set to the same as field if you don't want to 914 change the name). 915 @param spec 916 The field specification for the new field. 917 @param keys_new 918 Optional keys and indexes specification to be created on the 919 table along with changing the field. The format is the same as a 920 table specification but without the 'fields' element. 921 """ 922 php.Reference.check(ret) 923 sql = 'ALTER TABLE {' + table + '} CHANGE ' + field + ' ' + \ 924 _db_create_field_sql(field_new, _db_process_field(spec)) 925 if (php.count(keys_new) > 0): 926 sql += ', ADD ' + php.implode(', ADD ', _db_create_keys_sql(keys_new)) 927 ret.append( update_sql(sql) )
928 929
930 -def last_insert_id(table, field):
931 """ 932 Returns the last insert id. 933 934 @param table 935 The name of the table you inserted into. 936 @param field 937 The name of the autoincrement field. 938 """ 939 return db_result(db_query('SELECT LAST_INSERT_ID()'))
940 941 942
943 -def escape_string(data):
944 """ 945 Wrapper to escape a string 946 """ 947 return DrupyMySQL.mysqli_real_escape_string(lib_appglobals.active_db, data)
948 949 950 951 # 952 # Aliases 953 # 954 fetch_assoc = fetch_array 955