]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-14905 towards functional DB tests
authorskodak <skodak>
Thu, 12 Jun 2008 15:18:11 +0000 (15:18 +0000)
committerskodak <skodak>
Thu, 12 Jun 2008 15:18:11 +0000 (15:18 +0000)
lib/ddl/simpletest/testddllib.php
lib/dml/adodb_moodle_database.php
lib/dml/database_column_info.php
lib/dml/moodle_database.php
lib/dml/mysqli_adodb_moodle_database.php

index 5f8faff52bd6c337ac2e37701bba166ac1c0c66f..57d9b639758c763d429f60f477e7df19a9bfe5b1 100755 (executable)
@@ -94,22 +94,6 @@ class ddllib_test extends UnitTestCase {
         }
     }
 
-    public function testTableExists() {
-        $dbmanager = $this->db->get_manager();
-// TODO: this should be done with $this->db object
-
-        $table = $this->create_deftable('test_table0');
-        // Test giving a string
-        $this->assertFalse($dbmanager->table_exists('nonexistenttable'));
-        $this->assertTrue($dbmanager->table_exists('test_table0'));
-
-        // Test giving a table object
-        $nonexistenttable = new xmldb_table('nonexistenttable');
-        $this->assertFalse($dbmanager->table_exists($nonexistenttable));
-        $this->assertTrue($dbmanager->table_exists($table));
-    }
-
-
     private function create_deftable($tablename) {
         $dbmanager = $this->db->get_manager();
 
@@ -122,21 +106,37 @@ class ddllib_test extends UnitTestCase {
         if ($dbmanager->table_exists($table)) {
             $dbmanager->drop_table($table, true, false);
         }
-        $dbmanager->create_table($table);
+        $dbmanager->create_table($table, true, false);
 
         return $table;
     }
 
-    public function testCreateTable() {
+    public function testTableExists() {
+        $DB = $this->db; // do not use global $DB!
         $dbmanager = $this->db->get_manager();
-// TODO: add all data types, comments, keys and indexes
 
+        // first make sure it returns false if table does not exist
         $table = $this->tables['test_table0'];
+        ob_start(); // hide debug warning
+        $this->assertFalse($DB->get_records('test_table0'));
+        ob_end_clean();
+        $this->assertFalse($dbmanager->table_exists('test_table0'));
+        $this->assertFalse($dbmanager->table_exists($table));
 
-        $this->assertTrue($dbmanager->create_table($table));
+        // create table and test again
+        $this->assertTrue($dbmanager->create_table($table, true, false));
+        $this->assertTrue($DB->get_records('test_table0') !== false);
         $this->assertTrue($dbmanager->table_exists('test_table0'));
-        $dbmanager->drop_table($table);
-        $this->assertFalse($dbmanager->table_exists('test_table0'));
+        $this->assertTrue($dbmanager->table_exists($table));
+
+        // Test giving a string
+        $this->assertFalse($dbmanager->table_exists('nonexistenttable'));
+        $this->assertTrue($dbmanager->table_exists('test_table0'));
+    }
+
+    public function testCreateTable() {
+        $DB = $this->db; // do not use global $DB!
+        $dbmanager = $this->db->get_manager();
 
         // Give a wrong table param (expect a debugging message)
         $table = 'string';
@@ -144,19 +144,36 @@ class ddllib_test extends UnitTestCase {
         $this->assertFalse($dbmanager->create_table($table));
         ob_end_clean();
 
+        // create table and do basic column tests
+        $table = $this->tables['test_table1'];
+
+        $this->assertTrue($dbmanager->create_table($table));
+        $this->assertTrue($dbmanager->table_exists($table));
+
+        $columns = $DB->get_columns('test_table1');
+
+        $this->assertEqual($columns['id']->meta_type, 'R');
+        $this->assertEqual($columns['course']->meta_type, 'I');
+        $this->assertEqual($columns['name']->meta_type, 'C');
+        $this->assertEqual($columns['secondname']->meta_type, 'C');
+        $this->assertEqual($columns['intro']->meta_type, 'X');
+        $this->assertEqual($columns['avatar']->meta_type, 'B');
+        $this->assertEqual($columns['grade']->meta_type, 'N');
+
     }
 
     public function testDropTable() {
         $dbmanager = $this->db->get_manager();
 
         $table = $this->create_deftable('test_table0');
+
         $this->assertTrue($dbmanager->drop_table($table, true, false));
         $this->assertFalse($dbmanager->table_exists('test_table0'));
 
         // Try dropping non-existent table
         $table = new xmldb_table('nonexistenttable');
         ob_start(); // hide debug warning
-        $this->assertFalse($dbmanager->drop_table($table, true, false));
+        $this->assertTrue($dbmanager->drop_table($table, true, false));
         ob_end_clean();
 
         // Give a wrong table param
@@ -168,24 +185,70 @@ class ddllib_test extends UnitTestCase {
 
 
     public function testAddEnumField() {
+        $DB = $this->db; // do not use global $DB!
         $dbmanager = $this->db->get_manager();
-// TODO: verify the type in DB
 
-        $table = $this->create_deftable('test_table0');
+        $table = new xmldb_table('test_table_cust0');
+        $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'));
+        $this->assertTrue($dbmanager->create_table($table, true, false));
+
+        $enums = array('single', 'news', 'general');
 
         /// Create a new field with complex specs (enums are good candidates)
+        $field = new xmldb_field('type1');
+        $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, $enums, 'general', 'course');
+        $this->assertTrue($dbmanager->add_field($table, $field));
+        $this->assertTrue($dbmanager->field_exists($table, 'type1'));
+
         $field = new xmldb_field('type2');
-        $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM,
-            array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
+        $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, null, null, XMLDB_ENUM, $enums, 'general', 'course');
         $this->assertTrue($dbmanager->add_field($table, $field));
         $this->assertTrue($dbmanager->field_exists($table, 'type2'));
 
+        /// try inserting a good record
+        $record = new object();
+        $record->course = 666;
+        $record->type1 = 'news';
+        $record->type2 = NULL;
+        $this->assertTrue($DB->insert_record('test_table_cust0', $record, false));
+
+        /// try inserting a bad record
+        $record = new object();
+        $record->course = 666;
+        $record->type1 = 'xxxxxxxx';
+        $record->type2 = 'news';
+        ob_start(); // hide debug warning
+        $this->assertFalse($DB->insert_record('test_table_cust0', $record));
+        ob_end_clean();
+
+        /// try inserting a bad record
+        $record = new object();
+        $record->course = 666;
+        $record->type1 = 'news';
+        $record->type2 = 'xxxx';
+        ob_start(); // hide debug warning
+        $this->assertFalse($DB->insert_record('test_table_cust0', $record));
+        ob_end_clean();
+
+        $columns = $DB->get_columns('test_table_cust0');
+        $this->assertEqual($columns['type1']->meta_type, 'C');
+
+        // enums field is optional
+        $result = $columns['type1']->enums;
+        if (!is_null($result)) {
+            $this->assertEqual($result, $enums);
+        }
+
+        /// cleanup
         $dbmanager->drop_field($table, $field);
+        $dbmanager->drop_table($table);
     }
 
     public function testAddNumericField() {
+        $DB = $this->db; // do not use global $DB!
         $dbmanager = $this->db->get_manager();
-// TODO: verify the type in DB
 
         $table = $this->create_deftable('test_table0');
         /// Create a new field with complex specs (enums are good candidates)
@@ -194,10 +257,12 @@ class ddllib_test extends UnitTestCase {
         $this->assertTrue($dbmanager->add_field($table, $field));
         $this->assertTrue($dbmanager->field_exists($table, 'onenumber'));
 
+        $columns = $DB->get_columns('test_table0');
+        $this->assertEqual($columns['onenumber']->meta_type, 'I');
+
         $dbmanager->drop_field($table, $field);
     }
 
-
     public function testDropField() {
         $dbmanager = $this->db->get_manager();
 
@@ -206,39 +271,67 @@ class ddllib_test extends UnitTestCase {
 
         $this->assertTrue($dbmanager->field_exists($table, $field));
         $this->assertTrue($dbmanager->field_exists($table, 'type'));
+
         $this->assertTrue($dbmanager->drop_field($table, $field));
+
         $this->assertFalse($dbmanager->field_exists($table, 'type'));
     }
 
-
     public function testChangeFieldType() {
+        $DB = $this->db; // do not use global $DB!
         $dbmanager = $this->db->get_manager();
-// TODO: verify the type is changed in db
 
-        $table = $this->create_deftable('test_table1');
-        $field = new xmldb_field('course');
+        $table = new xmldb_table('test_table_cust0');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
+        $table->add_field('onenumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $dbmanager->create_table($table, true, false);
+
+        $record = new object();
+        $recorf->course = 2;
+        $DB->insert_record('test_table_cust0', $record);
+
+        $field = new xmldb_field('onenumber');
         $field->set_attributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, '0');
         $this->assertTrue($dbmanager->change_field_type($table, $field));
 
-        $field = new xmldb_field('course');
+        $columns = $DB->get_columns('test_table_cust0');
+        $this->assertEqual($columns['onenumber']->meta_type, 'C');
+
+        $field = new xmldb_field('onenumber');
         $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
         $this->assertTrue($dbmanager->change_field_type($table, $field));
 
-        $field = new xmldb_field('grade');
+        $columns = $DB->get_columns('test_table_cust0');
+        $this->assertEqual($columns['onenumber']->meta_type, 'I');
+
+        $field = new xmldb_field('onenumber');
         $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, "test'n drop");
         $this->assertTrue($dbmanager->change_field_type($table, $field));
 
-        $field = new xmldb_field('grade');
+        $columns = $DB->get_columns('test_table_cust0');
+        $this->assertEqual($columns['onenumber']->meta_type, 'C');
+
+        $field = new xmldb_field('onenumber');
         $field->set_attributes(XMLDB_TYPE_FLOAT, '20,10', XMLDB_UNSIGNED, null, null, null, null, null);
         $this->assertTrue($dbmanager->change_field_type($table, $field));
 
-        $field = new xmldb_field('grade');
+        $columns = $DB->get_columns('test_table_cust0');
+        $this->assertEqual($columns['onenumber']->meta_type, 'N');
+
+        $field = new xmldb_field('onenumber');
         $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'test');
         $this->assertTrue($dbmanager->change_field_type($table, $field));
 
-        $field = new xmldb_field('grade');
+        $columns = $DB->get_columns('test_table_cust0');
+        $this->assertEqual($columns['onenumber']->meta_type, 'C');
+
+        $field = new xmldb_field('onenumber');
         $field->set_attributes(XMLDB_TYPE_NUMBER, '20,10', XMLDB_UNSIGNED, null, null, null, null, null);
         $this->assertTrue($dbmanager->change_field_type($table, $field));
+
+        $columns = $DB->get_columns('test_table_cust0');
+        $this->assertEqual($columns['onenumber']->meta_type, 'N');
     }
 
     public function testChangeFieldPrecision() {
@@ -431,29 +524,6 @@ class ddllib_test extends UnitTestCase {
                 array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
         $this->assertTrue($dbmanager->change_field_enum($table, $field));
     }
-/*
-    public function testRenameIndex() {
-        // unsupported!
-        $dbmanager = $this->db->get_manager();
-
-        $table = $this->create_deftable('test_table0');
-        $index = new xmldb_index('course');
-        $index->set_attributes(XMLDB_INDEX_UNIQUE, array('course'));
-
-        $this->assertTrue($dbmanager->rename_index($table, $index, 'newindexname'));
-    }
-
-    public function testRenameKey() {
-        //unsupported
-         $dbmanager = $this->db->get_manager();
-
-        $table = $this->create_deftable('test_table0');
-        $key = new xmldb_key('course');
-        $key->set_attributes(XMLDB_KEY_UNIQUE, array('course'));
-
-        $this->assertTrue($dbmanager->rename_key($table, $key, 'newkeyname'));
-    }
-*/
 
     public function testRenameField() {
         $dbmanager = $this->db->get_manager();
@@ -639,5 +709,31 @@ class ddllib_test extends UnitTestCase {
         $this->assertFalse($dbmanager->table_exists('test_table1', true));
     }
 
+
+ // Following methods are not supported == Do not test
+/*
+    public function testRenameIndex() {
+        // unsupported!
+        $dbmanager = $this->db->get_manager();
+
+        $table = $this->create_deftable('test_table0');
+        $index = new xmldb_index('course');
+        $index->set_attributes(XMLDB_INDEX_UNIQUE, array('course'));
+
+        $this->assertTrue($dbmanager->rename_index($table, $index, 'newindexname'));
+    }
+
+    public function testRenameKey() {
+        //unsupported
+         $dbmanager = $this->db->get_manager();
+
+        $table = $this->create_deftable('test_table0');
+        $key = new xmldb_key('course');
+        $key->set_attributes(XMLDB_KEY_UNIQUE, array('course'));
+
+        $this->assertTrue($dbmanager->rename_key($table, $key, 'newkeyname'));
+    }
+*/
+
 }
 ?>
index 3ab3a0d900963217dca3365be8dddbcb23384eae..406c2aba9dbf0bb1a245f31a8c1ec7f996ab77ec 100644 (file)
@@ -154,6 +154,14 @@ abstract class adodb_moodle_database extends moodle_database {
         foreach ($columns as $column) {
             // colum names must be lowercase
             $column->meta_type = substr($this->db->MetaType($column), 0 ,1); // only 1 character
+            if (!empty($column->enums)) {
+                // hack: fix the 'quotes' surrounding the values itroduced by adodb
+                foreach ($column->enums as $key=>$value) {
+                    if (strpos($value, "'") === 0 and strlen($value) > 2) {
+                        $column->enums[$key] = substr($value, 1, strlen($value)-2);
+                    }
+                }
+            } 
             $this->columns[$table][$column->name] = new database_column_info($column);
         }
 
index 452dad03ca7a609d7244243d512ce521aed20cad..6bc7b53af2b81b5ef662a12dee28e755f6cd53c0 100644 (file)
@@ -36,8 +36,11 @@ class database_column_info {
     public $scale;
 
     /**
-     * Enumerated filed options,
+     * Enumerated field options,
      * null if not enum type
+     *
+     * For performance reasons this field is optional!
+     * You can use DDL sql_generator::getCheckConstraintsFromDB() if needed.
      */
     public $enums;
 
index 7593d5ffb3b11a7876f46985b7d144b6bf1c79fc..93e5cd88aa064a4efce92572e33631d8debb271e 100644 (file)
@@ -369,7 +369,7 @@ abstract class moodle_database {
      * @return void
      */
     public function reset_columns() {
-        $this->columns[] = array();
+        $this->columns = array();
     }
 
     /**
index 176a109776140ac83cebd2b2c644b9815936f1ec..80021cc6090354ccdf63510de8ddb53a07f84987 100644 (file)
@@ -150,9 +150,21 @@ class mysqli_adodb_moodle_database extends adodb_moodle_database {
             if (!isset($columns[$field])) {
                 continue;
             }
+            $column = $columns[$field];
             if (is_bool($value)) {
                 $value = (int)$value; // prevent "false" problems
             }
+            if (!empty($column->enums)) {
+                // workaround for problem with wrong enums in mysql
+                if (is_null($value) and !$column->not_null) {
+                    // ok - nulls allowed
+                } else {
+                    if (!in_array((string)$value, $column->enums)) {
+                        debugging('Enum value '.s($value).' not allowed in field '.$field.' table '.$table.'.');
+                        return false;
+                    }
+                }
+            }
             $cleaned[$field] = $value;
         }