diff --git a/lib/private/db.php b/lib/private/db.php index f801513368..dc25092e27 100644 --- a/lib/private/db.php +++ b/lib/private/db.php @@ -263,16 +263,7 @@ class OC_DB { */ public static function dropTable($tableName) { $connection = \OC::$server->getDatabaseConnection(); - $tableName = OC_Config::getValue('dbtableprefix', 'oc_' ) . trim($tableName); - - $connection->beginTransaction(); - - $platform = $connection->getDatabasePlatform(); - $sql = $platform->getDropTableSQL($platform->quoteIdentifier($tableName)); - - $connection->executeQuery($sql); - - $connection->commit(); + $connection->dropTable($tableName); } /** @@ -334,42 +325,7 @@ class OC_DB { * @throws \OC\DatabaseException */ public static function tableExists($table) { - - $table = OC_Config::getValue('dbtableprefix', 'oc_' ) . trim($table); - - $dbType = OC_Config::getValue( 'dbtype', 'sqlite' ); - switch ($dbType) { - case 'sqlite': - case 'sqlite3': - $sql = "SELECT name FROM sqlite_master " - . "WHERE type = 'table' AND name = ? " - . "UNION ALL SELECT name FROM sqlite_temp_master " - . "WHERE type = 'table' AND name = ?"; - $result = \OC_DB::executeAudited($sql, array($table, $table)); - break; - case 'mysql': - $sql = 'SHOW TABLES LIKE ?'; - $result = \OC_DB::executeAudited($sql, array($table)); - break; - case 'pgsql': - $sql = 'SELECT tablename AS table_name, schemaname AS schema_name ' - . 'FROM pg_tables WHERE schemaname NOT LIKE \'pg_%\' ' - . 'AND schemaname != \'information_schema\' ' - . 'AND tablename = ?'; - $result = \OC_DB::executeAudited($sql, array($table)); - break; - case 'oci': - $sql = 'SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME = ?'; - $result = \OC_DB::executeAudited($sql, array($table)); - break; - case 'mssql': - $sql = 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ?'; - $result = \OC_DB::executeAudited($sql, array($table)); - break; - default: - throw new \OC\DatabaseException("Unknown database type: $dbType"); - } - - return $result->fetchOne() === $table; + $connection = \OC::$server->getDatabaseConnection(); + return $connection->tableExists($table); } } diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php index a6cdf85889..9de7a719ff 100644 --- a/lib/private/db/connection.php +++ b/lib/private/db/connection.php @@ -164,6 +164,31 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection { return $msg; } + /** + * Drop a table from the database if it exists + * + * @param string $table table name without the prefix + */ + public function dropTable($table) { + $table = $this->tablePrefix . trim($table); + $schema = $this->getSchemaManager(); + if($schema->tablesExist(array($table))) { + $schema->dropTable($table); + } + } + + /** + * Check if a table exists + * + * @param string $table table name without the prefix + * @return bool + */ + public function tableExists($table){ + $table = $this->tablePrefix . trim($table); + $schema = $this->getSchemaManager(); + return $schema->tablesExist(array($table)); + } + // internal use /** * @param string $statement diff --git a/lib/private/db/oracleconnection.php b/lib/private/db/oracleconnection.php index 4cec7bc4ae..726ac1e4b6 100644 --- a/lib/private/db/oracleconnection.php +++ b/lib/private/db/oracleconnection.php @@ -47,4 +47,31 @@ class OracleConnection extends Connection { $identifier = $this->quoteKeys($identifier); return parent::delete($tableName, $identifier); } + + /** + * Drop a table from the database if it exists + * + * @param string $table table name without the prefix + */ + public function dropTable($table) { + $table = $this->tablePrefix . trim($table); + $table = $this->quoteIdentifier($table); + $schema = $this->getSchemaManager(); + if($schema->tablesExist(array($table))) { + $schema->dropTable($table); + } + } + + /** + * Check if a table exists + * + * @param string $table table name without the prefix + * @return bool + */ + public function tableExists($table){ + $table = $this->tablePrefix . trim($table); + $table = $this->quoteIdentifier($table); + $schema = $this->getSchemaManager(); + return $schema->tablesExist(array($table)); + } } diff --git a/lib/public/idbconnection.php b/lib/public/idbconnection.php index ce17d293e8..32310fe755 100644 --- a/lib/public/idbconnection.php +++ b/lib/public/idbconnection.php @@ -158,4 +158,19 @@ interface IDBConnection { * @return \Doctrine\DBAL\Platforms\AbstractPlatform The database platform. */ public function getDatabasePlatform(); + + /** + * Drop a table from the database if it exists + * + * @param string $table table name without the prefix + */ + public function dropTable($table); + + /** + * Check if a table exists + * + * @param string $table table name without the prefix + * @return bool + */ + public function tableExists($table); } diff --git a/tests/lib/db/connection.php b/tests/lib/db/connection.php new file mode 100644 index 0000000000..070c75db55 --- /dev/null +++ b/tests/lib/db/connection.php @@ -0,0 +1,69 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\DB; + +use Doctrine\DBAL\Platforms\SqlitePlatform; +use OC\DB\MDB2SchemaManager; + +class Connection extends \Test\TestCase { + /** + * @var \OCP\IDBConnection + */ + private $connection; + + public function setUp() { + parent::setUp(); + $this->connection = \OC::$server->getDatabaseConnection(); + } + + /** + * @param string $table + */ + public function assertTableExist($table) { + if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { + // sqlite removes the tables after closing the DB + $this->assertTrue(true); + } else { + $this->assertTrue($this->connection->tableExists($table), 'Table ' . $table . ' exists.'); + } + } + + /** + * @param string $table + */ + public function assertTableNotExist($table) { + if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { + // sqlite removes the tables after closing the DB + $this->assertTrue(true); + } else { + $this->assertFalse($this->connection->tableExists($table), 'Table ' . $table . ' doesnt exists.'); + } + } + + private function makeTestTable() { + $schemaManager = new MDB2SchemaManager($this->connection); + $schemaManager->createDbFromStructure(__DIR__ . '/testschema.xml'); + } + + public function testTableExists() { + $this->assertTableNotExist('table'); + $this->makeTestTable(); + $this->assertTableExist('table'); + } + + /** + * @depends testTableExists + */ + public function testDropTable() { + $this->assertTableExist('table'); + $this->connection->dropTable('table'); + $this->assertTableNotExist('table'); + } +}