t('Schema API'), 'description' => t('Tests table creation and modification via the schema API.'), 'group' => t('Database'), ); } /** * */ function testSchema() { // Try creating a table. $table_specification = array( 'description' => 'Schema table description.', 'fields' => array( 'id' => array( 'type' => 'int', 'default' => NULL, ), 'test_field' => array( 'type' => 'int', 'not null' => TRUE, 'description' => 'Schema column description.', ), ), ); $ret = array(); db_create_table($ret, 'test_table', $table_specification); // Assert that the table exists. $this->assertTrue(db_table_exists('test_table'), t('The table exists.')); // Assert that the table comment has been set. $this->checkSchemaComment($table_specification['description'], 'test_table'); // Assert that the column comment has been set. $this->checkSchemaComment($table_specification['fields']['test_field']['description'], 'test_table', 'test_field'); // An insert without a value for the column 'test_table' should fail. $this->assertFalse($this->tryInsert(), t('Insert without a default failed.')); // Add a default value to the column. db_field_set_default($ret, 'test_table', 'test_field', 0); // The insert should now succeed. $this->assertTrue($this->tryInsert(), t('Insert with a default succeeded.')); // Remove the default. db_field_set_no_default($ret, 'test_table', 'test_field'); // The insert should fail again. $this->assertFalse($this->tryInsert(), t('Insert without a default failed.')); // Rename the table. db_rename_table($ret, 'test_table', 'test_table2'); // We need the default so that we can insert after the rename. db_field_set_default($ret, 'test_table2', 'test_field', 0); $this->assertFalse($this->tryInsert(), t('Insert into the old table failed.')); $this->assertTrue($this->tryInsert('test_table2'), t('Insert into the new table succeeded.')); // We should have successfully inserted exactly two rows. $count = db_query('SELECT COUNT(*) FROM {test_table2}')->fetchField(); $this->assertEqual($count, 2, t('Two fields were successfully inserted.')); // Try to drop the table. db_drop_table($ret, 'test_table2'); $this->assertFalse(db_table_exists('test_table2'), t('The dropped table does not exist.')); // Recreate the table. db_create_table($ret, 'test_table', $table_specification); db_field_set_default($ret, 'test_table', 'test_field', 0); db_add_field($ret, 'test_table', 'test_serial', array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Added column description.')); // Assert that the column comment has been set. $this->checkSchemaComment('Added column description.', 'test_table', 'test_serial'); // Change the new field to a serial column. db_change_field($ret, 'test_table', 'test_serial', 'test_serial', array('type' => 'serial', 'not null' => TRUE, 'description' => 'Changed column description.'), array('primary key' => array('test_serial'))); // Assert that the column comment has been set. $this->checkSchemaComment('Changed column description.', 'test_table', 'test_serial'); $this->assertTrue($this->tryInsert(), t('Insert with a serial succeeded.')); $max1 = db_query('SELECT MAX(test_serial) FROM {test_table}')->fetchField(); $this->assertTrue($this->tryInsert(), t('Insert with a serial succeeded.')); $max2 = db_query('SELECT MAX(test_serial) FROM {test_table}')->fetchField(); $this->assertTrue($max2 > $max1, t('The serial is monotone.')); $count = db_query('SELECT COUNT(*) FROM {test_table}')->fetchField(); $this->assertEqual($count, 2, t('There were two rows.')); } function tryInsert($table = 'test_table') { try { db_query("INSERT INTO {" . $table . "} (id) VALUES (:id)", array(':id' => mt_rand(10,20))); return TRUE; } catch (Exception $e) { return FALSE; } } /** * Checks that a table or column comment matches a given description. * * @param $description * The asserted description. * @param $table * The table to test. * @param $column * Optional column to test. */ function checkSchemaComment($description, $table, $column = NULL) { if (method_exists(Database::getConnection()->schema(), 'getComment')) { $comment = Database::getConnection()->schema()->getComment($table, $column); $this->assertEqual($comment, $description, t('The comment matches the schema description.')); } } }