From fb76304b3bc760d6d035e4478dfbf93a878f8e7d Mon Sep 17 00:00:00 2001 From: skodak Date: Mon, 27 Oct 2008 20:21:04 +0000 Subject: [PATCH] MDL-17020 dml: native pgsql driver - implementation and unittests of transactions --- lib/dml/moodle_database.php | 6 +-- lib/dml/pgsql_native_moodle_database.php | 43 ++++++++++++++++ lib/dml/simpletest/testdml.php | 63 ++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/lib/dml/moodle_database.php b/lib/dml/moodle_database.php index 2ac78095105..cedb15eacef 100644 --- a/lib/dml/moodle_database.php +++ b/lib/dml/moodle_database.php @@ -1543,21 +1543,21 @@ abstract class moodle_database { * this is _very_ useful for massive updates */ public function begin_sql() { - return true; + return false; } /** * on DBs that support it, commit the transaction */ public function commit_sql() { - return true; + return false; } /** * on DBs that support it, rollback the transaction */ public function rollback_sql() { - return true; + return false; } /// performance and logging diff --git a/lib/dml/pgsql_native_moodle_database.php b/lib/dml/pgsql_native_moodle_database.php index c76e17ce487..ca78d839cb5 100644 --- a/lib/dml/pgsql_native_moodle_database.php +++ b/lib/dml/pgsql_native_moodle_database.php @@ -1036,4 +1036,47 @@ class pgsql_native_moodle_database extends moodle_database { return $positivematch ? '~*' : '!~*'; } +/// transactions + /** + * on DBs that support it, switch to transaction mode and begin a transaction + * you'll need to ensure you call commit_sql() or your changes *will* be lost. + * + * this is _very_ useful for massive updates + */ + public function begin_sql() { + $sql = "BEGIN ISOLATION LEVEL READ COMMITTED"; + $result = pg_query($this->pgsql, $sql); + if ($result === false) { + return false; + } + pg_free_result($result); + return true; + } + + /** + * on DBs that support it, commit the transaction + */ + public function commit_sql() { + $sql = "COMMIT"; + $result = pg_query($this->pgsql, $sql); + if ($result === false) { + return false; + } + pg_free_result($result); + return true; + } + + /** + * on DBs that support it, rollback the transaction + */ + public function rollback_sql() { + $sql = "ROLLBACK"; + $result = pg_query($this->pgsql, $sql); + if ($result === false) { + return false; + } + pg_free_result($result); + return true; + } + } diff --git a/lib/dml/simpletest/testdml.php b/lib/dml/simpletest/testdml.php index 01a19420bda..3be5bad67c9 100755 --- a/lib/dml/simpletest/testdml.php +++ b/lib/dml/simpletest/testdml.php @@ -1394,6 +1394,69 @@ class dml_test extends UnitTestCase { $this->assertEqual($DB->get_field_sql( "SELECT " . $DB->sql_position("'Oracle'", "'Moodle'") . $DB->sql_null_from_clause()), 0); } + + function test_begin_sql() { + $DB = $this->tdb; + $dbman = $DB->get_manager(); + + $table = $this->get_test_table($dbman, "testtable"); + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); + $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $dbman->create_table($table); + $this->tables[$table->getName()] = $table; + + $active = $DB->begin_sql(); + if ($active) { + // test only if driver supports transactions + $data = (object)array('course'=>3); + $DB->insert_record('testtable', $data); + $this->assertEqual(1, $DB->count_records('testtable')); + $DB->commit_sql(); + } + } + + function test_commit_sql() { + $DB = $this->tdb; + $dbman = $DB->get_manager(); + + $table = $this->get_test_table($dbman, "testtable"); + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); + $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $dbman->create_table($table); + $this->tables[$table->getName()] = $table; + + $active = $DB->begin_sql(); + if ($active) { + // test only if driver supports transactions + $data = (object)array('course'=>3); + $DB->insert_record('testtable', $data); + $DB->commit_sql(); + $this->assertEqual(1, $DB->count_records('testtable')); + } + } + + function test_rollback_sql() { + $DB = $this->tdb; + $dbman = $DB->get_manager(); + + $table = $this->get_test_table($dbman, "testtable"); + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); + $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $dbman->create_table($table); + $this->tables[$table->getName()] = $table; + + $active = $DB->begin_sql(); + if ($active) { + // test only if driver supports transactions + $data = (object)array('course'=>3); + $DB->insert_record('testtable', $data); + $DB->rollback_sql(); + $this->assertEqual(0, $DB->count_records('testtable')); + } + } } /**