? profiles/simpletest ? sites/default/modules ? sites/default/settings.php Index: includes/database/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/database.inc,v retrieving revision 1.29 diff -u -p -r1.29 database.inc --- includes/database/database.inc 22 Nov 2008 13:51:38 -0000 1.29 +++ includes/database/database.inc 27 Nov 2008 15:15:47 -0000 @@ -401,20 +401,168 @@ abstract class DatabaseConnection extend } /** - * Create the appropriate sequence name for a given table and serial field. + * Return abbreviated representation of the table name, automatically + * generated by spliting the table name is its words and getting the + * first 4 characters of each word. * - * This information is exposed to all database drivers, although it is only - * useful on some of them. This method is table prefix-aware. + * For example, the table "glossary_entries_categories" will converted + * to the "glosentrcate" abbreviation. * * @param $table - * The table name to use for the sequence. - * @param $field - * The field name to use for the sequence. - * @return - * A table prefix-parsed string for the sequence name. + * The table name to be abbreviate. + * @param $characters + * Number of characters use for each word. Default is 4. + * @return + * An abbreviated representation of the table name. + */ + public function abbreviateTableName($table, $characters = 4) { + // Breakdown table name into words. + $words = explode('_', $table); + + $return = ''; + foreach ($words as $word) { + $return .= substr($word, 0, $characters); + } + + return $return; + } + + /** + * Return abbreviated representation of the columns used by the object + * (index, key, sequence) generated by the concatenation of the first 3 + * characters of each field. + * + * For example, one index over the "name, level, context" fields be + * converted to the "namlevcon" abbreviation. + * + * @param $fields + * The array of columns name to be abbreviate. + * @param $characters + * Number of characters use for each word. Default is 3. + * @return + * An abbreviated representation of the columns used by the object. + */ + public function abbreviateColumnsName($fields, $characters = 3) { + // Standardize $fields to an array. + if (is_string($fields)) { + $fields = array($fields); + } + + // Remove '_' if exists. + $words = array(); + foreach ($fields as $field) { + // Special case: field in array format for SUBSTR handling. + if (is_array($field)) { + $words[] = strtr($field[0], '_', ''); + } + else { + $words[] = strtr($field, '_', ''); + } + } + + $return = ''; + sort($words); + foreach ($words as $word) { + $return .= substr($word, 0, $characters); + } + + return $return; + } + + /** + * Return an abbreviated string as constraint name. + * + * @param $table + * The table name to be abbreviate. + * @param $fields + * The array of columns name to be abbreviate. + * @param $type + * The object type of target constraint, for example: + * - pk: For Primary Keys. + * - uk: For Unique Keys. + * - fk: For Foreign Keys. + * - ck: For Check Constraints. + * - ix: For Indexes. + * - uix: For Unique Indexes. + * - seq: For Sequences. + * - trg: For Triggers. + * @param $characters + * Number of characters use for the constraint name. Default is 30. + * @return + * An abbreviated string as constraint name. + */ + public function makeConstraintName($table, $fields, $type, $characters = 30) { + $words['tablename'] = $this->prefixTables('{' . $this->abbreviateTableName($table) . '}'); + $words['columnames'] = $this->abbreviateColumnsName($fields); + $words['object_type'] = $type; + + // If any of the calculated names excess the infamous 30cc. the name will + // be reduced by removing characters from the "columnames_abbreviated" + // part until if fits completely. + $return = implode('_', $words); + $length = strlen($return); + if ($length > $characters) { + $words['columnames'] = substr($words['columnames'], 0, -($length - $characters)); + $return = implode('_', $words); + } + + return $return; + } + + /** + * Helper function of makeConstraintName + */ + public function makePrimaryKeyName($table, $fields) { + return $this->makeConstraintName($table, $fields, 'pk'); + } + + /** + * Helper function of makeConstraintName + */ + public function makeUniqueKeyName($table, $fields) { + return $this->makeConstraintName($table, $fields, 'uk'); + } + + /** + * Helper function of makeConstraintName + */ + public function makeForeignKeyName($table, $fields) { + return $this->makeConstraintName($table, $fields, 'fk'); + } + + /** + * Helper function of makeConstraintName + */ + public function makeCheckConstraintName($table, $fields) { + return $this->makeConstraintName($table, $fields, 'ck'); + } + + /** + * Helper function of makeConstraintName + */ + public function makeIndexName($table, $fields) { + return $this->makeConstraintName($table, $fields, 'ix'); + } + + /** + * Helper function of makeConstraintName + */ + public function makeUniqueIndexName($table, $fields) { + return $this->makeConstraintName($table, $fields, 'uix'); + } + + /** + * Helper function of makeConstraintName */ public function makeSequenceName($table, $field) { - return $this->prefixTables('{'. $table .'}_'. $field .'_seq'); + return $this->makeConstraintName($table, $field, 'seq'); + } + + /** + * Helper function of makeConstraintName + */ + public function makeTriggerName($table, $field) { + return $this->makeConstraintName($table, $field, 'trg'); } /** @@ -2033,9 +2181,11 @@ function db_add_primary_key(&$ret, $tabl * Array to which query results will be added. * @param $table * The table to be altered. + * @param $fields + * Fields for the primary key. */ -function db_drop_primary_key(&$ret, $table) { - return Database::getActiveConnection()->schema()->dropPrimaryKey($ret, $table); +function db_drop_primary_key(&$ret, $table, $fields) { + return Database::getActiveConnection()->schema()->dropPrimaryKey($ret, $table, $fields); } /** @@ -2045,13 +2195,11 @@ function db_drop_primary_key(&$ret, $tab * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the key. * @param $fields - * An array of field names. + * Fields for the unique key. */ -function db_add_unique_key(&$ret, $table, $name, $fields) { - return Database::getActiveConnection()->schema()->addUniqueKey($ret, $table, $name, $fields); +function db_add_unique_key(&$ret, $table, $fields) { + return Database::getActiveConnection()->schema()->addUniqueKey($ret, $table, $fields); } /** @@ -2061,11 +2209,11 @@ function db_add_unique_key(&$ret, $table * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the key. + * @param $fields + * Fields for the unique key. */ -function db_drop_unique_key(&$ret, $table, $name) { - return Database::getActiveConnection()->schema()->dropUniqueKey($ret, $table, $name); +function db_drop_unique_key(&$ret, $table, $fields) { + return Database::getActiveConnection()->schema()->dropUniqueKey($ret, $table, $fields); } /** @@ -2075,13 +2223,11 @@ function db_drop_unique_key(&$ret, $tabl * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the index. * @param $fields - * An array of field names. + * Fields for the index. */ -function db_add_index(&$ret, $table, $name, $fields) { - return Database::getActiveConnection()->schema()->addIndex($ret, $table, $name, $fields); +function db_add_index(&$ret, $table, $fields) { + return Database::getActiveConnection()->schema()->addIndex($ret, $table, $fields); } /** @@ -2091,11 +2237,11 @@ function db_add_index(&$ret, $table, $na * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the index. + * @param $fields + * Fields for the index. */ -function db_drop_index(&$ret, $table, $name) { - return Database::getActiveConnection()->schema()->dropIndex($ret, $table, $name); +function db_drop_index(&$ret, $table, $fields) { + return Database::getActiveConnection()->schema()->dropIndex($ret, $table, $fields); } /** Index: includes/database/schema.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/schema.inc,v retrieving revision 1.4 diff -u -p -r1.4 schema.inc --- includes/database/schema.inc 31 Oct 2008 15:46:16 -0000 1.4 +++ includes/database/schema.inc 27 Nov 2008 15:15:47 -0000 @@ -244,8 +244,10 @@ abstract class DatabaseSchema { * Array to which query results will be added. * @param $table * The table to be altered. + * @param $fields + * Fields for the primary key. */ - abstract public function dropPrimaryKey(&$ret, $table); + abstract public function dropPrimaryKey(&$ret, $table, $fields); /** * Add a unique key. @@ -254,12 +256,10 @@ abstract class DatabaseSchema { * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the key. * @param $fields * An array of field names. */ - abstract public function addUniqueKey(&$ret, $table, $name, $fields); + abstract public function addUniqueKey(&$ret, $table, $fields); /** * Drop a unique key. @@ -268,10 +268,10 @@ abstract class DatabaseSchema { * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the key. + * @param $fields + * An array of field names. */ - abstract public function dropUniqueKey(&$ret, $table, $name); + abstract public function dropUniqueKey(&$ret, $table, $fields); /** * Add an index. @@ -280,12 +280,10 @@ abstract class DatabaseSchema { * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the index. * @param $fields * An array of field names. */ - abstract public function addIndex(&$ret, $table, $name, $fields); + abstract public function addIndex(&$ret, $table, $fields); /** * Drop an index. @@ -294,10 +292,10 @@ abstract class DatabaseSchema { * Array to which query results will be added. * @param $table * The table to be altered. - * @param $name - * The name of the index. + * @param $fields + * An array of field names. */ - abstract public function dropIndex(&$ret, $table, $name); + abstract public function dropIndex(&$ret, $table, $fields); /** Index: includes/database/mysql/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/mysql/database.inc,v retrieving revision 1.7 diff -u -p -r1.7 database.inc --- includes/database/mysql/database.inc 13 Nov 2008 21:02:09 -0000 1.7 +++ includes/database/mysql/database.inc 27 Nov 2008 15:15:47 -0000 @@ -39,6 +39,11 @@ class DatabaseConnection_mysql extends D $this->exec('SET sql_mode=STRICT_ALL_TABLES'); } + // For MySQL, the PRIMARY KEY must be named (or is named by default) "primary". + public function makePrimaryKeyName($table, $field) { + return "primary"; + } + public function queryRange($query, Array $args, $from, $count, Array $options = array()) { return $this->query($query . ' LIMIT ' . $from . ', ' . $count, $args, $options); } Index: includes/database/mysql/schema.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/mysql/schema.inc,v retrieving revision 1.6 diff -u -p -r1.6 schema.inc --- includes/database/mysql/schema.inc 13 Nov 2008 20:52:13 -0000 1.6 +++ includes/database/mysql/schema.inc 27 Nov 2008 15:15:47 -0000 @@ -6,7 +6,6 @@ * Database schema code for MySQL database servers. */ - /** * @ingroup schemaapi * @{ @@ -22,7 +21,6 @@ class DatabaseSchema_mysql extends Datab return (bool) $this->connection->query("SHOW COLUMNS FROM {" . $this->connection->escapeTable($table) . "} LIKE '" . $this->connection->escapeTable($column) . "'", array(), array())->fetchField(); } - /** * Generate SQL to create a new table from a Drupal schema definition. * @@ -46,7 +44,7 @@ class DatabaseSchema_mysql extends Datab } // Process keys & indexes. - $keys = $this->createKeysSql($table); + $keys = $this->createKeysSql($name, $table); if (count($keys)) { $sql .= implode(", \n", $keys) . ", \n"; } @@ -177,10 +175,7 @@ class DatabaseSchema_mysql extends Datab return $map; } - - - - protected function createKeysSql($spec) { + protected function createKeysSql($table, $spec) { $keys = array(); if (!empty($spec['primary key'])) { @@ -188,12 +183,12 @@ class DatabaseSchema_mysql extends Datab } if (!empty($spec['unique keys'])) { foreach ($spec['unique keys'] as $key => $fields) { - $keys[] = 'UNIQUE KEY ' . $key .' ('. $this->createKeysSqlHelper($fields) . ')'; + $keys[] = 'UNIQUE KEY ' . $this->connection->makeUniqueKeyName($table, $fields) .' ('. $this->createKeysSqlHelper($fields) . ')'; } } if (!empty($spec['indexes'])) { foreach ($spec['indexes'] as $index => $fields) { - $keys[] = 'INDEX ' . $index . ' (' . $this->createKeysSqlHelper($fields) . ')'; + $keys[] = 'INDEX ' . $this->connection->makeIndexName($table, $fields) . ' (' . $this->createKeysSqlHelper($fields) . ')'; } } @@ -243,7 +238,7 @@ class DatabaseSchema_mysql extends Datab $query = 'ALTER TABLE {' . $table . '} ADD '; $query .= $this->createFieldSql($field, $this->processField($spec)); if (count($keys_new)) { - $query .= ', ADD ' . implode(', ADD ', $this->createKeysSql($keys_new)); + $query .= ', ADD ' . implode(', ADD ', $this->createKeysSql($table, $keys_new)); } $ret[] = update_sql($query); if (isset($spec['initial'])) { @@ -281,35 +276,34 @@ class DatabaseSchema_mysql extends Datab $ret[] = update_sql('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')'); } - public function dropPrimaryKey(&$ret, $table) { + public function dropPrimaryKey(&$ret, $table, $fields) { $ret[] = update_sql('ALTER TABLE {' . $table . '} DROP PRIMARY KEY'); } - public function addUniqueKey(&$ret, $table, $name, $fields) { - $ret[] = update_sql('ALTER TABLE {' . $table . '} ADD UNIQUE KEY ' . $name . ' (' . $this->createKeySql($fields) . ')'); + public function addUniqueKey(&$ret, $table, $fields) { + $ret[] = update_sql('ALTER TABLE {' . $table . '} ADD UNIQUE KEY ' . $this->connection->makeUniqueKeyName($table, $fields) . ' (' . $this->createKeySql($fields) . ')'); } - public function dropUniqueKey(&$ret, $table, $name) { - $ret[] = update_sql('ALTER TABLE {' . $table . '} DROP KEY ' . $name); + public function dropUniqueKey(&$ret, $table, $fields) { + $ret[] = update_sql('ALTER TABLE {' . $table . '} DROP KEY ' . $this->connection->makeUniqueKeyName($table, $fields)); } - public function addIndex(&$ret, $table, $name, $fields) { - $query = 'ALTER TABLE {' . $table . '} ADD INDEX ' . $name . ' (' . $this->createKeySql($fields) . ')'; + public function addIndex(&$ret, $table, $fields) { + $query = 'ALTER TABLE {' . $table . '} ADD INDEX ' . $this->connection->makeIndexName($table, $fields) . ' (' . $this->createKeySql($fields) . ')'; $ret[] = update_sql($query); } - public function dropIndex(&$ret, $table, $name) { - $ret[] = update_sql('ALTER TABLE {' . $table . '} DROP INDEX ' . $name); + public function dropIndex(&$ret, $table, $fields) { + $ret[] = update_sql('ALTER TABLE {' . $table . '} DROP INDEX ' . $this->connection->makeIndexName($table, $fields)); } public function changeField(&$ret, $table, $field, $field_new, $spec, $keys_new = array()) { $sql = 'ALTER TABLE {' . $table . '} CHANGE `' . $field . '` ' . $this->createFieldSql($field_new, $this->processField($spec)); if (count($keys_new)) { - $sql .= ', ADD ' . implode(', ADD ', $this->createKeysSql($keys_new)); + $sql .= ', ADD ' . implode(', ADD ', $this->createKeysSql($table, $keys_new)); } $ret[] = update_sql($sql); } - } /** Index: includes/database/pgsql/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database/pgsql/database.inc,v retrieving revision 1.9 diff -u -p -r1.9 database.inc --- includes/database/pgsql/database.inc 13 Nov 2008 21:02:10 -0000 1.9 +++ includes/database/pgsql/database.inc 27 Nov 2008 15:15:47 -0000 @@ -33,6 +33,12 @@ class DatabaseConnection_pgsql extends D )); } + // For PostgreSQL, the SERIAL keyword generates one sequence with a + // different name schema as tablename_colname_seq. + public function makeSequenceName($table, $field) { + return $this->prefixTables('{'. $table .'}_'. $field .'_seq'); + } + public function query($query, Array $args = array(), $options = array()) { $options += $this->defaultOptions();