Index: lib/ddl/mssql_sql_generator.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/ddl/mssql_sql_generator.php,v retrieving revision 1.10 diff -u -r1.10 mssql_sql_generator.php --- lib/ddl/mssql_sql_generator.php 21 Nov 2008 21:40:51 -0000 1.10 +++ lib/ddl/mssql_sql_generator.php 28 Apr 2009 07:26:12 -0000 @@ -84,11 +84,7 @@ * @throws dml_exception if error */ public function reset_sequence($table) { - if (is_string($table)) { - $tablename = $table; - } else { - $tablename = $table->getName(); - } + $tablename = $this->object_name($table); // From http://msdn.microsoft.com/en-us/library/ms176057.aspx $value = (int)$this->mdb->get_field_sql('SELECT MAX(id) FROM {'.$tablename.'}'); if ($value == 0) { @@ -97,6 +93,30 @@ return $this->mdb->change_database_structure("DBCC CHECKIDENT ('$this->prefix$tablename', RESEED, $value)"); } + /** + * Temporarily disables the ID sequence. Useful for bulk manipulations in + * upgrade.php scripts. Should not be used in normal code. It is ESSENTIAL + * that your code calls enable_id_sequence before it finishes. + * @param string $table name of table + * @return success + */ + public function disable_id_sequence($table) { + $tablename = $this->object_name($table); + return $this->mdb->change_database_structure("SET IDENTITY_INSERT $this->prefix$tablename OFF"); + } + + /** + * Re-enables the ID sequence. Must be used after disable_id_sequence. + * @param string $table name of table + * @return success + */ + public function enable_id_sequence($table) { + $tablename = $this->object_name($table); + // Make sure we attempt both operations, even if one fails. + $result1 = $this->mdb->change_database_structure("SET IDENTITY_INSERT $this->prefix$tablename ON"); + $result2 = parent::enable_id_sequence($tablename); + return $result1 && $result2; + } /** * Given one correct xmldb_table, returns the SQL statements Index: lib/ddl/database_manager.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/ddl/database_manager.php,v retrieving revision 1.22 diff -u -r1.22 database_manager.php --- lib/ddl/database_manager.php 27 Apr 2009 20:29:02 -0000 1.22 +++ lib/ddl/database_manager.php 28 Apr 2009 07:26:10 -0000 @@ -106,19 +106,30 @@ * @return success */ public function reset_sequence($table) { - /// Calculate the name of the table - if (is_string($table)) { - $tablename = $table; - } else { - $tablename = $table->getName(); - } + $this->check_table_exists($table); + return $this->generator->reset_sequence($table); + } - /// Check the table exists - if (!$this->table_exists($table)) { - throw new ddl_table_missing_exception($tablename); - } + /** + * Temporarily disables the ID sequence. Useful for bulk manipulations in + * upgrade.php scripts. Should not be used in normal code. It is ESSENTIAL + * that your code calls enable_id_sequence before it finishes. + * @param string $table name of table + * @return success + */ + public function disable_id_sequence($table) { + $this->check_table_exists($table); + return $this->generator->disable_id_sequence($table); + } - return $this->generator->reset_sequence($table); + /** + * Re-enables the ID sequence. Must be used after disable_id_sequence. + * @param string $table name of table + * @return success + */ + public function enable_id_sequence($table) { + $this->check_table_exists($table); + return $this->generator->enable_id_sequence($table); } /** @@ -129,29 +140,13 @@ * @return boolean true/false */ public function field_exists($table, $field) { - /// Calculate the name of the table - if (is_string($table)) { - $tablename = $table; - } else { - $tablename = $table->getName(); - } - - /// Check the table exists - if (!$this->table_exists($table)) { - throw new ddl_table_missing_exception($tablename); - } - - if (is_string($field)) { - $fieldname = $field; - } else { - /// Calculate the name of the table - $fieldname = $field->getName(); - } + $tablename = $this->check_table_exists($table); + $fieldname = $this->object_name($field); /// Get list of fields in table $columns = $this->mdb->get_columns($tablename, false); - $exists = array_key_exists($fieldname, $columns); + $exists = array_key_exists($fieldname, $columns); return $exists; } @@ -165,13 +160,7 @@ * @return string index name of false */ public function find_index_name(xmldb_table $xmldb_table, xmldb_index $xmldb_index) { - /// Calculate the name of the table - $tablename = $xmldb_table->getName(); - - /// Check the table exists - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($tablename); - } + $tablename = $this->check_table_exists($table); /// Extract index columns $indcolumns = $xmldb_index->getFields(); @@ -221,9 +210,7 @@ public function find_check_constraint_name(xmldb_table $xmldb_table, xmldb_field $xmldb_field) { /// Check the table exists - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); /// Check the field exists if (!$this->field_exists($xmldb_table, $xmldb_field)) { @@ -312,9 +299,7 @@ * @return string sequence name of false */ public function find_sequence_name(xmldb_table $xmldb_table) { - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); $sequencename = false; @@ -369,9 +354,7 @@ */ public function drop_table(xmldb_table $xmldb_table) { /// Check table exists - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); if (!$sqlarr = $this->generator->getDropTableSQL($xmldb_table)) { throw new ddl_exception('ddlunknownerror', null, 'table drop sql not generated'); @@ -530,9 +513,7 @@ $xmldb_table = $this->generator->tweakTempTable($xmldb_table); /// Check table doesn't exist - if (!$this->table_exists($xmldb_table, true)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); if (!$sqlarr = $this->generator->getDropTempTableSQL($xmldb_table)) { throw new ddl_exception('ddlunknownerror', null, 'temp table drop sql not generated'); @@ -618,9 +599,8 @@ * @return void */ public function drop_field(xmldb_table $xmldb_table, xmldb_field $xmldb_field) { - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); + /// Check the field exists if (!$this->field_exists($xmldb_table, $xmldb_field)) { throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName()); @@ -641,9 +621,7 @@ * @return void */ public function change_field_type(xmldb_table $xmldb_table, xmldb_field $xmldb_field) { - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); /// Check the field exists if (!$this->field_exists($xmldb_table, $xmldb_field)) { throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName()); @@ -700,9 +678,7 @@ * @return void */ public function change_field_enum(xmldb_table $xmldb_table, xmldb_field $xmldb_field) { - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); /// Check the field exists if (!$this->field_exists($xmldb_table, $xmldb_field)) { throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName()); @@ -735,9 +711,7 @@ * @return void */ public function change_field_default(xmldb_table $xmldb_table, xmldb_field $xmldb_field) { - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); /// Check the field exists if (!$this->field_exists($xmldb_table, $xmldb_field)) { throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName()); @@ -764,9 +738,7 @@ throw new ddl_exception('ddlunknownerror', null, 'newname can not be empty'); } - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); /// Check the field exists if (!$this->field_exists($xmldb_table, $xmldb_field)) { @@ -866,9 +838,7 @@ * @return void */ public function add_index($xmldb_table, $xmldb_intex) { - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); /// Check index doesn't exist if ($this->index_exists($xmldb_table, $xmldb_intex)) { @@ -893,9 +863,7 @@ * @return void */ public function drop_index($xmldb_table, $xmldb_intex) { - if (!$this->table_exists($xmldb_table)) { - throw new ddl_table_missing_exception($xmldb_table->getName()); - } + $this->check_table_exists($xmldb_table); /// Check index exists if (!$this->index_exists($xmldb_table, $xmldb_intex)) { @@ -1040,6 +1008,37 @@ return $errors; } + + /** + * Some functions accept either an XMLDB object, or a string name. This utility + * method will accept either, and return the string name. + * @param string|xmldb_object $dbobject either a string name, or an object. + * @return string The string name. + */ + protected function object_name($dbobject) { + if (is_string($table)) { + $objectname = $dbobject; + } else { + $objectname = $dbobject->getName(); + } + return $objectname; + } + + /** + * Utility method: throws a ddl_table_missing_exception exception if the + * specified table does not exist. + * @param string|xmldb_table $table either a table name or a table object. + * @return string the table name, as a string. (For convenience.) + */ + protected function check_table_exists($table) { + $tablename = $this->object_name($table); + + if (!$this->table_exists($table)) { + throw new ddl_table_missing_exception($tablename); + } + + return $tablename; + } } Index: lib/ddl/sql_generator.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/ddl/sql_generator.php,v retrieving revision 1.14 diff -u -r1.14 sql_generator.php --- lib/ddl/sql_generator.php 12 Jan 2009 16:52:54 -0000 1.14 +++ lib/ddl/sql_generator.php 28 Apr 2009 07:26:16 -0000 @@ -166,12 +166,7 @@ * @return boolean true/false */ public function table_exists($table, $temptable=false) { - if (is_string($table)) { - $tablename = $table; - } else { - /// Calculate the name of the table - $tablename = $table->getName(); - } + $tablename = $this->object_name($table); /// get all tables in moodle database $tables = $this->mdb->get_tables(); @@ -188,6 +183,26 @@ public abstract function reset_sequence($tablename); /** + * Temporarily disables the ID sequence. Useful for bulk manipulations in + * upgrade.php scripts. Should not be used in normal code. It is ESSENTIAL + * that your code calls enable_id_sequence before it finishes. + * @param string $table name of table + * @return success + */ + public function disable_id_sequence($tablename) { + return true; + } + + /** + * Re-enables the ID sequence. Must be used after disable_id_sequence. + * @param string $table name of table + * @return success + */ + public function enable_id_sequence($tablename) { + return reset_sequence($tablename); + } + + /** * This function will return the SQL code needed to create db tables and statements */ public function getCreateStructureSQL($xmldb_structure) { @@ -1294,6 +1309,21 @@ $s = str_replace("'", "\\'", $s); return $s; } + + /** + * Some functions accept either an XMLDB object, or a string name. This utility + * method will accept either, and return the string name. + * @param string|xmldb_object $dbobject either a string name, or an object. + * @return string The string name. + */ + protected function object_name($dbobject) { + if (is_string($table)) { + $objectname = $dbobject; + } else { + $objectname = $dbobject->getName(); + } + return $objectname; + } } ?> Index: lib/db/upgrade.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v retrieving revision 1.285 diff -u -r1.285 upgrade.php --- lib/db/upgrade.php 27 Apr 2009 20:29:01 -0000 1.285 +++ lib/db/upgrade.php 28 Apr 2009 07:26:07 -0000 @@ -1501,7 +1501,7 @@ /// $CFG->allowuserswitchrolestheycantassign if ($result && $oldversion < 2009032000) { /// First create the new table. - $table = new xmldb_table('role_allow_switch'); + $table = new xmldb_table('role_allow_switch'); /// Adding fields to table role_allow_switch $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); @@ -1527,7 +1527,14 @@ if ($result && $oldversion < 2009032001) { /// Copy from role_allow_assign into the new table. - $DB->execute('INSERT INTO {role_allow_switch} SELECT * FROM {role_allow_assign}'); + $dbman->disable_id_sequence('role_allow_switch'); + try { + $DB->execute('INSERT INTO {role_allow_switch} SELECT * FROM {role_allow_assign}'); + $dbman->enable_id_sequence('role_allow_switch'); + } catch (Exception $e) { + $dbman->enable_id_sequence('role_allow_switch'); + throw $e; + } /// Unset the config variable used in 1.9. unset_config('allowuserswitchrolestheycantassign');