? drupal-6.x-siren-1.x/sites/default/files ? drupal-6.x-siren-1.x/sites/default/settings.php Index: drupal-6.x-siren-1.x/INSTALL.oracle.txt =================================================================== RCS file: drupal-6.x-siren-1.x/INSTALL.oracle.txt diff -N drupal-6.x-siren-1.x/INSTALL.oracle.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/INSTALL.oracle.txt 4 Feb 2008 03:15:15 -0000 @@ -0,0 +1,71 @@ +// $Id: INSTALL.oracle.txt,v 1.1 2007/12/09 17:45:21 hswong3i Exp $ + +CREATE THE Oracle DATABASE +-------------------------- + +This file describes how to create a Oracle database for Drupal. + +If you control your databases through a web-based control panel, +check its documentation, as the following instructions are for the +command line only. + +This step is only necessary if you don't already have a database +set-up (e.g. by your host). In the following examples, 'dba_user' is +an example Oracle user which has the CREATE and GRANT privileges. Use +the appropriate user name for your system. + +Optionally, you can create a new tablespace for your Drupal site +datebase. Log into sqlplus by following command: + + sqlplus dba_user + +sqlplus will prompt for the 'dba_user' database password. At the +sqlplus prompt, enter following command: + + CREATE TABLESPACE tablespace_name + DATAFILE 'file_directory_path' + SIZE filesize AUTOEXTEND ON NEXT extend_size; + +where + + 'tablespace_name' is the name of you new tablespace + 'file_directory_path' is the file location in database server + 'filesize' is the initial file size, e.g. 50K, 1000M. + 'extend_size' is the volumn for extension when data file is full + +First, you must create a new user for your Drupal site. At the +sqlplus prompt, enter the following command: + + CREATE USER username + IDENTIFIED BY "password"; + DEFAULT TABLESPACE tablespace_name; + GRANT CONNECT, RESOURCE TO username; + +where + + 'tablespace_name' is the name of you tablespace + 'username' is the username of your Oracle account + 'password' is the password required for that username + + Note: Unless your database user has all of the privileges listed + above, you will not be able to run Drupal. + +Oracle SPECIAL REQUIREMENTS +--------------------------- + +1. SYSTEM REQUIREMENT + + Oracle driver for Drupal is fully tested with below softwares: + Oracle Database 10g Release 2 (10.2.0.1.0) for Linux x86, + Zend Core for Oracle v.2 Linux x86, + Zend Framework 1.0.0, + PHP Version 5.2.3, + Apache 2.2.3 (Debian) + + You may use something newer than above, but there is no guarantee for + backward compatible. + +2. TABLE PREFIX LIMITATION + + Table prefix are limited in maximum 12 characters. Proved by testing, it + is suggested to use table prefix within 10 characters. Index: drupal-6.x-siren-1.x/INSTALL.pgsql.txt =================================================================== RCS file: drupal-6.x-siren-1.x/INSTALL.pgsql.txt diff -N drupal-6.x-siren-1.x/INSTALL.pgsql.txt --- drupal-6.x-siren-1.x/INSTALL.pgsql.txt 26 Nov 2007 16:36:42 -0000 1.7 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,28 +0,0 @@ -// $Id: INSTALL.pgsql.txt,v 1.7 2007/11/26 16:36:42 dries Exp $ - -CREATE THE PostgreSQL DATABASE ------------------------------- - -Note that the database must be created with UTF-8 (Unicode) encoding. - -1. CREATE DATABASE USER - - This step is only necessary if you don't already have a user set up (e.g. - by your host) or you want to create new user for use with Drupal only. The - following command creates a new user named "username" and asks for a - password for that user: - - createuser --pwprompt --encrypted --no-adduser --no-createdb username - - If everything works correctly, you'll see a "CREATE USER" notice. - -2. CREATE THE DRUPAL DATABASE - - This step is only necessary if you don't already have a database set up (e.g. - by your host) or you want to create new database for use with Drupal only. - The following command creates a new database named "databasename", which is - owned by previously created "username": - - createdb --encoding=UNICODE --owner=username databasename - - If everything works correctly, you'll see a "CREATE DATABASE" notice. Index: drupal-6.x-siren-1.x/INSTALL.postgresql.txt =================================================================== RCS file: drupal-6.x-siren-1.x/INSTALL.postgresql.txt diff -N drupal-6.x-siren-1.x/INSTALL.postgresql.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/INSTALL.postgresql.txt 4 Feb 2008 03:15:15 -0000 @@ -0,0 +1,28 @@ +// $Id: INSTALL.postgresql.txt,v 1.1 2007/12/09 17:45:21 hswong3i Exp $ + +CREATE THE PostgreSQL DATABASE +------------------------------ + +Note that the database must be created with UTF-8 (Unicode) encoding. + +1. CREATE DATABASE USER + + This step is only necessary if you don't already have a user set up (e.g. + by your host) or you want to create new user for use with Drupal only. The + following command creates a new user named "username" and asks for a + password for that user: + + createuser --pwprompt --encrypted --no-adduser --no-createdb username + + If everything works correctly, you'll see a "CREATE USER" notice. + +2. CREATE THE DRUPAL DATABASE + + This step is only necessary if you don't already have a database set up (e.g. + by your host) or you want to create new database for use with Drupal only. + The following command creates a new database named "databasename", which is + owned by previously created "username": + + createdb --encoding=UNICODE --owner=username databasename + + If everything works correctly, you'll see a "CREATE DATABASE" notice. Index: drupal-6.x-siren-1.x/MAINTAINERS.siren.txt =================================================================== RCS file: drupal-6.x-siren-1.x/MAINTAINERS.siren.txt diff -N drupal-6.x-siren-1.x/MAINTAINERS.siren.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/MAINTAINERS.siren.txt 4 Feb 2008 03:15:15 -0000 @@ -0,0 +1,24 @@ +// $Id$ + +List of maintainers +-------------------------------------------------------------------------------- + +LEGEND +====== + +- M: the maintainer +- S: status: + "supported" : someone is actually paid to look after this. + "maintained" : someone actually looks after it. + "fixes/patches" : it has a maintainer but they don't have time to + do much other than throw the odd patch in. + "orphan" : no current maintainer, but maybe you could take + the role as you write new code? +- W: website with status or information + +-------------------------------------------------------------------------------- + +Siren +M: Edison Wong +S: maintained +W: http://edin.no-ip.com/project/siren/ Index: drupal-6.x-siren-1.x/README.siren.txt =================================================================== RCS file: drupal-6.x-siren-1.x/README.siren.txt diff -N drupal-6.x-siren-1.x/README.siren.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/README.siren.txt 4 Feb 2008 03:15:15 -0000 @@ -0,0 +1,60 @@ +// $Id$ + +WHAT IS SIREN? +-------------- + +This is my personal project besides Drupal, which try to research the +possibility of other database supporting for Drupal, e.g. Oracle, IBM DB2, +MSSQL, SQLite, etc; on the other hand, I will provide unofficial database +supporting during Drupal-6.x life cycle, and further more contribute the +research progress for Drupal-7.x. + +For more information on Siren visit +the Siren project homepage at http://edin.no-ip.com/project/siren/ + +CURRENT RESEARCH PROGRESS +------------------------- + +Besides official Drupal-6.x mysql, mysqli and pgsql, Siren also provide +pdo_mysql, pdo_pgsql and oci8 database driver supporting. According to the +needs of PDO and Oracle drivers implementation, ALL core queries and some +APIs are hacked for compatibility concern. + +3rd PARTY MODULE HACK HOWTO +--------------------------- + +Based on cross database compatibility concern, Siren come with lots of core +queries hack. Most works are done for you, and it should run across +MySQl/PgSQL/Oracle without any critical problem. + +Anyway, you will also need to apply some 3rd party module. So how to let them +work together with this unofficial core? + +1. ENCLOSE ALL TABLE/COLUMN/CONSTRAINT NAME WITH [] + + Go though you target module, and enclose all table/column/constraint name + with [] syntax, which similar as {} syntax for all table. + + This can be helped by using VI + regex: /{[A-Za-z0-9_]*} + +2. REPLACE ALL '%s' SYNTAX WITH %s + + This is very important for unofficial PDO supporting. + + This can be helped by using VI + regex: :%s/'%s'/%s/gc + +3. REMOVE ANY %% SYNTAX + + PDO don't allow inline % syntax when using with ? placeholder. + + This can be helped by using VI + regex: /%% + +4. UTILIZE ALL DB_* ABSTRACTION IF POSSIBLE + + These abstraction are mainly duel with syntax different among different DB. + +5. USE %s EVEN IT IS AN EMPTY STRING + + Using empty string as placeholder will cause problem among Oracle and + MSSQL. Escape it by using %s. Oracle and MSSQL driver will able to catch + them and replace it as required empty string placeholder internally. Index: drupal-6.x-siren-1.x/UPGRADE.siren.txt =================================================================== RCS file: drupal-6.x-siren-1.x/UPGRADE.siren.txt diff -N drupal-6.x-siren-1.x/UPGRADE.siren.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/UPGRADE.siren.txt 4 Feb 2008 03:15:15 -0000 @@ -0,0 +1,12 @@ +// $Id$ + +UPGRADING FOR SIREN +------------------- + +As a flash new research project, Siren 1.x remove the direct upgrade handling +from Drupal 5.x. You should always use Siren for flash install. + +On the other hand, you may first upgrade your site from Drupal 5.x to +Drupal 6.x, and handle the convert from Drupal 6.x to Siren 1.x manually. +There is no guarantee about this handling, and please backup and do this with +your own risk. Index: drupal-6.x-siren-1.x/install.php =================================================================== RCS file: /cvs/drupal/drupal/install.php,v retrieving revision 1.113 diff -u -p -r1.113 install.php --- drupal-6.x-siren-1.x/install.php 25 Jan 2008 12:36:37 -0000 1.113 +++ drupal-6.x-siren-1.x/install.php 4 Feb 2008 03:15:16 -0000 @@ -136,7 +136,7 @@ function install_main() { */ function install_verify_drupal() { // Read the variable manually using the @ so we don't trigger an error if it fails. - $result = @db_query("SELECT value FROM {variable} WHERE name = '%s'", 'install_task'); + $result = @db_query("SELECT [value] FROM [{variable}] WHERE [name] = %s", 'install_task'); if ($result) { return unserialize(db_result($result)); } @@ -189,7 +189,7 @@ function install_change_settings($profil include_once './includes/form.inc'; install_task_list('database'); - if ($db_url == 'mysql://username:password@localhost/databasename') { + if ($db_url == 'drupal://username:password@localhost/databasename#mysql') { $db_user = $db_pass = $db_path = ''; } elseif (!empty($db_url)) { @@ -217,6 +217,15 @@ function install_settings_form(&$form_st if (isset($db_types['mysqli'])) { unset($db_types['mysql']); } + // If both 'mysqli' and 'pdo_mysql' are available, we disable 'mysqli': + if (isset($db_types['pdo_mysql'])) { + unset($db_types['mysqli']); + } + + // If both 'pgsql' and 'pdo_pgsql' are available, we disable 'pgsql': + if (isset($db_types['pdo_pgsql'])) { + unset($db_types['pgsql']); + } if (count($db_types) == 0) { $form['no_db_types'] = array( @@ -362,7 +371,8 @@ function _install_settings_form_validate // Check database type if (!isset($form)) { $_db_url = is_array($db_url) ? $db_url['default'] : $db_url; - $db_type = substr($_db_url, 0, strpos($_db_url, '://')); + $_db_url = parse_url($_db_url); + $db_type = $_db_url['fragment']; } $databases = drupal_detect_database_types(); if (!in_array($db_type, $databases)) { @@ -370,7 +380,7 @@ function _install_settings_form_validate } else { // Verify - $db_url = $db_type .'://'. urlencode($db_user) . ($db_pass ? ':'. urlencode($db_pass) : '') .'@'. ($db_host ? urlencode($db_host) : 'localhost') . ($db_port ? ":$db_port" : '') .'/'. urlencode($db_path); + $db_url = 'drupal://'. urlencode($db_user) . ($db_pass ? ':'. urlencode($db_pass) : '') .'@'. ($db_host ? urlencode($db_host) : 'localhost') . ($db_port ? ":$db_port" : '') .'/'. urlencode($db_path) .'#'. $db_type; if (isset($form)) { form_set_value($form['_db_url'], $db_url, $form_state); } Index: drupal-6.x-siren-1.x/update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.252 diff -u -p -r1.252 update.php --- drupal-6.x-siren-1.x/update.php 3 Feb 2008 18:41:16 -0000 1.252 +++ drupal-6.x-siren-1.x/update.php 4 Feb 2008 03:15:16 -0000 @@ -55,26 +55,26 @@ function db_add_column(&$ret, $table, $c if (array_key_exists('default', $attributes)) { if (is_null($attributes['default'])) { $default_val = 'NULL'; - $default = 'default NULL'; + $default = 'DEFAULT NULL'; } elseif ($attributes['default'] === FALSE) { $default = ''; } else { - $default_val = "$attributes[default]"; - $default = "default $attributes[default]"; + $default_val = $attributes['default']; + $default = "DEFAULT ". $attributes['default']; } } - $ret[] = update_sql("ALTER TABLE {". $table ."} ADD $column $type"); + $ret[] = update_sql("ALTER TABLE [{". $table ."}] ADD [$column] $type"); if (!empty($default)) { - $ret[] = update_sql("ALTER TABLE {". $table ."} ALTER $column SET $default"); + $ret[] = update_sql("ALTER TABLE [{". $table ."}] ALTER [$column] SET $default"); } if (!empty($not_null)) { if (!empty($default)) { - $ret[] = update_sql("UPDATE {". $table ."} SET $column = $default_val"); + $ret[] = update_sql("UPDATE [{". $table ."}] SET [$column] = $default_val"); } - $ret[] = update_sql("ALTER TABLE {". $table ."} ALTER $column SET NOT NULL"); + $ret[] = update_sql("ALTER TABLE [{". $table ."}] ALTER [$column] SET NOT NULL"); } } @@ -111,23 +111,23 @@ function db_change_column(&$ret, $table, if (array_key_exists('default', $attributes)) { if (is_null($attributes['default'])) { $default_val = 'NULL'; - $default = 'default NULL'; + $default = 'DEFAULT NULL'; } elseif ($attributes['default'] === FALSE) { $default = ''; } else { - $default_val = "$attributes[default]"; - $default = "default $attributes[default]"; + $default_val = $attributes['default']; + $default = "DEFAULT ". $attributes['default']; } } - $ret[] = update_sql("ALTER TABLE {". $table ."} RENAME $column TO ". $column ."_old"); - $ret[] = update_sql("ALTER TABLE {". $table ."} ADD $column_new $type"); - $ret[] = update_sql("UPDATE {". $table ."} SET $column_new = ". $column ."_old"); - if ($default) { $ret[] = update_sql("ALTER TABLE {". $table ."} ALTER $column_new SET $default"); } - if ($not_null) { $ret[] = update_sql("ALTER TABLE {". $table ."} ALTER $column_new SET NOT NULL"); } - $ret[] = update_sql("ALTER TABLE {". $table ."} DROP ". $column ."_old"); + $ret[] = update_sql("ALTER TABLE [{". $table ."}] RENAME [$column] TO [". $column ."_old]"); + $ret[] = update_sql("ALTER TABLE [{". $table ."}] ADD [$column_new] $type"); + $ret[] = update_sql("UPDATE [{". $table ."}] SET [$column_new] = [". $column ."_old]"); + if ($default) { $ret[] = update_sql("ALTER TABLE [{". $table ."}] ALTER [$column_new] SET $default"); } + if ($not_null) { $ret[] = update_sql("ALTER TABLE [{". $table ."}] ALTER [$column_new] SET NOT NULL"); } + $ret[] = update_sql("ALTER TABLE [{". $table ."}] DROP [". $column ."_old]"); } /** @@ -428,14 +428,14 @@ function update_create_batch_table() { function update_fix_compatibility() { $ret = array(); $incompatible = array(); - $query = db_query("SELECT name, type, status FROM {system} WHERE status = 1 AND type IN ('module','theme')"); + $query = db_query("SELECT [name], [type], [status] FROM [{system}] WHERE [status] = 1 AND [type] IN ('module', 'theme')"); while ($result = db_fetch_object($query)) { if (update_check_incompatibility($result->name, $result->type)) { $incompatible[] = $result->name; } } if (!empty($incompatible)) { - $ret[] = update_sql("UPDATE {system} SET status = 0 WHERE name IN ('". implode("','", $incompatible) ."')"); + $ret[] = update_sql("UPDATE [{system}] SET [status] = 0 WHERE [name] IN ('". implode("', '", $incompatible) ."')"); } return $ret; } Index: drupal-6.x-siren-1.x/includes/actions.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/actions.inc,v retrieving revision 1.8 diff -u -p -r1.8 actions.inc --- drupal-6.x-siren-1.x/includes/actions.inc 31 Dec 2007 14:51:04 -0000 1.8 +++ drupal-6.x-siren-1.x/includes/actions.inc 4 Feb 2008 03:15:16 -0000 @@ -54,7 +54,7 @@ function actions_do($action_ids, &$objec $where_values = array(); foreach ($action_ids as $action_id) { if (is_numeric($action_id)) { - $where[] = 'OR aid = %d'; + $where[] = 'OR [aid] = %d'; $where_values[] = $action_id; } elseif (isset($available_actions[$action_id])) { @@ -68,7 +68,7 @@ function actions_do($action_ids, &$objec $where_clause = implode(' ', $where); // Strip off leading 'OR '. $where_clause = '('. strstr($where_clause, " ") .')'; - $result_db = db_query('SELECT * FROM {actions} WHERE '. $where_clause, $where_values); + $result_db = db_query('SELECT * FROM [{actions}] WHERE '. $where_clause, $where_values); while ($action = db_fetch_object($result_db)) { $actions[$action->aid] = $action->parameters ? unserialize($action->parameters) : array(); $actions[$action->aid]['callback'] = $action->callback; @@ -93,7 +93,7 @@ function actions_do($action_ids, &$objec else { // If it's a configurable action, retrieve stored parameters. if (is_numeric($action_ids)) { - $action = db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = %d", $action_ids)); + $action = db_fetch_object(db_query("SELECT * FROM [{actions}] WHERE [aid] = %d", $action_ids)); $function = $action->callback; $context = array_merge($context, unserialize($action->parameters)); $result[$action_ids] = $function($object, $context, $a1, $a2); @@ -177,7 +177,7 @@ function actions_list($reset = FALSE) { */ function actions_get_all_actions() { $actions = array(); - $result = db_query("SELECT * FROM {actions}"); + $result = db_query("SELECT * FROM [{actions}]"); while ($action = db_fetch_object($result)) { $actions[$action->aid] = array( 'callback' => $action->callback, @@ -238,7 +238,7 @@ function actions_function_lookup($hash) } // Must be an instance; must check database. - $aid = db_result(db_query("SELECT aid FROM {actions} WHERE MD5(aid) = '%s' AND parameters != ''", $hash)); + $aid = db_result(db_query("SELECT [aid] FROM [{actions}] WHERE MD5([aid]) = %s AND [parameters] <> %s", $hash, '')); return $aid; } @@ -255,7 +255,7 @@ function actions_synchronize($actions_in $actions_in_code = actions_list(); } $actions_in_db = array(); - $result = db_query("SELECT * FROM {actions} WHERE parameters = ''"); + $result = db_query("SELECT * FROM [{actions}] WHERE [parameters] = %s", ''); while ($action = db_fetch_object($result)) { $actions_in_db[$action->callback] = array('aid' => $action->aid, 'description' => $action->description); } @@ -271,7 +271,7 @@ function actions_synchronize($actions_in } else { // This is a new singleton that we don't have an aid for; assign one. - db_query("INSERT INTO {actions} (aid, type, callback, parameters, description) VALUES ('%s', '%s', '%s', '%s', '%s')", $callback, $array['type'], $callback, '', $array['description']); + db_query("INSERT INTO [{actions}] ([aid], [type], [callback], [parameters], [description]) VALUES (%s, %s, %s, %s, %s)", $callback, $array['type'], $callback, '', $array['description']); watchdog('actions', "Action '%action' added.", array('%action' => filter_xss_admin($array['description']))); } } @@ -284,14 +284,14 @@ function actions_synchronize($actions_in foreach ($actions_in_db as $callback => $array) { $orphaned[] = $callback; - $placeholder[] = "'%s'"; + $placeholder[] = "%s"; } $orphans = implode(', ', $orphaned); if ($delete_orphans) { $placeholders = implode(', ', $placeholder); - $results = db_query("SELECT a.aid, a.description FROM {actions} a WHERE callback IN ($placeholders)", $orphaned); + $results = db_query("SELECT a.[aid], a.[description] FROM [{actions}] a WHERE [callback] IN ($placeholders)", $orphaned); while ($action = db_fetch_object($results)) { actions_delete($action->aid); watchdog('actions', "Removed orphaned action '%action' from database.", array('%action' => filter_xss_admin($action->description))); @@ -325,15 +325,15 @@ function actions_synchronize($actions_in function actions_save($function, $type, $params, $desc, $aid = NULL) { $serialized = serialize($params); if ($aid) { - db_query("UPDATE {actions} SET callback = '%s', type = '%s', parameters = '%s', description = '%s' WHERE aid = %d", $function, $type, $serialized, $desc, $aid); + db_query("UPDATE [{actions}] SET [callback] = %s, [type] = %s, [parameters] = %s, [description] = %s WHERE [aid] = %d", $function, $type, $serialized, $desc, $aid); watchdog('actions', 'Action %action saved.', array('%action' => $desc)); } else { // aid is the callback for singleton actions so we need to keep a // separate table for numeric aids. - db_query('INSERT INTO {actions_aid} VALUES (default)'); + db_query('INSERT INTO [{actions_aid}] VALUES (default)'); $aid = db_last_insert_id('actions_aid', 'aid'); - db_query("INSERT INTO {actions} (aid, callback, type, parameters, description) VALUES (%d, '%s', '%s', '%s', '%s')", $aid, $function, $type, $serialized, $desc); + db_query("INSERT INTO [{actions}] ([aid], [callback], [type], [parameters], [description]) VALUES (%d, %s, %s, %s, %s)", $aid, $function, $type, $serialized, $desc); watchdog('actions', 'Action %action created.', array('%action' => $desc)); } @@ -350,7 +350,7 @@ function actions_save($function, $type, * The appropriate action row from the database as an object. */ function actions_load($aid) { - return db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = %d", $aid)); + return db_fetch_object(db_query("SELECT * FROM [{actions}] WHERE [aid] = %d", $aid)); } /** @@ -360,6 +360,6 @@ function actions_load($aid) { * integer The ID of the action to delete. */ function actions_delete($aid) { - db_query("DELETE FROM {actions} WHERE aid = %d", $aid); + db_query("DELETE FROM [{actions}] WHERE [aid] = %d", $aid); module_invoke_all('actions_delete', $aid); } Index: drupal-6.x-siren-1.x/includes/batch.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/batch.inc,v retrieving revision 1.14 diff -u -p -r1.14 batch.inc --- drupal-6.x-siren-1.x/includes/batch.inc 20 Dec 2007 11:57:20 -0000 1.14 +++ drupal-6.x-siren-1.x/includes/batch.inc 4 Feb 2008 03:15:16 -0000 @@ -12,7 +12,7 @@ function _batch_page() { $batch =& batch_get(); // Retrieve the current state of batch from db. - if (isset($_REQUEST['id']) && $data = db_result(db_query("SELECT batch FROM {batch} WHERE bid = %d AND token = '%s'", $_REQUEST['id'], drupal_get_token($_REQUEST['id'])))) { + if (isset($_REQUEST['id']) && $data = db_result(db_query("SELECT [batch] FROM [{batch}] WHERE [bid] = %d AND [token] = %s", $_REQUEST['id'], drupal_get_token($_REQUEST['id'])))) { $batch = unserialize($data); } else { @@ -305,7 +305,7 @@ function _batch_finished() { // Cleanup the batch table and unset the global $batch variable. if ($batch['progressive']) { - db_query("DELETE FROM {batch} WHERE bid = %d", $batch['id']); + db_query("DELETE FROM [{batch}] WHERE [bid] = %d", $batch['id']); } $_batch = $batch; $batch = NULL; @@ -349,6 +349,6 @@ function _batch_finished() { */ function _batch_shutdown() { if ($batch = batch_get()) { - db_query("UPDATE {batch} SET batch = '%s' WHERE bid = %d", serialize($batch), $batch['id']); + db_query("UPDATE [{batch}] SET [batch] = %s WHERE [bid] = %d", serialize($batch), $batch['id']); } } Index: drupal-6.x-siren-1.x/includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.206 diff -u -p -r1.206 bootstrap.inc --- drupal-6.x-siren-1.x/includes/bootstrap.inc 10 Jan 2008 22:47:17 -0000 1.206 +++ drupal-6.x-siren-1.x/includes/bootstrap.inc 4 Feb 2008 03:15:16 -0000 @@ -384,7 +384,7 @@ function drupal_get_filename($type, $nam // the database. This is required because this function is called both // before we have a database connection (i.e. during installation) and // when a database connection fails. - elseif (db_is_active() && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) { + elseif (db_is_active() && (($file = db_result(db_query("SELECT [filename] FROM [{system}] WHERE [name] = %s AND [type] = %s", $name, $type))) && file_exists($file))) { $files[$type][$name] = $file; } else { @@ -420,7 +420,7 @@ function variable_init($conf = array()) $variables = $cached->data; } else { - $result = db_query('SELECT * FROM {variable}'); + $result = db_query('SELECT * FROM [{variable}]'); while ($variable = db_fetch_object($result)) { $variables[$variable->name] = unserialize($variable->value); } @@ -463,9 +463,9 @@ function variable_set($name, $value) { global $conf; $serialized_value = serialize($value); - db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name); + db_query("UPDATE [{variable}] SET [value] = %s WHERE [name] = %s", $serialized_value, $name); if (!db_affected_rows()) { - @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value); + @db_query("INSERT INTO [{variable}] ([name], [value]) VALUES (%s, %s)", $name, $serialized_value); } cache_clear_all('variables', 'cache'); @@ -482,7 +482,7 @@ function variable_set($name, $value) { function variable_del($name) { global $conf; - db_query("DELETE FROM {variable} WHERE name = '%s'", $name); + db_query("DELETE FROM [{variable}] WHERE [name] = %s", $name); cache_clear_all('variables', 'cache'); unset($conf[$name]); @@ -865,13 +865,19 @@ function drupal_get_messages($type = NUL * TRUE if access is denied, FALSE if access is allowed. */ function drupal_is_denied($type, $mask) { - // Because this function is called for every page request, both cached - // and non-cached pages, we tried to optimize it as much as possible. - // We deny access if the only matching records in the {access} table have - // status 0 (deny). If any have status 1 (allow), or if there are no - // matching records, we allow access. - $sql = "SELECT 1 FROM {access} WHERE type = '%s' AND LOWER('%s') LIKE LOWER(mask) AND status = %d"; - return db_result(db_query_range($sql, $type, $mask, 0, 0, 1)) && !db_result(db_query_range($sql, $type, $mask, 1, 0, 1)); + switch ($GLOBALS['db_type']) { + case 'ibm_db2': + case 'pdo_ibm': + return FALSE; + default: + // Because this function is called for every page request, both cached + // and non-cached pages, we tried to optimize it as much as possible. + // We deny access if the only matching records in the {access} table have + // status 0 (deny). If any have status 1 (allow), or if there are no + // matching records, we allow access. + $sql = "SELECT 1 FROM [{access}] WHERE [type] = %s AND LOWER(%s) LIKE LOWER([mask]) AND [status] = %d"; + return db_result(db_query_range($sql, $type, $mask, 0, 0, 1)) && !db_result(db_query_range($sql, $type, $mask, 1, 0, 1)); + } } /** @@ -1069,7 +1075,7 @@ function language_list($field = 'languag // Init language list if (!isset($languages)) { if (variable_get('language_count', 1) > 1 || module_exists('locale')) { - $result = db_query('SELECT * FROM {languages} ORDER BY weight ASC, name ASC'); + $result = db_query('SELECT * FROM [{languages}] ORDER BY [weight] ASC, [name] ASC'); while ($row = db_fetch_object($result)) { $languages['language'][$row->language] = $row; } Index: drupal-6.x-siren-1.x/includes/cache.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/cache.inc,v retrieving revision 1.17 diff -u -p -r1.17 cache.inc --- drupal-6.x-siren-1.x/includes/cache.inc 29 Jan 2008 11:36:06 -0000 1.17 +++ drupal-6.x-siren-1.x/includes/cache.inc 4 Feb 2008 03:15:16 -0000 @@ -20,10 +20,10 @@ function cache_get($cid, $table = 'cache // Reset the variable immediately to prevent a meltdown in heavy load situations. variable_set('cache_flush', 0); // Time to flush old cache data - db_query("DELETE FROM {". $table ."} WHERE expire != %d AND expire <= %d", CACHE_PERMANENT, $cache_flush); + db_query("DELETE FROM [{". $table ."}] WHERE [expire] <> %d AND [expire] <= %d", CACHE_PERMANENT, $cache_flush); } - $cache = db_fetch_object(db_query("SELECT data, created, headers, expire, serialized FROM {". $table ."} WHERE cid = '%s'", $cid)); + $cache = db_fetch_object(db_query("SELECT [data], [created], [headers], [expire], [serialized] FROM [{". $table ."}] WHERE [cid] = %s", $cid)); if (isset($cache->data)) { // If the data is permanent or we're not enforcing a minimum cache lifetime // always return the cached data. @@ -106,9 +106,17 @@ function cache_set($cid, $data, $table = $serialized = 1; } $created = time(); - db_query("UPDATE {". $table ."} SET data = %b, created = %d, expire = %d, headers = '%s', serialized = %d WHERE cid = '%s'", $data, $created, $expire, $headers, $serialized, $cid); + $values = array( + array('field' => 'data', 'placeholder' => '%b', 'data' => $data), + array('field' => 'created', 'placeholder' => '%d', 'data' => $created), + array('field' => 'expire', 'placeholder' => '%d', 'data' => $expire), + array('field' => 'headers', 'placeholder' => "%s", 'data' => $headers), + array('field' => 'serialized', 'placeholder' => '%d', 'data' => $serialized), + ); + db_query_update($table, $values, "[cid] = %s", $cid); if (!db_affected_rows()) { - @db_query("INSERT INTO {". $table ."} (cid, data, created, expire, headers, serialized) VALUES ('%s', %b, %d, %d, '%s', %d)", $cid, $data, $created, $expire, $headers, $serialized); + $values[] = array('field' => 'cid', 'placeholder' => "%s", 'data' => $cid); + db_query_insert($table, $values); } } @@ -157,26 +165,26 @@ function cache_clear_all($cid = NULL, $t else if (time() > ($cache_flush + variable_get('cache_lifetime', 0))) { // Clear the cache for everyone, cache_flush_delay seconds have // passed since the first request to clear the cache. - db_query("DELETE FROM {". $table ."} WHERE expire != %d AND expire < %d", CACHE_PERMANENT, time()); + db_query("DELETE FROM [{". $table ."}] WHERE [expire] <> %d AND [expire] < %d", CACHE_PERMANENT, time()); variable_set('cache_flush', 0); } } else { // No minimum cache lifetime, flush all temporary cache entries now. - db_query("DELETE FROM {". $table ."} WHERE expire != %d AND expire < %d", CACHE_PERMANENT, time()); + db_query("DELETE FROM [{". $table ."}] WHERE [expire] <> %d AND [expire] < %d", CACHE_PERMANENT, time()); } } else { if ($wildcard) { if ($cid == '*') { - db_query("DELETE FROM {". $table ."}"); + db_query("DELETE FROM [{". $table ."}]"); } else { - db_query("DELETE FROM {". $table ."} WHERE cid LIKE '%s%%'", $cid); + db_query("DELETE FROM [{". $table ."}] WHERE [cid] LIKE %s", $cid ."%"); } } else { - db_query("DELETE FROM {". $table ."} WHERE cid = '%s'", $cid); + db_query("DELETE FROM [{". $table ."}] WHERE [cid] = %s", $cid); } } } Index: drupal-6.x-siren-1.x/includes/common.db2.inc =================================================================== RCS file: drupal-6.x-siren-1.x/includes/common.db2.inc diff -N drupal-6.x-siren-1.x/includes/common.db2.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/includes/common.db2.inc 4 Feb 2008 03:15:16 -0000 @@ -0,0 +1,397 @@ + $t('DB2 database'), + 'value' => $version, + ); + + if (version_compare($version, DRUPAL_MINIMUM_DB2) < 0) { + $form['db2']['severity'] = REQUIREMENT_ERROR; + $form['db2']['description'] = $t('Your DB2 Server is too old. Drupal requires at least DB2 %version.', array('%version' => DRUPAL_MINIMUM_DB2)); + } + + return $form; +} + +/** + * Returns the version of the database server currently in use. + * + * @return Database server version + */ +function db_version() { + $banner = db_result(db_query("SELECT SERVICE_LEVEL FROM TABLE (SYSPROC.ENV_GET_INST_INFO()) AS INSTANCEINFO")); + preg_match('/\s*v([0-9.]+)\s*/', $banner, $version); + return array_pop($version); +} + +/** + * Insert a row of record into database. + * + * @param $table + * Table to insert. + * @param $values + * An array containing the insert values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_insert($table, $values) { + $fields = array(); + $placeholders = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = $value['field']; + $placeholders[] = $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "INSERT INTO [{". $table ."}] ([". implode('], [', $fields) ."]) VALUES (". implode(', ', $placeholders) .")"; + return db_query($query, $data); +} + +/** + * Update a row of record in database. + * + * @param $table + * Table to update. + * @param $values + * An array containing the update values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_update($table, $values, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 3); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $fields = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = '['. $value['field'] .'] = '. $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "UPDATE [{". $table ."}] SET ". implode(', ', $fields); + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = array_merge($data, $args); + } + return db_query($query, $data); +} + +/** + * Delete a row of record from database. + * + * @param $table + * Table to delete. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_delete($table, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 2); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $data = array(); + + $query = "DELETE FROM [{". $table ."}]"; + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = $args; + } + return db_query($query, $data); +} + +/** + * Returns the last insert id. This function is thread safe. + * + * @param $table + * The name of the table you inserted into. + * @param $field + * The name of the autoincrement field. + */ +function db_last_insert_id($table, $field) { + return db_result(db_query("SELECT SYSIBM.IDENTITY_VAL_LOCAL() FROM [{". $table ."}]")); +} + +/** + * Runs a limited-range query in the active database. + * + * Use this as a substitute for db_query() when a subset of the query + * is to be returned. + * User-supplied arguments to the query should be passed in as separate + * parameters so that they can be properly escaped to avoid SQL injection + * attacks. + * + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. Instead of a variable number of query arguments, + * you may also pass a single array containing the query arguments. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: use NULL as arguments substitution for %b and %c. This will be + * replaced as corresponding empty LOB value placeholder, based on the + * database specific representation. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $from + * The first result row to return. + * @param $count + * The maximum number of result rows to return. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_range($query) { + $args = func_get_args(); + $count = array_pop($args); + $from = array_pop($args); + array_shift($args); + + $query = 'SELECT * FROM (SELECT [sub1].*, ROW_NUMBER() OVER() AS [line2] FROM (' . $query . ') AS [sub1]) AS [sub2] WHERE [line2] BETWEEN ' . $from . ' AND ' . ($from + $count); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Runs a SELECT query and stores its results in a temporary table. + * + * Use this as a substitute for db_query() when the results need to stored + * in a temporary table. Temporary tables exist for the duration of the page + * request. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * + * Note that if you need to know how many results were returned, you should do + * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() do + * not give consistent result across different database types in this case. + * + * @param $query + * A string containing a normal SELECT SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. The query arguments can be enclosed in one + * array instead. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: use NULL as arguments substitution for %b and %c. This will be + * replaced as corresponding empty LOB value placeholder, based on the + * database specific representation. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $table + * The name of the temporary table to select into. This name will not be + * prefixed as there is no risk of collision. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_temporary($query) { + $args = func_get_args(); + $tablename = array_pop($args); + array_shift($args); + + $query = 'DECLARE GLOBAL TEMPORARY TABLE ['. $tablename .'] AS (' . $query . ') DEFINITION ONLY INCLUDING IDENTITY COLUMN ATTRIBUTES INCLUDING COLUMN DEFAULTS ON COMMIT PRESERVE ROWS NOT LOGGED'; + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Lock a table. + * This function automatically starts a transaction. + */ +function db_lock_table($table) { + db_query('LOCK TABLE [{'. db_escape_table($table) .'}] IN EXCLUSIVE MODE'); +} + +/** + * Unlock all locked tables. + * This function automatically commits a transaction. + */ +function db_unlock_tables() { + db_query('COMMIT'); +} + +/** + * Check if a table exists. + */ +function db_table_exists($table) { + return (bool) db_result(db_query("SELECT COUNT(TABLE_NAME) FROM SYSIBM.TABLES WHERE TABLE_NAME LIKE '{". db_escape_table($table) ."}'")); +} + +/** + * Check if a column exists in the given table. + */ +function db_column_exists($table, $column) { + return (bool) db_result(db_query("SELECT COUNT(COLUMN_NAME) FROM SYSIBM.COLUMNS WHERE TABLE_NAME LIKE '{". db_escape_table($table) ."}' AND COLUMN_NAME LIKE '" . db_escape_table($column) ."'")); +} + +/** + * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to + * the SELECT list entry of the given query and the resulting query is returned. + * This function only applies the wrapper if a DISTINCT doesn't already exist in + * the query. + * + * @param $table Table containing the field to set as DISTINCT + * @param $field Field to set as DISTINCT + * @param $query Query to apply the wrapper to + * @return SQL query with the DISTINCT wrapper surrounding the given table.field. + */ +function db_distinct_field($table, $field, $query) { + $field_to_select = 'DISTINCT (['. $table .'].['. $field .'])'; + // (? %d", $name, ip_address(), time() - 3600)); + $number = db_result(db_query("SELECT COUNT(*) FROM [{flood}] WHERE [event] = %s AND [hostname] = %s AND [timestamp] > %d", $name, ip_address(), time() - 3600)); return ($number < $threshold ? TRUE : FALSE); } @@ -3194,7 +3194,9 @@ function _drupal_initialize_schema($modu **/ function drupal_schema_fields_sql($table, $prefix = NULL) { $schema = drupal_get_schema($table); - $fields = array_keys($schema['fields']); + foreach ($schema['fields'] as $key => $value) { + $fields[] = '['. $key .']'; + } if ($prefix) { $columns = array(); foreach ($fields as $field) { @@ -3219,7 +3221,7 @@ function drupal_schema_fields_sql($table * The object to write. This is a reference, as defaults according to * the schema may be filled in on the object, as well as ID on the serial * type(s). Both array an object types may be passed. - * @param $update + * @param primary_keys * If this is an update, specify the primary keys' field names. It is the * caller's responsibility to know if a record for this object already * exists in the database. If there is only 1 key, you may pass a simple string. @@ -3230,19 +3232,15 @@ function drupal_schema_fields_sql($table * the $table. For example, $object->nid will be populated after inserting * a new node. */ -function drupal_write_record($table, &$object, $update = array()) { - // Standardize $update to an array. - if (is_string($update)) { - $update = array($update); +function drupal_write_record($table, &$object, $primary_keys = array()) { + // Standardize $primary_keys to an array. + if (!is_array($primary_keys)) { + $primary_keys = array($primary_keys); } // Convert to an object if needed. - if (is_array($object)) { + if ($array = is_array($object)) { $object = (object) $object; - $array = TRUE; - } - else { - $array = FALSE; } $schema = drupal_get_schema($table); @@ -3250,18 +3248,19 @@ function drupal_write_record($table, &$o return FALSE; } - $fields = $defs = $values = $serials = $placeholders = array(); + $values = array(); + $serials = array(); // Go through our schema, build SQL, and when inserting, fill in defaults for // fields that are not set. foreach ($schema['fields'] as $field => $info) { // Special case -- skip serial types if we are updating. - if ($info['type'] == 'serial' && count($update)) { + if ($info['type'] == 'serial' && count($primary_keys)) { continue; } // For inserts, populate defaults from Schema if not already provided - if (!isset($object->$field) && !count($update) && isset($info['default'])) { + if (!isset($object->$field) && !count($primary_keys) && isset($info['default'])) { $object->$field = $info['default']; } @@ -3274,44 +3273,40 @@ function drupal_write_record($table, &$o // Build arrays for the fields, placeholders, and values in our query. if (isset($object->$field)) { - $fields[] = $field; - $placeholders[] = db_type_placeholder($info['type']); + $value['field'] = $field; + $value['placeholder'] = db_type_placeholder($info['type']); if (empty($info['serialize'])) { - $values[] = $object->$field; + $value['data'] = $object->$field; } else { - $values[] = serialize($object->$field); + $value['data'] = serialize($object->$field); } + + $values[] = $value; } } - // Build the SQL. - $query = ''; - if (!count($update)) { - $query = "INSERT INTO {". $table ."} (". implode(', ', $fields) .') VALUES ('. implode(', ', $placeholders) .')'; + // Execute the SQL. + if (!count($primary_keys)) { + $result = db_query_insert($table, $values); $return = SAVED_NEW; } else { - $query = ''; - foreach ($fields as $id => $field) { - if ($query) { - $query .= ', '; + foreach ($primary_keys as $key => $value){ + // $primary_key is NOT in key-value pair format. + if (!isset($schema['fields'][$key]) && isset($schema['fields'][$value])) { + $key = $value; + $value = $object->$key; } - $query .= $field .' = '. $placeholders[$id]; - } - - foreach ($update as $key){ - $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']); - $values[] = $object->$key; + $conditions[] = "[$key] = ". db_type_placeholder($schema['fields'][$key]['type']); + $args[] = $value; } - - $query = "UPDATE {". $table ."} SET $query WHERE ". implode(' AND ', $conditions); + $result = db_query_update($table, $values, implode(' AND ', $conditions), $args); $return = SAVED_UPDATED; } - // Execute the SQL. - if (db_query($query, $values)) { + if ($result) { if ($serials) { // Get last insert ids and fill them in. foreach ($serials as $field) { @@ -3331,6 +3326,47 @@ function drupal_write_record($table, &$o } /** + * Drop a record from the database based upon the schema. + * + * @param $table + * The name of the table; this must exist in schema API. + * @param $object + * The object to drop. This is a reference, as defaults according to + * the schema may be filled in on the object, as well as ID on the serial + * type(s). Both array an object types may be passed. + * @param primary_keys + * Specify the primary keys' field names. If there is only 1 key, you may + * pass a simple string. + * @return (boolean) Failure to write a record will return FALSE. Otherwise, + * TRUE is returned. + */ +function drupal_drop_record($table, $object, $primary_keys = array()) { + // Standardize $primary_keys to an array. + if (!is_array($primary_keys)) { + $primary_keys = array($primary_keys); + } + + // Convert to an object if needed. + if ($array = is_array($object)) { + $object = (object) $object; + } + + $schema = drupal_get_schema($table); + if (empty($schema)) { + return FALSE; + } + + // Execute the request. + foreach ($primary_keys as $key){ + $conditions[] = "[$key] = ". db_type_placeholder($schema['fields'][$key]['type']); + $args[] = $object->$key; + } + db_query_delete($table, implode(' AND ', $conditions), $args); + + return SAVED_DELETED; +} + +/** * @} End of "ingroup schemaapi". */ Index: drupal-6.x-siren-1.x/includes/common.mysql.inc =================================================================== RCS file: drupal-6.x-siren-1.x/includes/common.mysql.inc diff -N drupal-6.x-siren-1.x/includes/common.mysql.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/includes/common.mysql.inc 4 Feb 2008 03:15:17 -0000 @@ -0,0 +1,385 @@ + 0) ? "CONCAT($return)" : ''; +} + +/** + * Returns a string that is the equivalent of MySQL IFNULL or Oracle NVL. + * + * @return + * If $expr1 is not NULL, returns $expr1; otherwise it returns $expr2. + */ +function db_if_null($expr1, $expr2) { + return " IFNULL($expr1, $expr2) "; +} + +/** + * Report database status. + */ +function db_status_report($phase) { + $t = get_t(); + + $version = db_version(); + + $form['mysql'] = array( + 'title' => $t('MySQL database'), + 'value' => ($phase == 'runtime') ? l($version, 'admin/reports/status/sql') : $version, + ); + + if (version_compare($version, DRUPAL_MINIMUM_MYSQL) < 0) { + $form['mysql']['severity'] = REQUIREMENT_ERROR; + $form['mysql']['description'] = $t('Your MySQL Server is too old. Drupal requires at least MySQL %version.', array('%version' => DRUPAL_MINIMUM_MYSQL)); + } + + return $form; +} + +/** + * Returns the version of the database server currently in use. + * + * @return Database server version + */ +function db_version() { + global $active_db; + list($version) = explode('-', db_result(db_query("SELECT VERSION();"))); + return $version; +} + +/** + * Insert a row of record into database. + * + * @param $table + * Table to insert. + * @param $values + * An array containing the insert values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_insert($table, $values) { + $fields = array(); + $placeholders = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = $value['field']; + $placeholders[] = $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "INSERT INTO [{". $table ."}] ([". implode('], [', $fields) ."]) VALUES (". implode(', ', $placeholders) .")"; + return db_query($query, $data); +} + +/** + * Update a row of record in database. + * + * @param $table + * Table to update. + * @param $values + * An array containing the update values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_update($table, $values, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 3); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $fields = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = '['. $value['field'] .'] = '. $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "UPDATE [{". $table ."}] SET ". implode(', ', $fields); + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = array_merge($data, $args); + } + return db_query($query, $data); +} + +/** + * Delete a row of record from database. + * + * @param $table + * Table to delete. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_delete($table, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 2); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $data = array(); + + $query = "DELETE FROM [{". $table ."}]"; + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = $args; + } + return db_query($query, $data); +} + +/** + * Returns the last insert id. + * + * @param $table + * The name of the table you inserted into. + * @param $field + * The name of the autoincrement field. + */ +function db_last_insert_id($table, $field) { + return db_result(db_query('SELECT LAST_INSERT_ID()')); +} + +/** + * Runs a limited-range query in the active database. + * + * Use this as a substitute for db_query() when a subset of the query is to be + * returned. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. The query arguments can be enclosed in one + * array instead. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $from + * The first result row to return. + * @param $count + * The maximum number of result rows to return. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_range($query) { + $args = func_get_args(); + $count = array_pop($args); + $from = array_pop($args); + array_shift($args); + + $query .= ' LIMIT '. (int) $from .', '. (int) $count; + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Runs a SELECT query and stores its results in a temporary table. + * + * Use this as a substitute for db_query() when the results need to stored + * in a temporary table. Temporary tables exist for the duration of the page + * request. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * + * Note that if you need to know how many results were returned, you should do + * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() does + * not give consistent result across different database types in this case. + * + * @param $query + * A string containing a normal SELECT SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. The query arguments can be enclosed in one + * array instead. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $table + * The name of the temporary table to select into. This name will not be + * prefixed as there is no risk of collision. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_temporary($query) { + $args = func_get_args(); + $tablename = array_pop($args); + array_shift($args); + + $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' Engine=HEAP SELECT', $query); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Lock a table. + */ +function db_lock_table($table) { + db_query('LOCK TABLES [{'. db_escape_table($table) .'}] WRITE'); +} + +/** + * Unlock all locked tables. + */ +function db_unlock_tables() { + db_query('UNLOCK TABLES'); +} + +/** + * Check if a table exists. + */ +function db_table_exists($table) { + return (bool) db_fetch_object(db_query("SHOW TABLES LIKE '{". db_escape_table($table) ."}'")); +} + +/** + * Check if a column exists in the given table. + */ +function db_column_exists($table, $column) { + return (bool) db_fetch_object(db_query("SHOW COLUMNS FROM [{". db_escape_table($table) ."}] LIKE '". db_escape_table($column) ."'")); +} + +/** + * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to + * the SELECT list entry of the given query and the resulting query is returned. + * This function only applies the wrapper if a DISTINCT doesn't already exist in + * the query. + * + * @param $table Table containing the field to set as DISTINCT + * @param $field Field to set as DISTINCT + * @param $query Query to apply the wrapper to + * @return SQL query with the DISTINCT wrapper surrounding the given table.field. + */ +function db_distinct_field($table, $field, $query) { + $field_to_select = 'DISTINCT(['. $table .'].['. $field .'])'; + // (? 30) { + // Try to fetch mapping, if not exists, set it up. + $trim = variable_get('oracle_'. $match, NULL); + if (!$trim) { + // Fetch last counter, and +1 for next mapping. + $count = variable_get('_db_escape_quote', 0) + 1; + variable_set('_db_escape_quote', $count); + // Setup mapping and reverse mapping. + $trim = substr($match, 0, 30 - strlen($count)) . $count; + variable_set('oracle_'. $match, $trim); + variable_set('oracle_'. $trim, $match); + $match = $trim; + } + } + return DB_QUOTE_OPERATOR . $match . DB_QUOTE_OPERATOR; +} + +/** + * Return a portably concatenate strings. + * + * @param ... + * Variable number of string parameters. + * @return + * Portably concatenate strings. + */ +function db_concat() { + $args = func_get_args(); + return implode(DB_CONCAT_OPERATOR, $args); +} + +/** + * Returns a string that is the equivalent of MySQL IFNULL or Oracle NVL. + * + * @return + * If $expr1 is not NULL, returns $expr1; otherwise it returns $expr2. + */ +function db_if_null($expr1, $expr2) { + return " NVL($expr1, $expr2) "; +} + +/** + * Report database status. + */ +function db_status_report($phase) { + $t = get_t(); + + $version = db_version(); + + $form['oracle'] = array( + 'title' => $t('Oracle database'), + 'value' => $version, + ); + + if (version_compare($version, DRUPAL_MINIMUM_ORACLE) < 0) { + $form['oracle']['severity'] = REQUIREMENT_ERROR; + $form['oracle']['description'] = $t('Your Oracle Server is too old. Drupal requires at least Oracle %version.', array('%version' => DRUPAL_MINIMUM_ORACLE)); + } + + return $form; +} + +/** + * Returns the version of the database server currently in use. + * + * @return Database server version + */ +function db_version() { + $banner = db_result(db_query('SELECT BANNER FROM SYS.V_$VERSION')); + preg_match('/\s([0-9.]+)\s/', $banner, $version); + return array_pop($version); +} + +/** + * Insert a row of record into database. + * + * @param $table + * Table to insert. + * @param $values + * An array containing the insert values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_insert($table, $values) { + $fields = array(); + $placeholders = array(); + $args = array(); + $lob_fields = array(); + $lob_placeholders = array(); + $lob_args = array(); + foreach ($values as $value) { + $fields[] = $value['field']; + switch ($value['placeholder']) { + case '%b': + $placeholders[] = 'EMPTY_BLOB()'; + $lob_fields[] = $value['field']; + $lob_placeholders[] = $value['placeholder']; + $lob_args[] = $value['data']; + break; + case '%c': + $placeholders[] = 'EMPTY_CLOB()'; + $lob_fields[] = $value['field']; + $lob_placeholders[] = $value['placeholder']; + $lob_args[] = $value['data']; + break; + default: + $placeholders[] = $value['placeholder']; + $args[] = $value['data']; + } + } + + $query = "INSERT INTO [{". $table ."}] ([". implode('], [', $fields) ."]) VALUES (". implode(', ', $placeholders) .")"; + if (count($lob_fields)) { + $query .= " RETURNING [". implode('], [', $lob_fields) ."] INTO ". implode(', ', $lob_placeholders); + $args = array_merge($args, $lob_args); + } + return db_query($query, $args); +} + +/** + * Update a row of record in database. + * + * @param $table + * Table to update. + * @param $values + * An array containing the update values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_update($table, $values, $where_clause = NULL) { + global $active_db, $last_result, $queries; + + $where_args = func_get_args(); + $where_args = array_slice($where_args, 3); + if (isset($where_args[0]) and is_array($where_args[0])) { // 'All arguments in one array' syntax + $where_args = $where_args[0]; + } + + $fields = array(); + $args = array(); + $lob_fields = array(); + $lob_placeholders = array(); + $lob_args = array(); + foreach ($values as $value) { + switch ($value['placeholder']) { + case '%b': + $fields[] = '['. $value['field'] .'] = EMPTY_BLOB()'; + $lob_fields[] = $value['field']; + $lob_placeholders[] = $value['placeholder']; + $lob_args[] = $value['data']; + break; + case '%c': + $fields[] = '['. $value['field'] .'] = EMPTY_CLOB()'; + $lob_fields[] = $value['field']; + $lob_placeholders[] = $value['placeholder']; + $lob_args[] = $value['data']; + break; + default: + $fields[] = '['. $value['field'] .'] = '. $value['placeholder']; + $args[] = $value['data']; + } + } + + $query = "UPDATE [{". $table ."}] SET ". implode(', ', $fields); + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $args = array_merge($args, $where_args); + } + if (count($lob_fields)) { + $query .= " RETURNING [". implode('], [', $lob_fields) ."] INTO ". implode(', ', $lob_placeholders); + $args = array_merge($args, $lob_args); + } + return db_query($query, $args); +} + +/** + * Delete a row of record from database. + * + * @param $table + * Table to delete. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_delete($table, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 2); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $query['query'] = "DELETE FROM [{". $table ."}]"; + if ($where_clause) { + $query['query'] .= " WHERE ". $where_clause; + } + return db_query($query, $args); +} + +/** + * Returns the last insert id. This function is thread safe. + * + * @param $table + * The name of the table you inserted into. + * @param $field + * The name of the autoincrement field. + */ +function db_last_insert_id($table, $field) { + return db_result(db_query("SELECT [seq_{". $table ."}_" . $field ."].CURRVAL FROM DUAL")); +} + +/** + * Runs a limited-range query in the active database. + * + * Use this as a substitute for db_query() when a subset of the query + * is to be returned. + * User-supplied arguments to the query should be passed in as separate + * parameters so that they can be properly escaped to avoid SQL injection + * attacks. + * + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. Instead of a variable number of query arguments, + * you may also pass a single array containing the query arguments. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: use NULL as arguments substitution for %b and %c. This will be + * replaced as corresponding empty LOB value placeholder, based on the + * database specific representation. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $from + * The first result row to return. + * @param $count + * The maximum number of result rows to return. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_range($query) { + $args = func_get_args(); + $count = array_pop($args); + $from = array_pop($args); + array_shift($args); + + $query = 'SELECT * FROM (SELECT [sub1].*, ROWNUM AS [line2] FROM ('. $query .') [sub1]) WHERE [line2] BETWEEN '. ($from + 1) .' AND '. ($from + $count); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Runs a SELECT query and stores its results in a temporary table. + * + * Use this as a substitute for db_query() when the results need to stored + * in a temporary table. Temporary tables exist for the duration of the page + * request. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * + * Note that if you need to know how many results were returned, you should do + * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() do + * not give consistent result across different database types in this case. + * + * @param $query + * A string containing a normal SELECT SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. The query arguments can be enclosed in one + * array instead. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: use NULL as arguments substitution for %b and %c. This will be + * replaced as corresponding empty LOB value placeholder, based on the + * database specific representation. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $table + * The name of the temporary table to select into. This name will not be + * prefixed as there is no risk of collision. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_temporary($query) { + $args = func_get_args(); + $tablename = array_pop($args); + array_shift($args); + + $query = preg_replace('/^SELECT/i', 'CREATE GLOBAL TEMPORARY TABLE ['. $tablename .'] ON COMMIT PRESERVE ROWS AS SELECT', $query); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Lock a table. + * This function automatically starts a transaction. + */ +function db_lock_table($table) { + db_query('LOCK TABLE [{'. db_escape_table($table) .'}] IN EXCLUSIVE MODE'); +} + +/** + * Unlock all locked tables. + * This function automatically commits a transaction. + */ +function db_unlock_tables() { + db_query('COMMIT'); +} + +/** + * Check if a table exists. + */ +function db_table_exists($table) { + return db_result(db_query("SELECT COUNT(TABLE_NAME) FROM USER_TABLES WHERE TABLE_NAME LIKE '{". db_escape_table($table) ."}'")) ? TRUE : FALSE; +} + +/** + * Check if a column exists in the given table. + */ +function db_column_exists($table, $column) { + return db_result(db_query("SELECT COUNT(COLUMN_NAME) FROM USER_TAB_COLS WHERE TABLE_NAME LIKE '{". db_escape_table($table) ."}' AND COLUMN_NAME LIKE '". db_escape_table($column) ."'")) ? TRUE : FALSE; +} + +/** + * Check if constraint exists in the given table. + */ +function db_constraint_exists($table, $fields) { + $queries = array(); + foreach ($fields as $key => $value) { + $queries[] = "SELECT CONSTRAINT_NAME FROM USER_CONS_COLUMNS WHERE TABLE_NAME LIKE '{". db_escape_table($table) ."}' AND COLUMN_NAME LIKE '". db_escape_table($value) ."'"; + } + return db_result(db_query(implode(' INTERSECT ', $queries))) ? TRUE : FALSE; +} + +/** + * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to + * the SELECT list entry of the given query and the resulting query is returned. + * This function only applies the wrapper if a DISTINCT doesn't already exist in + * the query. + * + * @param $table Table containing the field to set as DISTINCT + * @param $field Field to set as DISTINCT + * @param $query Query to apply the wrapper to + * @return SQL query with the DISTINCT wrapper surrounding the given table.field. + */ +function db_distinct_field($table, $field, $query) { + $field_to_select = 'DISTINCT (['. $table .'].['. $field .'])'; + // (? $t('PostgreSQL database'), + 'value' => $version, + ); + + if (version_compare($version, DRUPAL_MINIMUM_POSTGRESQL) < 0) { + $form['postgresql']['severity'] = REQUIREMENT_ERROR; + $form['postgresql']['description'] = $t('Your PostgreSQL Server is too old. Drupal requires at least PostgreSQL %version.', array('%version' => DRUPAL_MINIMUM_POSTGRESQL)); + } + + return $form; +} + +/** + * Returns the version of the database server currently in use. + * + * @return Database server version + */ +function db_version() { + return db_result(db_query("SHOW SERVER_VERSION")); +} + +/** + * Insert a row of record into database. + * + * @param $table + * Table to insert. + * @param $values + * An array containing the insert values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_insert($table, $values) { + $fields = array(); + $placeholders = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = $value['field']; + $placeholders[] = $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "INSERT INTO [{". $table ."}] ([". implode('], [', $fields) ."]) VALUES (". implode(', ', $placeholders) .")"; + return db_query($query, $data); +} + +/** + * Update a row of record in database. + * + * @param $table + * Table to update. + * @param $values + * An array containing the update values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_update($table, $values, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 3); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $fields = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = '['. $value['field'] .'] = '. $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "UPDATE [{". $table ."}] SET ". implode(', ', $fields); + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = array_merge($data, $args); + } + return db_query($query, $data); +} + +/** + * Delete a row of record from database. + * + * @param $table + * Table to delete. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_delete($table, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 2); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $data = array(); + + $query = "DELETE FROM [{". $table ."}]"; + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = $args; + } + return db_query($query, $data); +} + +/** + * Returns the last insert id. This function is thread safe. + * + * @param $table + * The name of the table you inserted into. + * @param $field + * The name of the autoincrement field. + */ +function db_last_insert_id($table, $field) { + return db_result(db_query("SELECT CURRVAL('{". db_escape_table($table) ."}_". db_escape_table($field) ."_seq')")); +} + +/** + * Runs a limited-range query in the active database. + * + * Use this as a substitute for db_query() when a subset of the query + * is to be returned. + * User-supplied arguments to the query should be passed in as separate + * parameters so that they can be properly escaped to avoid SQL injection + * attacks. + * + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. Instead of a variable number of query arguments, + * you may also pass a single array containing the query arguments. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $from + * The first result row to return. + * @param $count + * The maximum number of result rows to return. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_range($query) { + $args = func_get_args(); + $count = array_pop($args); + $from = array_pop($args); + array_shift($args); + + $query .= ' LIMIT '. (int) $count .' OFFSET '. (int) $from; + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Runs a SELECT query and stores its results in a temporary table. + * + * Use this as a substitute for db_query() when the results need to stored + * in a temporary table. Temporary tables exist for the duration of the page + * request. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * + * Note that if you need to know how many results were returned, you should do + * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() does + * not give consistent result across different database types in this case. + * + * @param $query + * A string containing a normal SELECT SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. The query arguments can be enclosed in one + * array instead. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $table + * The name of the temporary table to select into. This name will not be + * prefixed as there is no risk of collision. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_temporary($query) { + $args = func_get_args(); + $tablename = array_pop($args); + array_shift($args); + + $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' AS SELECT', $query); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Lock a table. + * This function automatically starts a transaction. + */ +function db_lock_table($table) { + db_query('LOCK TABLE [{'. db_escape_table($table) .'}] IN EXCLUSIVE MODE'); +} + +/** + * Unlock all locked tables. + * This function automatically commits a transaction. + */ +function db_unlock_tables() { + db_query('COMMIT'); +} + +/** + * Check if a table exists. + */ +function db_table_exists($table) { + return (bool) db_result(db_query("SELECT COUNT(*) FROM [pg_class] WHERE [relname] = '{". db_escape_table($table) ."}'")); +} + +/** + * Check if a column exists in the given table. + */ +function db_column_exists($table, $column) { + return (bool) db_result(db_query("SELECT COUNT([pg_attribute].[attname]) FROM [pg_class], [pg_attribute] WHERE [pg_attribute].[attrelid] = [pg_class].[oid] AND [pg_class].[relname] = '{". db_escape_table($table) ."}' AND [attname] = '". db_escape_table($column) ."'")); +} + +/** + * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to + * the SELECT list entry of the given query and the resulting query is returned. + * This function only applies the wrapper if a DISTINCT doesn't already exist in + * the query. + * + * @param $table Table containing the field to set as DISTINCT + * @param $field Field to set as DISTINCT + * @param $query Query to apply the wrapper to + * @return SQL query with the DISTINCT wrapper surrounding the given table.field. + */ +function db_distinct_field($table, $field, $query) { + $field_to_select = 'DISTINCT ON (['. $table .'].['. $field ."]) [$table].[$field]"; + // (?PostgreSQL documentation.', array('%encoding' => $encoding, '@url' => 'http://www.postgresql.org/docs/7.4/interactive/multibyte.html')), 'status'); + } +} + +/** + * @} End of "ingroup database". + */ Index: drupal-6.x-siren-1.x/includes/common.sqlite.inc =================================================================== RCS file: drupal-6.x-siren-1.x/includes/common.sqlite.inc diff -N drupal-6.x-siren-1.x/includes/common.sqlite.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drupal-6.x-siren-1.x/includes/common.sqlite.inc 4 Feb 2008 03:15:17 -0000 @@ -0,0 +1,393 @@ + $t('SQLite database'), + 'value' => $version, + ); + + if (version_compare($version, DRUPAL_MINIMUM_SQLITE) < 0) { + $form['sqlite']['severity'] = REQUIREMENT_ERROR; + $form['sqlite']['description'] = $t('Your SQLite Server is too old. Drupal requires at least SQLite %version.', array('%version' => DRUPAL_MINIMUM_SQLITE)); + } + + return $form; +} + +/** + * Returns the version of the database server currently in use. + * + * @return Database server version + */ +function db_version() { + return db_result(db_query("SELECT SQLITE_VERSION()")); +} + +/** + * Insert a row of record into database. + * + * @param $table + * Table to insert. + * @param $values + * An array containing the insert values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_insert($table, $values) { + $fields = array(); + $placeholders = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = $value['field']; + $placeholders[] = $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "INSERT INTO [{". $table ."}] ([". implode('], [', $fields) ."]) VALUES (". implode(', ', $placeholders) .")"; + return db_query($query, $data); +} + +/** + * Update a row of record in database. + * + * @param $table + * Table to update. + * @param $values + * An array containing the update values. Each element of the array + * should be an associatie array with the following keys: + * - "field": The database field represented in the table column. + * - "placeholder": The placeholder of the table column, using printf() + * syntax. Valid %-modifiers are: %d, %f, %s and %b. + * - "data": The data to insert into the table column. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_update($table, $values, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 3); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $fields = array(); + $data = array(); + foreach ($values as $value) { + $fields[] = '['. $value['field'] .'] = '. $value['placeholder']; + $data[] = $value['data']; + } + + if (!count($fields)) { + return FALSE; + } + + $query = "UPDATE [{". $table ."}] SET ". implode(', ', $fields); + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = array_merge($data, $args); + } + return db_query($query, $data); +} + +/** + * Delete a row of record from database. + * + * @param $table + * Table to delete. + * @param $where_clause + * A string containing an update condition query (where clause). + * @param ... + * A variable number of arguments which are substituted into the query + * WHERE condition, using printf() syntax. Instead of a variable number + * of query arguments, you may also pass a single array containing the + * query arguments. + * + * Valid %-modifiers are: %d, %f and %s. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query_delete($table, $where_clause = NULL) { + $args = func_get_args(); + $args = array_slice($args, 2); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + + $data = array(); + + $query = "DELETE FROM [{". $table ."}]"; + if ($where_clause) { + $query .= " WHERE ". $where_clause; + $data = $args; + } + return db_query($query, $data); +} + +/** + * Returns the last insert id. This function is thread safe. + * + * @param $table + * The name of the table you inserted into. + * @param $field + * The name of the autoincrement field. + */ +function db_last_insert_id($table, $field) { + return db_result(db_query("SELECT LAST_INSERT_ROWID()")); +} + +/** + * Runs a limited-range query in the active database. + * + * Use this as a substitute for db_query() when a subset of the query + * is to be returned. + * User-supplied arguments to the query should be passed in as separate + * parameters so that they can be properly escaped to avoid SQL injection + * attacks. + * + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. Instead of a variable number of query arguments, + * you may also pass a single array containing the query arguments. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $from + * The first result row to return. + * @param $count + * The maximum number of result rows to return. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_range($query) { + $args = func_get_args(); + $count = array_pop($args); + $from = array_pop($args); + array_shift($args); + + $query .= ' LIMIT '. (int) $count .' OFFSET '. (int) $from; + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Runs a SELECT query and stores its results in a temporary table. + * + * Use this as a substitute for db_query() when the results need to stored + * in a temporary table. Temporary tables exist for the duration of the page + * request. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * + * Note that if you need to know how many results were returned, you should do + * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() does + * not give consistent result across different database types in this case. + * + * @param $query + * A string containing a normal SELECT SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. The query arguments can be enclosed in one + * array instead. + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $table + * The name of the temporary table to select into. This name will not be + * prefixed as there is no risk of collision. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_temporary($query) { + $args = func_get_args(); + $tablename = array_pop($args); + array_shift($args); + + $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' AS SELECT', $query); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + return db_query($query, $args); +} + +/** + * Lock a table. + * This function automatically starts a transaction. + */ +function db_lock_table($table) { + db_query('BEGIN'); +} + +/** + * Unlock all locked tables. + * This function automatically commits a transaction. + */ +function db_unlock_tables() { + db_query('COMMIT'); +} + +/** + * Check if a table exists. + */ +function db_table_exists($table) { + return (bool) db_result(db_query("SELECT COUNT(*) FROM SQLITE_MASTER WHERE TBL_NAME LIKE '{". db_escape_table($table) ."}'")); +} + +/** + * Check if a column exists in the given table. + */ +function db_column_exists($table, $column) { + $result = db_query("PRAGMA TABLE_INFO('{". db_escape_table($table) ."}')"); + while ($column = db_fetch_array($result)) { + if ($column['name'] == $column) { + return TRUE; + } + } + return FALSE; +} + +/** + * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to + * the SELECT list entry of the given query and the resulting query is returned. + * This function only applies the wrapper if a DISTINCT doesn't already exist in + * the query. + * + * @param $table Table containing the field to set as DISTINCT + * @param $field Field to set as DISTINCT + * @param $query Query to apply the wrapper to + * @return SQL query with the DISTINCT wrapper surrounding the given table.field. + */ +function db_distinct_field($table, $field, $query) { + $field_to_select = 'DISTINCT ON (['. $table .'].['. $field ."]) [$table].[$field]"; + // (?
");
+  print_r($msg);
+  print("
"); +} + +function _debug_query($query) { + //_print($query); + + if (preg_match('/[^\[\'{a-z0-9_:]([a-z0-9_{}]{3,})[^\]\'}a-z0-9_]/Ds', $query, $matches) && !preg_match('/[0-9]/', $matches[1])) { + _print("NO []: ". $query); + _print($matches); + } + if (preg_match("/'%s'/", $query)) { + _print("OLD '%s': ". $query); + } +} + +/** + * @ingroup database + * @{ + */ + +// Include functions shared between ibm_db2 and pdo_ibm. +require_once './includes/common.db2.inc'; + +// Include schema API shared between ibm_db2 and pdo_ibm. +require_once './includes/schema.db2.inc'; + +/** + * Initialize a database connection. + */ +function db_connect($url) { + + // Check if Oracle support is present in PHP + if (!(function_exists('db2_connect') && extension_loaded('ibm_db2'))) { + _db_error_page('Unable to use the DB2 database because the ibm_db2 extension for PHP is not installed. Check your php.ini to see how you can enable it.'); + } + + $url = parse_url($url); + $conn_string = ''; + + // Decode url-encoded information in the db connection string. + $conn_string .= 'PROTOCOL=TCPIP;'; + if (isset($url['user'])) { + $conn_string .= 'UID='. urldecode($url['user']) .';'; + } + if (isset($url['pass'])) { + $conn_string .= 'PWD='. urldecode($url['pass']) .';'; + } + if (isset($url['path'])) { + $conn_string .= 'DATABASE='. substr(urldecode($url['path']), 1) .';'; + } + if (isset($url['host'])) { + $conn_string .= 'HOSTNAME='. urldecode($url['host']) .';'; + } + if (isset($url['port'])) { + $conn_string .= 'PORT='. urldecode($url['port']) .';'; + } + else { + $conn_string .= 'PORT=50000;'; + } + + // Build db2 connection options array. + $conn_options = array( + // Turns autocommit on for this connection handle. + 'autocommit' => DB2_AUTOCOMMIT_ON, + // Specifies that column names are returned in natural case. + 'DB2_ATTR_CASE' => DB2_CASE_NATURAL, + // Specifies a forward-only cursor for a statement resource. + 'CURSOR' => DB2_FORWARD_ONLY + ); + + // Test connecting to the database. + $connection = @db2_connect($conn_string, '', '', $conn_options); + if (!$connection) { + $error = db2_conn_errormsg(); + _db_error_page($error); + } + + return $connection; +} + +/** + * Runs a basic query in the active database. + * + * User-supplied arguments to the query should be passed in as separate + * parameters so that they can be properly escaped to avoid SQL injection + * attacks. + * + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. Instead of a variable number of query arguments, + * you may also pass a single array containing the query arguments. + * + * Valid %-modifiers are: %s, %d, %f and %b (binary data, do not enclose + * in ''). + * + * NOTE: use NULL as arguments substitution for %b and %c. This will be + * replaced as corresponding empty LOB value placeholder, based on the + * database specific representation. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query($query) { + $args = func_get_args(); + array_shift($args); + _debug_query($query); + $query = db_prefix_tables($query); + $query = db_escape_quote($query); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + _db_query_callback(array('query' => $query, 'args' => $args), TRUE); + $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); + $args = _db_query_callback(NULL, TRUE); + return _db_query(array('query' => $query, 'args' => $args)); +} + +/** + * Helper function for db_query(). + */ +function _db_query($query, $debug = 0) { + global $active_db, $last_result, $queries; + + // Expand $query if it is in array format. + $args = array(); + if (is_array($query)) { + // We need hybrid handleing in case of ibm_db2: replace all + // interger/float/string as inline query arguments, but keep CLOB and + // BLOB as placeholder with "?". This is because replace string with + // placeholder "?" is not suitable for LOWER(). + foreach ($query['args'] as $arg) { + if (isset($arg['type']) && $arg['type'] == DB2_BINARY) { + $args[] = $arg['data']; + } + } + $query = $query['query']; + + // Check if arguments match number of placeholders, or else unset it. + $args = array_slice($args, 0, preg_match_all('/\?/', $query, $matches)); + } + + if (variable_get('dev_query', 0)) { + list($usec, $sec) = explode(' ', microtime()); + $timer = (float)$usec + (float)$sec; + // If devel.module query logging is enabled, prepend a comment with the username and calling function + // to the SQL string. This is useful when running mysql's SHOW PROCESSLIST to learn what exact + // code is issueing the slow query. + $bt = debug_backtrace(); + // t() may not be available yet so we don't wrap 'Anonymous' + $name = $user->uid ? $user->name : variable_get('anonymous', 'Anonymous'); + // str_replace() to prevent SQL injection via username or anonymous name. + $name = str_replace(array('*', '/'), '', $name); + $query = '/* '. $name .' : '. $bt[2]['function'] .' */ '. $query; + } + + // Perform actual query and return the result set. + $stmt = db2_prepare($active_db, $query); + if (!$stmt) { + // Indicate to drupal_error_handler that this is a database error. + ${DB_ERROR} = TRUE; + $error = db2_stmt_errormsg(); + trigger_error(check_plain($error ."\nquery: ". $query), E_USER_WARNING); + return FALSE; + } + + // Execute the statement + $result = db2_execute($stmt, $args); + if (!$result) { + // Indicate to drupal_error_handler that this is a database error. + ${DB_ERROR} = TRUE; + $error = db2_stmt_errormsg(); + trigger_error(check_plain($error ."\nquery: ". $query), E_USER_WARNING); + return FALSE; + } + + if (variable_get('dev_query', 0)) { + $bt = debug_backtrace(); + $query = $bt[2]['function'] ."\n". $query; + list($usec, $sec) = explode(' ', microtime()); + $stop = (float)$usec + (float)$sec; + $diff = $stop - $timer; + $queries[] = array($query, $diff); + } + + if ($debug) { + $error = db2_stmt_errormsg(); + print '

query: '. $query .'
error:'. $error .'

'; + } + + $last_result = $stmt; + return $last_result; +} + +/** + * Fetch one result row from the previous query as an object. + * + * @param $result + * A database query result resource, as returned from db_query(). + * @return + * An object representing the next row of the result, or FALSE. The attributes + * of this object are the table fields selected by the query. + */ +function db_fetch_object($result) { + if ($result) { + $object = db2_fetch_object($result); + return isset($object) ? $object : FALSE; + } +} + +/** + * Fetch one result row from the previous query as an array. + * + * @param $result + * A database query result resource, as returned from db_query(). + * @return + * An associative array representing the next row of the result, or FALSE. + * The keys of this object are the names of the table fields selected by the + * query, and the values are the field values for this result row. + */ +function db_fetch_array($result) { + if ($result) { + $array = db2_fetch_assoc($result); + return isset($array) ? $array : FALSE; + } +} + +/** + * Return an individual result field from the previous query. + * + * Only use this function if exactly one field is being selected; otherwise, + * use db_fetch_object() or db_fetch_array(). + * + * @param $result + * A database query result resource, as returned from db_query(). + * @return + * The resulting field or FALSE. + */ +function db_result($result) { + if ($result && $array = db2_fetch_array($result)) { + return $array[0]; + } + return FALSE; +} + +/** + * Determine whether the previous query caused an error. + */ +function db_error() { + $error = oci_error(); + return $error['message']; +} + +/** + * Determine the number of rows changed by the preceding query. + */ +function db_affected_rows() { + global $last_result; + if ($last_result) { + $count = db2_num_rows($last_result); + return $count <= 0 ? 0 : $count; + } + return 0; +} + +/* + * Prepare user input for use in a database query, preventing SQL injection attacks. + * + * @param $data + * Data to encode. Return with processed array pattern for variable binding. + * @return + * Locator for variable binding. + */ +function db_escape_decimal(&$data) { + return (int) $data; +} + +/** + * Prepare user input for use in a database query, preventing SQL injection attacks. + * + * @param $data + * Data to encode. Return with processed array pattern for variable binding. + * @return + * Locator for variable binding. + */ +function db_escape_float(&$data) { + return (float) $data; +} + +/** + * Prepare user input for use in a database query, preventing SQL injection attacks. + * + * @param $data + * Data to encode. Return with processed array pattern for variable binding. + * @return + * Locator for variable binding. + */ +function db_escape_string(&$data) { + // Trim first 4000 characters, since functions in the SYSFUN schema taking + // a VARCHAR as an argument will not accept VARCHARs greater than 4000 + // bytes long as an argument. + $data = preg_replace('/(.{0,4000})(.*)/', '\1', $data); + return "'". db2_escape_string($data) ."'"; +} + +/** + * Returns a properly formatted Binary Large OBject value. + * + * @param $data + * Data to encode. Return with processed array pattern for variable binding. + * @return + * Locator for variable binding. + */ +function db_encode_blob(&$data) { + $data = array( + 'data' => $data, + 'type' => DB2_BINARY, + ); + return "?"; +} + +/** + * Returns text from a Binary Large OBject value. + * + * @param $data + * Data to decode. + * @return + * Decoded data. + */ +function db_decode_blob($data) { + return $data; +} + +/** + * @} End of "ingroup database". + */ Index: drupal-6.x-siren-1.x/includes/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.inc,v retrieving revision 1.92 diff -u -p -r1.92 database.inc --- drupal-6.x-siren-1.x/includes/database.inc 8 Jan 2008 16:03:31 -0000 1.92 +++ drupal-6.x-siren-1.x/includes/database.inc 4 Feb 2008 03:15:17 -0000 @@ -139,14 +139,15 @@ function db_set_active($name = 'default' $connect_url = $db_url; } - $db_type = substr($connect_url, 0, strpos($connect_url, '://')); + $_connect_url = parse_url($connect_url); + $db_type = $_connect_url['fragment']; $handler = "./includes/database.$db_type.inc"; if (is_file($handler)) { include_once $handler; } else { - _db_error_page("The database type '". $db_type ."' is unsupported. Please use either 'mysql' or 'mysqli' for MySQL, or 'pgsql' for PostgreSQL databases."); + _db_error_page("The database type '". $db_type ."' is unsupported. Please use either 'mysql', 'mysqli' or 'pdo_mysql' for MySQL; 'pgsql' or 'pdo_pgsql' for PostgreSQL databases; 'oci8' or 'pdo_oci' for Oracle databases; 'ibm_db2' or 'pdo_ibm' for IBM DB2 databases; 'pdo_sqlite' for SQLite databases."); } $db_conns[$name] = db_connect($connect_url); @@ -199,23 +200,28 @@ function db_is_active() { * Helper function for db_query(). */ function _db_query_callback($match, $init = FALSE) { - static $args = NULL; + static $args = NULL, $ident = NULL, $count = 0; if ($init) { - $args = $match; - return; + if ($match) { + $count = 0; + $ident = substr(md5($match['query']), 1, 8); + $args = array_values($match['args']); + return; + } + return $args; } + $current = $count++; + $locator = ":l". $ident . $current; switch ($match[1]) { - case '%d': // We must use type casting to int to convert FALSE/NULL/(TRUE?) - return (int) array_shift($args); // We don't need db_escape_string as numbers are db-safe - case '%s': - return db_escape_string(array_shift($args)); - case '%%': - return '%'; + case '%d': + return db_escape_decimal($args[$current], $locator); case '%f': - return (float) array_shift($args); - case '%b': // binary data - return db_encode_blob(array_shift($args)); + return db_escape_float($args[$current], $locator); + case '%s': + return db_escape_string($args[$current], $locator); + case '%b': // Binary Large OBject. + return db_encode_blob($args[$current], $locator); } } @@ -238,7 +244,7 @@ function db_placeholders($arguments, $ty /** * Indicates the place holders that should be replaced in _db_query_callback(). */ -define('DB_QUERY_REGEXP', '/(%d|%s|%%|%f|%b)/'); +define('DB_QUERY_REGEXP', '/(%d|%f|%s|%b)/'); /** * Helper function for db_rewrite_sql. @@ -260,7 +266,7 @@ define('DB_QUERY_REGEXP', '/(%d|%s|%%|%f * @return * An array: join statements, where statements, field or DISTINCT(field). */ -function _db_rewrite_sql($query = '', $primary_table = 'n', $primary_field = 'nid', $args = array()) { +function _db_rewrite_sql($query = '', $primary_table = 'n', $primary_field = '[nid]', $args = array()) { $where = array(); $join = array(); $distinct = FALSE; @@ -307,7 +313,7 @@ function _db_rewrite_sql($query = '', $p * The original query with JOIN and WHERE statements inserted from * hook_db_rewrite_sql implementations. nid is rewritten if needed. */ -function db_rewrite_sql($query, $primary_table = 'n', $primary_field = 'nid', $args = array()) { +function db_rewrite_sql($query, $primary_table = 'n', $primary_field = '[nid]', $args = array()) { list($join, $where, $distinct) = _db_rewrite_sql($query, $primary_table, $primary_field, $args); if ($distinct) { @@ -540,15 +546,7 @@ function db_type_placeholder($type) { case 'char': case 'text': case 'datetime': - return '\'%s\''; - case 'numeric': - // For 'numeric' values, we use '%s', not '\'%s\'' as with - // string types, because numeric values should not be enclosed - // in quotes in queries (though they can be, at least on mysql - // and pgsql). Numerics should only have [0-9.+-] and - // presumably no db's "escape string" function will mess with - // those characters. return '%s'; case 'serial': Index: drupal-6.x-siren-1.x/includes/database.mysql-common.inc =================================================================== RCS file: drupal-6.x-siren-1.x/includes/database.mysql-common.inc diff -N drupal-6.x-siren-1.x/includes/database.mysql-common.inc --- drupal-6.x-siren-1.x/includes/database.mysql-common.inc 2 Oct 2007 16:15:56 -0000 1.13 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,532 +0,0 @@ - $field) { - $sql .= _db_create_field_sql($field_name, _db_process_field($field)) .", \n"; - } - - // Process keys & indexes. - $keys = _db_create_keys_sql($table); - if (count($keys)) { - $sql .= implode(", \n", $keys) .", \n"; - } - - // Remove the last comma and space. - $sql = substr($sql, 0, -3) ."\n) "; - - $sql .= $table['mysql_suffix']; - - return array($sql); -} - -function _db_create_keys_sql($spec) { - $keys = array(); - - if (!empty($spec['primary key'])) { - $keys[] = 'PRIMARY KEY ('. _db_create_key_sql($spec['primary key']) .')'; - } - if (!empty($spec['unique keys'])) { - foreach ($spec['unique keys'] as $key => $fields) { - $keys[] = 'UNIQUE KEY '. $key .' ('. _db_create_key_sql($fields) .')'; - } - } - if (!empty($spec['indexes'])) { - foreach ($spec['indexes'] as $index => $fields) { - $keys[] = 'INDEX '. $index .' ('. _db_create_key_sql($fields) .')'; - } - } - - return $keys; -} - -function _db_create_key_sql($fields) { - $ret = array(); - foreach ($fields as $field) { - if (is_array($field)) { - $ret[] = $field[0] .'('. $field[1] .')'; - } - else { - $ret[] = $field; - } - } - return implode(', ', $ret); -} - -/** - * Set database-engine specific properties for a field. - * - * @param $field - * A field description array, as specified in the schema documentation. - */ -function _db_process_field($field) { - - if (!isset($field['size'])) { - $field['size'] = 'normal'; - } - - // Set the correct database-engine specific datatype. - if (!isset($field['mysql_type'])) { - $map = db_type_map(); - $field['mysql_type'] = $map[$field['type'] .':'. $field['size']]; - } - - if ($field['type'] == 'serial') { - $field['auto_increment'] = TRUE; - } - - return $field; -} - -/** - * Create an SQL string for a field to be used in table creation or alteration. - * - * Before passing a field out of a schema definition into this function it has - * to be processed by _db_process_field(). - * - * @param $name - * Name of the field. - * @param $spec - * The field specification, as per the schema data structure format. - */ -function _db_create_field_sql($name, $spec) { - $sql = "`". $name ."` ". $spec['mysql_type']; - - if (isset($spec['length'])) { - $sql .= '('. $spec['length'] .')'; - } - elseif (isset($spec['precision']) && isset($spec['scale'])) { - $sql .= '('. $spec['scale'] .', '. $spec['precision'] .')'; - } - - if (!empty($spec['unsigned'])) { - $sql .= ' unsigned'; - } - - if (!empty($spec['not null'])) { - $sql .= ' NOT NULL'; - } - - if (!empty($spec['auto_increment'])) { - $sql .= ' auto_increment'; - } - - if (isset($spec['default'])) { - if (is_string($spec['default'])) { - $spec['default'] = "'". $spec['default'] ."'"; - } - $sql .= ' DEFAULT '. $spec['default']; - } - - if (empty($spec['not null']) && !isset($spec['default'])) { - $sql .= ' DEFAULT NULL'; - } - - return $sql; -} - -/** - * This maps a generic data type in combination with its data size - * to the engine-specific data type. - */ -function db_type_map() { - // Put :normal last so it gets preserved by array_flip. This makes - // it much easier for modules (such as schema.module) to map - // database types back into schema types. - $map = array( - 'varchar:normal' => 'VARCHAR', - - 'text:tiny' => 'SMALLTEXT', - 'text:small' => 'SMALLTEXT', - 'text:medium' => 'MEDIUMTEXT', - 'text:big' => 'LONGTEXT', - 'text:normal' => 'TEXT', - - 'serial:tiny' => 'TINYINT', - 'serial:small' => 'SMALLINT', - 'serial:medium' => 'MEDIUMINT', - 'serial:big' => 'BIGINT', - 'serial:normal' => 'INT', - - 'int:tiny' => 'TINYINT', - 'int:small' => 'SMALLINT', - 'int:medium' => 'MEDIUMINT', - 'int:big' => 'BIGINT', - 'int:normal' => 'INT', - - 'float:tiny' => 'FLOAT', - 'float:small' => 'FLOAT', - 'float:medium' => 'FLOAT', - 'float:big' => 'DOUBLE', - 'float:normal' => 'FLOAT', - - 'numeric:normal' => 'NUMERIC', - - 'blob:big' => 'LONGBLOB', - 'blob:normal' => 'BLOB', - - 'datetime:normal' => 'DATETIME', - ); - return $map; -} - -/** - * Rename a table. - * - * @param $ret - * Array to which query results will be added. - * @param $table - * The table to be renamed. - * @param $new_name - * The new name for the table. - */ -function db_rename_table(&$ret, $table, $new_name) { - $ret[] = update_sql('ALTER TABLE {'. $table .'} RENAME TO {'. $new_name .'}'); -} - -/** - * Drop a table. - * - * @param $ret - * Array to which query results will be added. - * @param $table - * The table to be dropped. - */ -function db_drop_table(&$ret, $table) { - $ret[] = update_sql('DROP TABLE {'. $table .'}'); -} - -/** - * Add a new field to a table. - * - * @param $ret - * Array to which query results will be added. - * @param $table - * Name of the table to be altered.