Index: includes/database/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/database.inc,v retrieving revision 1.33 diff -u -p -r1.33 database.inc --- includes/database/database.inc 8 Dec 2008 21:41:53 -0000 1.33 +++ includes/database/database.inc 10 Dec 2008 00:52:39 -0000 @@ -308,7 +308,7 @@ abstract class DatabaseConnection extend * * Queries sent to Drupal should wrap all table names in curly brackets. This * function searches for this syntax and adds Drupal's table prefix to all - * tables, allowing Drupal to coexist with other systems in the same database + * tables, allowing Drupal to coexist with other systems in the same database/schema * if necessary. * * @param $sql @@ -318,26 +318,45 @@ abstract class DatabaseConnection extend */ protected function prefixTables($sql) { global $db_prefix; + static $info; + $info = isset($info) ? $info : Database::getConnectionInfo(); - if (is_array($db_prefix)) { - if (array_key_exists('default', $db_prefix)) { - $tmp = $db_prefix; - unset($tmp['default']); - foreach ($tmp as $key => $val) { - $sql = strtr($sql, array('{' . $key . '}' => $val . $key)); + if (is_array($db_prefix) && array_key_exists('default', $db_prefix)) { + $prefix =& $db_prefix['default']; + } + elseif (is_array($db_prefix)) { + $prefix = ""; + } + else { + $prefix =& $db_prefix; + } + $bits = explode('.', $prefix); + if (count($bits) <= 1) { + // require schema and database info + $prefix = $info['default']['database'] . '.public.' . $prefix; + } + elseif (count($bits) == 2) { + // require database info + $prefix = $info['default']['database'] . '.' . $prefix; + } + if (!is_array($db_prefix)) return strtr($sql, array('{' . $prefix => $prefix, '{' => $prefix , '}' => '')); + + foreach ($db_prefix as $table => $pfx) { + if ($table == 'default') continue; + $bits = explode('.', $pfx); + if (count($bits) == 1) { + // require schema and database info + $sql = strtr($sql, array('{' . $table . '}' => $info['default']['database'] . '.public.' . $pfx . $table)); } - return strtr($sql, array('{' => $db_prefix['default'] , '}' => '')); - } - else { - foreach ($db_prefix as $key => $val) { - $sql = strtr($sql, array('{' . $key . '}' => $val . $key)); + elseif (count($bits) == 2) { + // require database info + $sql = strtr($sql, array('{' . $table . '}' => $info['default']['database'] . '.' . $pfx . $table)); + } + else { + $sql = strtr($sql, array('{' . $table . '}' => $pfx . $table)); } - return strtr($sql, array('{' => '' , '}' => '')); - } - } - else { - return strtr($sql, array('{' => $db_prefix , '}' => '')); } + return strtr($sql, array('{' => $prefix , '}' => '')); } /** @@ -353,7 +372,7 @@ abstract class DatabaseConnection extend * A PDO prepared statement ready for its execute() method. */ protected function prepareQuery($query) { - $query = self::prefixTables($query); + $query = $this->prefixTables($query); if (empty($this->preparedStatements[$query])) { // Call PDO::prepare. $this->preparedStatements[$query] = parent::prepare($query); Index: includes/database/schema.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/schema.inc,v retrieving revision 1.5 diff -u -p -r1.5 schema.inc --- includes/database/schema.inc 3 Dec 2008 16:32:21 -0000 1.5 +++ includes/database/schema.inc 10 Dec 2008 00:52:39 -0000 @@ -414,14 +414,34 @@ abstract class DatabaseSchema { * @return * Array, both the keys and the values are the matching tables. */ - public function findTables($table_expression) { - global $db_prefix; - $info = Database::getConnectionInfo(); - $result = db_query("SELECT table_name FROM information_schema.tables WHERE table_schema = :database AND table_name LIKE :table_name", array( - ':database' => $info['default']['database'], - ':table_name' => $table_expression, - )); - return $result->fetchAllKeyed(0, 0); + public function findTables($table) { + return (bool) db_result(db_query("SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = :schema AND table_catalog = :database AND table_name ILIKE :table", array( + ':schema' => $this->explodeTable($table)->schema,// will return 'public' in most cases + ':database' => $this->explodeTable($table)->database, + ':table' => $this->explodeTable($table)->table, + ))); + } + + /** + * breaks information about a table up into better peices + * + * @param table name to get specific infomation about + * + * @return + * object ( + * schema => //schema within database + * database => //database table exists in + * table => //table name including prefix + * ) + */ + protected function explodeTable($table) { + //initializing + list($database, $schema, $table) = explode('.', Database::getActiveConnection()->prefixTables('{' . $table . '}')); + return (object) array( + "schema" => $schema, + "database" => $database, + "table" => $table, + ); } } Index: includes/database/mysql/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/mysql/database.inc,v retrieving revision 1.11 diff -u -p -r1.11 database.inc --- includes/database/mysql/database.inc 8 Dec 2008 21:41:53 -0000 1.11 +++ includes/database/mysql/database.inc 10 Dec 2008 00:52:39 -0000 @@ -69,6 +69,42 @@ class DatabaseConnection_mysql extends D // (? $prefix, '{' => $prefix , '}' => '')); + + foreach ($db_prefix as $table => $pfx) { + if ($table == 'default') continue; + $bits = explode('.', $pfx); + if (count($bits) == 1) { + // require database info + $sql = strtr($sql, array('{' . $table . '}' => $info['default']['database'] . '.' . $pfx . $table)); + } + else { + $sql = strtr($sql, array('{' . $table . '}' => $pfx . $table)); + } + } + return strtr($sql, array('{' . $prefix => $prefix, '{' => $prefix , '}' => '')); + } + } Index: includes/database/mysql/schema.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/mysql/schema.inc,v retrieving revision 1.7 diff -u -p -r1.7 schema.inc --- includes/database/mysql/schema.inc 2 Dec 2008 19:45:01 -0000 1.7 +++ includes/database/mysql/schema.inc 10 Dec 2008 00:52:39 -0000 @@ -14,15 +14,29 @@ class DatabaseSchema_mysql extends DatabaseSchema { - public function tableExists($table) { - return (bool) $this->connection->query("SHOW TABLES LIKE '{" . $table . "}'", array(), array())->fetchField(); + public function findTables($table_expression) { + $result = db_query("SELECT table_name FROM information_schema.tables WHERE table_schema = :database AND table_name LIKE :table_name", array( + ':database' => $this->explodeTable($table_expression)->database, + ':table_name' => $this->explodeTable($table_expression)->table, + )); + return $result->fetchAllKeyed(0, 0); } + public function tableExists($table) { + return (bool) db_result(db_query("SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = :database AND table_name = :table", array( + ':database' => $this->explodeTable($table)->database, + ':table' => $this->explodeTable($table)->table, + ))); + } + public function columnExists($table, $column) { - return (bool) $this->connection->query("SHOW COLUMNS FROM {" . $this->connection->escapeTable($table) . "} LIKE '" . $this->connection->escapeTable($column) . "'", array(), array())->fetchField(); + return (bool) db_result(db_query("SELECT COUNT(column_name) FROM information_schema.columns WHERE table_schema = :database AND table_name = :table AND column_name = :column", array( + ':database' => $this->explodeTable($table)->database, + ':table' => $this->explodeTable($table)->table, + ':column' => $column, + ))); } - /** * Generate SQL to create a new table from a Drupal schema definition. * @@ -310,6 +324,15 @@ class DatabaseSchema_mysql extends Datab $ret[] = update_sql($sql); } + protected function explodeTable($table) { + //initializing + list($database, $table) = explode('.', Database::getActiveConnection()->prefixTables('{' . $table . '}')); + return (object) array( + "database" => $database, + "table" => $table, + ); + } + } /** Index: includes/database/pgsql/schema.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/pgsql/schema.inc,v retrieving revision 1.3 diff -u -p -r1.3 schema.inc --- includes/database/pgsql/schema.inc 26 Nov 2008 13:42:25 -0000 1.3 +++ includes/database/pgsql/schema.inc 10 Dec 2008 00:52:39 -0000 @@ -14,11 +14,20 @@ class DatabaseSchema_pgsql extends DatabaseSchema { public function tableExists($table) { - return (bool) db_result(db_query("SELECT COUNT(*) FROM pg_class WHERE relname = '{" . db_escape_table($table) . "}'")); - } + return (bool) db_result(db_query("SELECT COUNT(table_name) FROM information_schema.tables WHERE table_catalog = :database AND table_schema = :schema AND table_name = :table", array( + ':schema' => $this->explodeTable($table)->schema,// will return 'public' in most cases + ':database' => $this->explodeTable($table)->database, + ':table' => $this->explodeTable($table)->table, + ))); + } public function columnExists($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) . "'")); + return (bool) db_result(db_query("SELECT COUNT(column_name) FROM information_schema.columns WHERE table_schema = :schema AND table_catalog = :database AND table_name = :table AND column_name = :column", array( + ':schema' => $this->explodeTable($table)->schema,// will return 'public' in most cases + ':database' => $this->explodeTable($table)->database, + ':table' => $this->explodeTable($table)->table, + ':column' => $column, + ))); } /** @@ -43,7 +52,7 @@ class DatabaseSchema_pgsql extends Datab } if (isset($table['unique keys']) && is_array($table['unique keys'])) { foreach ($table['unique keys'] as $key_name => $key) { - $sql_keys[] = 'CONSTRAINT {' . $name . '}_' . $key_name . '_key UNIQUE (' . implode(', ', $key) . ')'; + $sql_keys[] = 'CONSTRAINT ' . $this->explodeTable($name)->table . '_' . $key_name . '_key UNIQUE (' . implode(', ', $key) . ')'; } } @@ -140,7 +149,7 @@ class DatabaseSchema_pgsql extends Datab // 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( + static $map = array( 'varchar:normal' => 'varchar', 'char:normal' => 'character', @@ -486,7 +495,7 @@ class DatabaseSchema_pgsql extends Datab } protected function _createIndexSql($table, $name, $fields) { - $query = 'CREATE INDEX {' . $table . '}_' . $name . '_idx ON {' . $table . '} ('; + $query = 'CREATE INDEX ' . $this->explodeTable($table)->table . '_' . $name . '_idx ON {' . $table . '} ('; $query .= $this->_createKeySql($fields) . ')'; return $query; } @@ -506,4 +515,23 @@ class DatabaseSchema_pgsql extends Datab } } } + + /** + * Find all tables that are like the specified base table name. + * + * @param $table_expression + * An SQL expression, for example "simpletest%" (without the quotes). + * BEWARE: this is not prefixed, the caller should take care of that. + * @return + * Array, both the keys and the values are the matching tables. + */ + public function findTables($table_expression) { + $result = db_query("SELECT table_name FROM information_schema.tables WHERE table_schema = :schema AND table_catalog = :database AND table_name ILIKE :table_name", array( + ':schema' => $this->explodeTable($table_expression)->schema, + ':database' => $this->explodeTable($table_expression)->database, + ':table_name' => $this->explodeTable($table_expression)->table, + )); + return $result->fetchAllKeyed(0, 0); + } + }