=== modified file 'includes/actions.inc' --- includes/actions.inc 2008-12-20 05:20:20 +0000 +++ includes/actions.inc 2009-01-17 11:12:50 +0000 @@ -325,7 +325,7 @@ function actions_save($function, $type, // aid is the callback for singleton actions so we need to keep a separate // table for numeric aids. if (!$aid) { - $aid = db_insert('actions_aid')->useDefaults(array('aid'))->execute(); + $aid = db_next_id('actions'); } db_merge('actions') === modified file 'includes/database/database.inc' --- includes/database/database.inc 2009-01-14 21:16:19 +0000 +++ includes/database/database.inc 2009-01-17 11:15:37 +0000 @@ -1017,6 +1017,26 @@ abstract class DatabaseConnection extend public function commit() { throw new ExplicitTransactionsNotSupportedException(); } + + /** + * Retrieves an unique id from a given sequence. + * + * Use this function if for some reason you can't use a serial field, + * normally a serial field with db_last_insert_id is preferred. + * + * @param $sequence + * The name of the sequence. + * @return + * An integer number larger than any number returned by earlier calls + * to this function with the same sequence argument. + */ + public function nextId($sequence) { + // In the degenerate case every id comes from a single source. + return Database::getActiveConnection() + ->insert('sequences') + ->useDefaults(array('sid')) + ->execute(); + } } /** @@ -2027,6 +2047,22 @@ function db_driver() { } /** + * Retrieves an unique id from a given sequence. Use db_last_insert_id is preferred. + * + * Use this function if for some reason you can't use a serial field, + * normally a serial field with db_last_insert_id is preferred. + * + * @param $sequence + * The name of the sequence. + * @return + * An integer number larger than any number returned before for this + * sequence. + */ +function db_next_id($sequence) { + return Database::getActiveConnection()->nextId($sequence); +} + +/** * @} End of "defgroup database". */ === modified file 'modules/simpletest/simpletest.install' --- modules/simpletest/simpletest.install 2008-11-15 13:01:04 +0000 +++ modules/simpletest/simpletest.install 2009-01-17 11:12:50 +0000 @@ -197,17 +197,5 @@ function simpletest_schema() { 'reporter' => array('test_class', 'message_id'), ), ); - $schema['simpletest_test_id'] = array( - 'description' => 'Stores simpletest test IDs, used to auto-incrament the test ID so that a fresh test ID is used.', - 'fields' => array( - 'test_id' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique simpletest ID used to group test results together. Each time a set of tests - are run a new test ID is used.', - ), - ), - 'primary key' => array('test_id'), - ); return $schema; } === modified file 'modules/simpletest/simpletest.module' --- modules/simpletest/simpletest.module 2009-01-12 06:23:57 +0000 +++ modules/simpletest/simpletest.module 2009-01-17 11:12:50 +0000 @@ -125,7 +125,6 @@ function simpletest_test_form() { // Clear test results. if (variable_get('simpletest_clear_results', TRUE)) { db_query('DELETE FROM {simpletest} WHERE test_id = %d', $_SESSION['test_id']); - db_query('DELETE FROM {simpletest_test_id} WHERE test_id = %d', $_SESSION['test_id']); } unset($_SESSION['test_id']); @@ -353,7 +352,7 @@ function simpletest_test_form_submit($fo */ function simpletest_run_tests($test_list, $reporter = 'drupal') { cache_clear_all(); - $test_id = db_insert('simpletest_test_id')->useDefaults(array('test_id'))->execute(); + $test_id = db_next_id('simpletest'); // Get the info for the first test being run. $first_test = array_shift($test_list); @@ -526,8 +525,7 @@ function simpletest_clean_database() { $schema = drupal_get_schema_unprocessed('simpletest'); $ret = array(); foreach (array_diff_key($tables, $schema) as $table) { - // Strip the prefix and skip tables without digits following "simpletest", - // e.g. {simpletest_test_id}. + // Strip the prefix and skip tables without digits following "simpletest". if (preg_match('/simpletest\d+.*/', $table, $matches)) { db_drop_table($ret, $matches[0]); } @@ -589,12 +587,9 @@ function simpletest_clean_temporary_dire */ function simpletest_clean_results_table() { if (variable_get('simpletest_clear_results', TRUE)) { - $count = db_result(db_query('SELECT COUNT(test_id) FROM {simpletest_test_id}')); - // Clear test results. db_query('DELETE FROM {simpletest}'); - db_query('DELETE FROM {simpletest_test_id}'); - drupal_set_message(t('Removed @count test results.', array('@count' => $count))); + drupal_set_message(t('Removed @count test results.', array('@count' => db_affected_rows()))); } } === modified file 'modules/simpletest/tests/database_test.test' --- modules/simpletest/tests/database_test.test 2009-01-11 10:57:20 +0000 +++ modules/simpletest/tests/database_test.test 2009-01-17 11:19:48 +0000 @@ -2357,3 +2357,25 @@ class DatabaseTransactionTestCase extend } } } + +/** + * Check the sequences API. + */ +class DatabaseNextIdCase extends DatabaseTestCase { + function getInfo() { + return array( + 'name' => t('Sequences API'), + 'description' => t('Test the secondary sequences API.'), + 'group' => t('Database'), + ); + } + + /** + * Test that the sequences API work. + */ + function testDbNextId() { + $first = db_next_id('test'); + $second = db_next_id('test'); + $this->assertTrue($first < $second, t('The second call from a sequence provides a larger number')); + } +} === modified file 'modules/system/system.install' --- modules/system/system.install 2009-01-14 21:13:41 +0000 +++ modules/system/system.install 2009-01-17 11:20:45 +0000 @@ -293,7 +293,7 @@ function system_install() { if (db_driver() == 'pgsql') { // We create some functions using global names instead of prefixing them // like we do with table names. If this function is ever called again (for - // example, by the test framework when creating prefixed test databases), + // example, by the test framework when creating prefixed test databases), // the global names will already exist. We therefore avoid trying to create // them again in that case. @@ -476,19 +476,6 @@ function system_schema() { 'primary key' => array('aid'), ); - $schema['actions_aid'] = array( - 'description' => 'Stores action IDs for non-default actions.', - 'fields' => array( - 'aid' => array( - 'description' => 'Primary Key: Unique actions ID.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - ), - 'primary key' => array('aid'), - ); - $schema['batch'] = array( 'description' => 'Stores details about batches (processes that run in multiple HTTP requests).', 'fields' => array( @@ -1113,6 +1100,19 @@ function system_schema() { 'primary key' => array('filename'), ); + $schema['sequences'] = array( + 'description' => 'Stores IDs.', + 'fields' => array( + 'sid' => array( + 'description' => 'Primary Key: Unique ID.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + ), + 'primary key' => array('sid'), + ); + $schema['sessions'] = array( 'description' => "Drupal's session handlers read and write into the sessions table. Each record represents a user session, either anonymous or authenticated.", 'fields' => array( @@ -3140,11 +3140,11 @@ function system_update_7016() { $ret = array(); // Only run these queries if the driver used is pgsql. if (db_driver() == 'pgsql') { - $result = db_query("SELECT c.relname AS table, a.attname AS field, - pg_catalog.format_type(a.atttypid, a.atttypmod) AS type - FROM pg_catalog.pg_attribute a - LEFT JOIN pg_class c ON (c.oid = a.attrelid) - WHERE pg_catalog.pg_table_is_visible(c.oid) AND c.relkind = 'r' + $result = db_query("SELECT c.relname AS table, a.attname AS field, + pg_catalog.format_type(a.atttypid, a.atttypmod) AS type + FROM pg_catalog.pg_attribute a + LEFT JOIN pg_class c ON (c.oid = a.attrelid) + WHERE pg_catalog.pg_table_is_visible(c.oid) AND c.relkind = 'r' AND pg_catalog.format_type(a.atttypid, a.atttypmod) LIKE '%unsigned%'"); while ($row = db_fetch_object($result)) { switch ($row->type) { @@ -3157,7 +3157,7 @@ function system_update_7016() { $datatype = 'bigint'; break; } - $ret[] = update_sql('ALTER TABLE ' . $row->table . ' ALTER COLUMN ' . $row->field . ' TYPE ' . $datatype); + $ret[] = update_sql('ALTER TABLE ' . $row->table . ' ALTER COLUMN ' . $row->field . ' TYPE ' . $datatype); $ret[] = update_sql('ALTER TABLE ' . $row->table . ' ADD CHECK (' . $row->field . ' >= 0)'); } $ret[] = update_sql('DROP DOMAIN smallint_unsigned'); @@ -3197,6 +3197,16 @@ function system_update_7017() { } /** + * Reuse the actions_aid table as sequences. + */ +function system_update_7018() { + $ret = array(); + db_drop_primary_key($ret, 'actions_aid'); + db_change_field($ret, 'actions_aid', 'aid', 'sid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('sid'))); + db_rename_table($ret, 'actions_aid', 'sequences'); +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */ === modified file 'scripts/run-tests.sh' --- scripts/run-tests.sh 2009-01-13 22:39:11 +0000 +++ scripts/run-tests.sh 2009-01-17 11:24:45 +0000 @@ -72,7 +72,7 @@ if (!ini_get('safe_mode')) { simpletest_script_reporter_init(); // Setup database for test results. -$test_id = db_insert('simpletest_test_id')->useDefaults(array('test_id'))->execute(); +$test_id = db_next_id('simpletest'); // Execute tests. simpletest_script_command($args['concurrency'], $test_id, implode(",", $test_list));