Issue #2056133 by chx, dawehner, plach, alexpott: Add db_copy_table().
parent
ccc7822c4d
commit
0e129e5817
|
@ -679,6 +679,23 @@ function db_rename_table($table, $new_name) {
|
|||
return Database::getConnection()->schema()->renameTable($table, $new_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the structure of a table.
|
||||
*
|
||||
* @param string $source
|
||||
* The name of the table to be copied.
|
||||
* @param string $destination
|
||||
* The name for the new table.
|
||||
*
|
||||
* @return \Drupal\Core\Database\StatementInterface
|
||||
* The result of the executed query.
|
||||
*
|
||||
* @see \Drupal\Core\Database\Schema::copyTable()
|
||||
*/
|
||||
function db_copy_table_schema($source, $destination) {
|
||||
return Database::getConnection()->schema()->copyTable($source, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a table.
|
||||
*
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Database\Driver\mysql;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Database\SchemaObjectExistsException;
|
||||
|
@ -327,6 +328,21 @@ class Schema extends DatabaseSchema {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function copyTable($source, $destination) {
|
||||
if (!$this->tableExists($source)) {
|
||||
throw new SchemaObjectDoesNotExistException(String::format("Cannot copy @source to @destination: table @source doesn't exist.", array('@source' => $source, '@destination' => $destination)));
|
||||
}
|
||||
if ($this->tableExists($destination)) {
|
||||
throw new SchemaObjectExistsException(String::format("Cannot copy @source to @destination: table @destination already exists.", array('@source' => $source, '@destination' => $destination)));
|
||||
}
|
||||
|
||||
$info = $this->getPrefixInfo($destination);
|
||||
return $this->connection->query('CREATE TABLE `' . $info['table'] . '` LIKE {' . $source . '}');
|
||||
}
|
||||
|
||||
public function addField($table, $field, $spec, $keys_new = array()) {
|
||||
if (!$this->tableExists($table)) {
|
||||
throw new SchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", array('@field' => $field, '@table' => $table)));
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Database\Driver\pgsql;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Database\SchemaObjectExistsException;
|
||||
|
@ -348,6 +349,16 @@ class Schema extends DatabaseSchema {
|
|||
$this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $prefixInfo['table']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function copyTable($source, $destination) {
|
||||
// @TODO The server is likely going to rename indexes and constraints
|
||||
// during the copy process, and it will not match our
|
||||
// table_name + constraint name convention anymore.
|
||||
throw new \Exception('Not implemented, see https://drupal.org/node/2061879');
|
||||
}
|
||||
|
||||
public function dropTable($table) {
|
||||
if (!$this->tableExists($table)) {
|
||||
return FALSE;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Database\Driver\sqlite;
|
||||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Database\SchemaObjectExistsException;
|
||||
use Drupal\Core\Database\SchemaObjectDoesNotExistException;
|
||||
use Drupal\Core\Database\Schema as DatabaseSchema;
|
||||
|
@ -272,6 +273,20 @@ class Schema extends DatabaseSchema {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function copyTable($source, $destination) {
|
||||
if (!$this->tableExists($source)) {
|
||||
throw new SchemaObjectDoesNotExistException(String::format("Cannot copy @source to @destination: table @source doesn't exist.", array('@source' => $source, '@destination' => $destination)));
|
||||
}
|
||||
if ($this->tableExists($destination)) {
|
||||
throw new SchemaObjectExistsException(String::format("Cannot copy @source to @destination: table @destination already exists.", array('@source' => $source, '@destination' => $destination)));
|
||||
}
|
||||
|
||||
$this->createTable($destination, $this->introspectSchema($source));
|
||||
}
|
||||
|
||||
public function dropTable($table) {
|
||||
if (!$this->tableExists($table)) {
|
||||
return FALSE;
|
||||
|
|
|
@ -407,6 +407,24 @@ abstract class Schema implements PlaceholderInterface {
|
|||
*/
|
||||
abstract public function dropTable($table);
|
||||
|
||||
/**
|
||||
* Copies the table schema.
|
||||
*
|
||||
* @param string $source
|
||||
* The name of the table to be used as source.
|
||||
* @param string $destination
|
||||
* The name of the table to be used as destination.
|
||||
*
|
||||
* @return \Drupal\Core\Database\StatementInterface
|
||||
* The result of the executed query.
|
||||
*
|
||||
* @throws \Drupal\Core\Database\SchemaObjectExistsException
|
||||
* Thrown when the source table does not exist.
|
||||
* @throws \Drupal\Core\Database\SchemaObjectDoesNotExistException
|
||||
* Thrown when the destination table already exists.
|
||||
*/
|
||||
abstract public function copyTable($source, $destination);
|
||||
|
||||
/**
|
||||
* Add a new field to a table.
|
||||
*
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
namespace Drupal\system\Tests\Database;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\SchemaObjectDoesNotExistException;
|
||||
use Drupal\Core\Database\SchemaObjectExistsException;
|
||||
use Drupal\simpletest\UnitTestBase;
|
||||
|
||||
/**
|
||||
|
@ -87,6 +89,38 @@ class SchemaTest extends UnitTestBase {
|
|||
$index_exists = Database::getConnection()->schema()->indexExists('test_table2', 'test_field');
|
||||
$this->assertTrue($index_exists, 'Index was renamed.');
|
||||
|
||||
// Copy the schema of the table.
|
||||
db_copy_table_schema('test_table2', 'test_table3');
|
||||
|
||||
// Index should be copied.
|
||||
$index_exists = Database::getConnection()->schema()->indexExists('test_table3', 'test_field');
|
||||
$this->assertTrue($index_exists, 'Index was copied.');
|
||||
|
||||
// Data should still exist on the old table but not on the new one.
|
||||
$count = db_select('test_table2')->countQuery()->execute()->fetchField();
|
||||
$this->assertEqual($count, 1, 'The old table still has its content.');
|
||||
$count = db_select('test_table3')->countQuery()->execute()->fetchField();
|
||||
$this->assertEqual($count, 0, 'The new table has no content.');
|
||||
|
||||
// Ensure that the proper exceptions are thrown for db_copy_table_schema().
|
||||
$fail = FALSE;
|
||||
try {
|
||||
db_copy_table_schema('test_table4', 'test_table5');
|
||||
}
|
||||
catch (SchemaObjectDoesNotExistException $e) {
|
||||
$fail = TRUE;
|
||||
}
|
||||
$this->assertTrue($fail, 'Ensure that db_copy_table_schema() throws an exception when the source table does not exist.');
|
||||
|
||||
$fail = FALSE;
|
||||
try {
|
||||
db_copy_table_schema('test_table2', 'test_table3');
|
||||
}
|
||||
catch (SchemaObjectExistsException $e) {
|
||||
$fail = TRUE;
|
||||
}
|
||||
$this->assertTrue($fail, 'Ensure that db_copy_table_schema() throws an exception when the destination table already exists.');
|
||||
|
||||
// We need the default so that we can insert after the rename.
|
||||
db_field_set_default('test_table2', 'test_field', 0);
|
||||
$this->assertFalse($this->tryInsert(), 'Insert into the old table failed.');
|
||||
|
@ -154,9 +188,9 @@ class SchemaTest extends UnitTestBase {
|
|||
*/
|
||||
function tryInsert($table = 'test_table') {
|
||||
try {
|
||||
db_insert($table)
|
||||
->fields(array('id' => mt_rand(10, 20)))
|
||||
->execute();
|
||||
db_insert($table)
|
||||
->fields(array('id' => mt_rand(10, 20)))
|
||||
->execute();
|
||||
return TRUE;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
|
@ -227,8 +261,8 @@ class SchemaTest extends UnitTestBase {
|
|||
function tryUnsignedInsert($table_name, $column_name) {
|
||||
try {
|
||||
db_insert($table_name)
|
||||
->fields(array($column_name => -1))
|
||||
->execute();
|
||||
->fields(array($column_name => -1))
|
||||
->execute();
|
||||
return TRUE;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
|
|
Loading…
Reference in New Issue