Merge pull request #4291 from owncloud/schema

update DB Schema class
This commit is contained in:
Bart Visscher 2013-08-05 11:29:52 -07:00
commit 9b6357e6aa
2 changed files with 81 additions and 59 deletions

View File

@ -193,6 +193,27 @@ class OC_DB {
return true; return true;
} }
/**
* get the database connection object
*
* @return \Doctrine\DBAL\Connection
*/
private static function getConnection()
{
self::connect();
return self::$connection;
}
/**
* get MDB2 schema manager
*
* @return \OC\DB\MDB2SchemaManager
*/
private static function getMDB2SchemaManager()
{
return new \OC\DB\MDB2SchemaManager(self::getConnection());
}
/** /**
* @brief Prepare a SQL query * @brief Prepare a SQL query
* @param string $query Query string * @param string $query Query string
@ -387,7 +408,7 @@ class OC_DB {
} }
/** else { /** else {
* @brief saves database scheme to xml file * @brief saves database schema to xml file
* @param string $file name of file * @param string $file name of file
* @param int $mode * @param int $mode
* @return bool * @return bool
@ -395,8 +416,8 @@ class OC_DB {
* TODO: write more documentation * TODO: write more documentation
*/ */
public static function getDbStructure( $file, $mode=MDB2_SCHEMA_DUMP_STRUCTURE) { public static function getDbStructure( $file, $mode=MDB2_SCHEMA_DUMP_STRUCTURE) {
self::connectDoctrine(); $schemaManager = self::getMDB2SchemaManager();
return OC_DB_Schema::getDbStructure(self::$DOCTRINE, $file); return $schemaManager->getDbStructure($file);
} }
/** /**
@ -407,20 +428,21 @@ class OC_DB {
* TODO: write more documentation * TODO: write more documentation
*/ */
public static function createDbFromStructure( $file ) { public static function createDbFromStructure( $file ) {
self::connectDoctrine(); $schemaManager = self::getMDB2SchemaManager();
return OC_DB_Schema::createDbFromStructure(self::$DOCTRINE, $file); $result = $schemaManager->createDbFromStructure($file);
return $result;
} }
/** /**
* @brief update the database scheme * @brief update the database schema
* @param string $file file to read structure from * @param string $file file to read structure from
* @throws Exception * @throws Exception
* @return bool * @return bool
*/ */
public static function updateDbFromStructure($file) { public static function updateDbFromStructure($file) {
self::connectDoctrine(); $schemaManager = self::getMDB2SchemaManager();
try { try {
$result = OC_DB_Schema::updateDbFromStructure(self::$DOCTRINE, $file); $result = $schemaManager->updateDbFromStructure($file);
} catch (Exception $e) { } catch (Exception $e) {
OC_Log::write('core', 'Failed to update database structure ('.$e.')', OC_Log::FATAL); OC_Log::write('core', 'Failed to update database structure ('.$e.')', OC_Log::FATAL);
throw $e; throw $e;
@ -599,8 +621,8 @@ class OC_DB {
* @param string $tableName the table to drop * @param string $tableName the table to drop
*/ */
public static function dropTable($tableName) { public static function dropTable($tableName) {
self::connectDoctrine(); $schemaManager = self::getMDB2SchemaManager();
OC_DB_Schema::dropTable(self::$DOCTRINE, $tableName); $schemaManager->dropTable($tableName);
} }
/** /**
@ -608,8 +630,8 @@ class OC_DB {
* @param string $file the xml file describing the tables * @param string $file the xml file describing the tables
*/ */
public static function removeDBStructure($file) { public static function removeDBStructure($file) {
self::connectDoctrine(); $schemaManager = self::getMDB2SchemaManager();
OC_DB_Schema::removeDBStructure(self::$DOCTRINE, $file); $schemaManager->removeDBStructure($file);
} }
/** /**
@ -617,8 +639,8 @@ class OC_DB {
* @param $file string path to the MDB2 xml db export file * @param $file string path to the MDB2 xml db export file
*/ */
public static function replaceDB( $file ) { public static function replaceDB( $file ) {
self::connectDoctrine(); $schemaManager = self::getMDB2SchemaManager();
OC_DB_Schema::replaceDB(self::$DOCTRINE, $file); $schemaManager->replaceDB($file);
} }
/** /**

View File

@ -6,47 +6,58 @@
* See the COPYING-README file. * See the COPYING-README file.
*/ */
class OC_DB_Schema { namespace OC\DB;
class MDB2SchemaManager {
/**
* @var \Doctrine\DBAL\Connection $conn
*/
protected $conn;
/**
* @param \Doctrine\DBAL\Connection $conn
*/
public function __construct($conn) {
$this->conn = $conn;
}
/** /**
* @brief saves database scheme to xml file * @brief saves database scheme to xml file
* @param \Doctrine\DBAL\Connection $conn
* @param string $file name of file * @param string $file name of file
* @param int|string $mode * @param int|string $mode
* @return bool * @return bool
* *
* TODO: write more documentation * TODO: write more documentation
*/ */
public static function getDbStructure( $conn, $file, $mode=MDB2_SCHEMA_DUMP_STRUCTURE) { public function getDbStructure( $file, $mode = MDB2_SCHEMA_DUMP_STRUCTURE) {
$sm = $conn->getSchemaManager(); $sm = $this->conn->getSchemaManager();
return OC_DB_MDB2SchemaWriter::saveSchemaToFile($file, $sm); return \OC_DB_MDB2SchemaWriter::saveSchemaToFile($file, $sm);
} }
/** /**
* @brief Creates tables from XML file * @brief Creates tables from XML file
* @param \Doctrine\DBAL\Connection $conn
* @param string $file file to read structure from * @param string $file file to read structure from
* @return bool * @return bool
* *
* TODO: write more documentation * TODO: write more documentation
*/ */
public static function createDbFromStructure( $conn, $file ) { public function createDbFromStructure( $file ) {
$schemaReader = new \OC\DB\MDB2SchemaReader(\OC_Config::getObject(), $conn->getDatabasePlatform()); $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
$toSchema = $schemaReader->loadSchemaFromFile($file); $toSchema = $schemaReader->loadSchemaFromFile($file);
return self::executeSchemaChange($conn, $toSchema); return $this->executeSchemaChange($toSchema);
} }
/** /**
* @brief update the database scheme * @brief update the database scheme
* @param \Doctrine\DBAL\Connection $conn
* @param string $file file to read structure from * @param string $file file to read structure from
* @return bool * @return bool
*/ */
public static function updateDbFromStructure($conn, $file) { public function updateDbFromStructure($file) {
$sm = $conn->getSchemaManager(); $sm = $this->conn->getSchemaManager();
$fromSchema = $sm->createSchema(); $fromSchema = $sm->createSchema();
$schemaReader = new \OC\DB\MDB2SchemaReader(\OC_Config::getObject(), $conn->getDatabasePlatform()); $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
$toSchema = $schemaReader->loadSchemaFromFile($file); $toSchema = $schemaReader->loadSchemaFromFile($file);
// remove tables we don't know about // remove tables we don't know about
@ -65,43 +76,34 @@ class OC_DB_Schema {
$comparator = new \Doctrine\DBAL\Schema\Comparator(); $comparator = new \Doctrine\DBAL\Schema\Comparator();
$schemaDiff = $comparator->compare($fromSchema, $toSchema); $schemaDiff = $comparator->compare($fromSchema, $toSchema);
$platform = $conn->getDatabasePlatform(); $platform = $this->conn->getDatabasePlatform();
$tables = $schemaDiff->newTables + $schemaDiff->changedTables + $schemaDiff->removedTables; $tables = $schemaDiff->newTables + $schemaDiff->changedTables + $schemaDiff->removedTables;
foreach($tables as $tableDiff) { foreach($tables as $tableDiff) {
$tableDiff->name = $platform->quoteIdentifier($tableDiff->name); $tableDiff->name = $platform->quoteIdentifier($tableDiff->name);
} }
return $this->executeSchemaChange($schemaDiff);
//$from = $fromSchema->toSql($conn->getDatabasePlatform());
//$to = $toSchema->toSql($conn->getDatabasePlatform());
//echo($from[9]);
//echo '<br>';
//echo($to[9]);
//var_dump($from, $to);
return self::executeSchemaChange($conn, $schemaDiff);
} }
/** /**
* @brief drop a table * @brief drop a table
* @param \Doctrine\DBAL\Connection $conn
* @param string $tableName the table to drop * @param string $tableName the table to drop
*/ */
public static function dropTable($conn, $tableName) { public function dropTable($tableName) {
$sm = $conn->getSchemaManager(); $sm = $this->conn->getSchemaManager();
$fromSchema = $sm->createSchema(); $fromSchema = $sm->createSchema();
$toSchema = clone $fromSchema; $toSchema = clone $fromSchema;
$toSchema->dropTable($tableName); $toSchema->dropTable($tableName);
$sql = $fromSchema->getMigrateToSql($toSchema, $conn->getDatabasePlatform()); $sql = $fromSchema->getMigrateToSql($toSchema, $this->conn->getDatabasePlatform());
$conn->execute($sql); $this->conn->execute($sql);
} }
/** /**
* remove all tables defined in a database structure xml file * remove all tables defined in a database structure xml file
* @param \Doctrine\DBAL\Connection $conn
* @param string $file the xml file describing the tables * @param string $file the xml file describing the tables
*/ */
public static function removeDBStructure($conn, $file) { public function removeDBStructure($file) {
$schemaReader = new \OC\DB\MDB2SchemaReader(\OC_Config::getObject(), $conn->getDatabasePlatform()); $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
$fromSchema = $schemaReader->loadSchemaFromFile($file); $fromSchema = $schemaReader->loadSchemaFromFile($file);
$toSchema = clone $fromSchema; $toSchema = clone $fromSchema;
foreach($toSchema->getTables() as $table) { foreach($toSchema->getTables() as $table) {
@ -109,42 +111,40 @@ class OC_DB_Schema {
} }
$comparator = new \Doctrine\DBAL\Schema\Comparator(); $comparator = new \Doctrine\DBAL\Schema\Comparator();
$schemaDiff = $comparator->compare($fromSchema, $toSchema); $schemaDiff = $comparator->compare($fromSchema, $toSchema);
self::executeSchemaChange($conn, $schemaDiff); $this->executeSchemaChange($schemaDiff);
} }
/** /**
* @brief replaces the ownCloud tables with a new set * @brief replaces the ownCloud tables with a new set
* @param \Doctrine\DBAL\Connection $conn
* @param $file string path to the MDB2 xml db export file * @param $file string path to the MDB2 xml db export file
*/ */
public static function replaceDB( $conn, $file ) { public function replaceDB( $file ) {
$apps = OC_App::getAllApps(); $apps = \OC_App::getAllApps();
self::beginTransaction(); $this->conn->beginTransaction();
// Delete the old tables // Delete the old tables
self::removeDBStructure( $conn, OC::$SERVERROOT . '/db_structure.xml' ); $this->removeDBStructure( OC::$SERVERROOT . '/db_structure.xml' );
foreach($apps as $app) { foreach($apps as $app) {
$path = OC_App::getAppPath($app).'/appinfo/database.xml'; $path = \OC_App::getAppPath($app).'/appinfo/database.xml';
if(file_exists($path)) { if(file_exists($path)) {
self::removeDBStructure( $conn, $path ); $this->removeDBStructure( $path );
} }
} }
// Create new tables // Create new tables
self::commit(); $this->conn->commit();
} }
/** /**
* @param \Doctrine\DBAL\Connection $conn
* @param \Doctrine\DBAL\Schema\Schema $schema * @param \Doctrine\DBAL\Schema\Schema $schema
* @return bool * @return bool
*/ */
private static function executeSchemaChange($conn, $schema) { private function executeSchemaChange($schema) {
$conn->beginTransaction(); $this->conn->beginTransaction();
foreach($schema->toSql($conn->getDatabasePlatform()) as $sql) { foreach($schema->toSql($this->conn->getDatabasePlatform()) as $sql) {
$conn->query($sql); $this->conn->query($sql);
} }
$conn->commit(); $this->conn->commit();
return true; return true;
} }
} }