2012-10-10 18:49:47 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
|
|
|
|
* This file is licensed under the Affero General Public License version 3 or
|
|
|
|
* later.
|
|
|
|
* See the COPYING-README file.
|
|
|
|
*/
|
|
|
|
|
2013-07-29 15:46:20 +00:00
|
|
|
namespace OC\DB;
|
|
|
|
|
2013-08-02 11:19:27 +00:00
|
|
|
class MDB2SchemaManager {
|
2013-07-29 15:46:20 +00:00
|
|
|
/**
|
2013-08-06 13:43:58 +00:00
|
|
|
* @var \OC\DB\Connection $conn
|
2013-07-29 15:46:20 +00:00
|
|
|
*/
|
|
|
|
protected $conn;
|
|
|
|
|
2013-08-02 13:09:50 +00:00
|
|
|
/**
|
2013-08-06 13:43:58 +00:00
|
|
|
* @param \OC\DB\Connection $conn
|
2013-08-02 13:09:50 +00:00
|
|
|
*/
|
|
|
|
public function __construct($conn) {
|
2013-07-29 15:46:20 +00:00
|
|
|
$this->conn = $conn;
|
2013-11-24 22:13:23 +00:00
|
|
|
$this->conn->close();
|
|
|
|
$this->conn->connect();
|
2013-07-29 15:46:20 +00:00
|
|
|
}
|
|
|
|
|
2012-10-10 18:49:47 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* saves database scheme to xml file
|
2012-10-10 18:49:47 +00:00
|
|
|
* @param string $file name of file
|
2013-06-27 21:34:36 +00:00
|
|
|
* @param int|string $mode
|
2012-10-10 18:49:47 +00:00
|
|
|
* @return bool
|
|
|
|
*
|
|
|
|
* TODO: write more documentation
|
|
|
|
*/
|
2013-08-02 13:09:50 +00:00
|
|
|
public function getDbStructure( $file, $mode = MDB2_SCHEMA_DUMP_STRUCTURE) {
|
2013-07-29 15:46:20 +00:00
|
|
|
$sm = $this->conn->getSchemaManager();
|
2012-10-10 18:49:47 +00:00
|
|
|
|
2013-07-29 15:46:20 +00:00
|
|
|
return \OC_DB_MDB2SchemaWriter::saveSchemaToFile($file, $sm);
|
2012-10-10 18:49:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* Creates tables from XML file
|
2012-10-10 18:49:47 +00:00
|
|
|
* @param string $file file to read structure from
|
|
|
|
* @return bool
|
|
|
|
*
|
|
|
|
* TODO: write more documentation
|
|
|
|
*/
|
2013-07-29 15:46:20 +00:00
|
|
|
public function createDbFromStructure( $file ) {
|
2013-08-02 13:09:50 +00:00
|
|
|
$schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
|
2013-07-29 14:33:00 +00:00
|
|
|
$toSchema = $schemaReader->loadSchemaFromFile($file);
|
2013-07-29 15:46:20 +00:00
|
|
|
return $this->executeSchemaChange($toSchema);
|
2012-10-10 18:49:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* update the database scheme
|
2012-10-10 18:49:47 +00:00
|
|
|
* @param string $file file to read structure from
|
2014-02-06 15:30:58 +00:00
|
|
|
* @return string|boolean
|
2012-10-10 18:49:47 +00:00
|
|
|
*/
|
2013-10-17 10:51:30 +00:00
|
|
|
public function updateDbFromStructure($file, $generateSql = false) {
|
2013-07-29 15:46:20 +00:00
|
|
|
$sm = $this->conn->getSchemaManager();
|
2012-10-10 18:49:47 +00:00
|
|
|
$fromSchema = $sm->createSchema();
|
|
|
|
|
2013-08-02 13:09:50 +00:00
|
|
|
$schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
|
2013-07-29 14:33:00 +00:00
|
|
|
$toSchema = $schemaReader->loadSchemaFromFile($file);
|
2012-10-10 18:49:47 +00:00
|
|
|
|
|
|
|
// remove tables we don't know about
|
2013-10-17 12:54:37 +00:00
|
|
|
/** @var $table \Doctrine\DBAL\Schema\Table */
|
2012-10-10 18:49:47 +00:00
|
|
|
foreach($fromSchema->getTables() as $table) {
|
|
|
|
if (!$toSchema->hasTable($table->getName())) {
|
|
|
|
$fromSchema->dropTable($table->getName());
|
|
|
|
}
|
|
|
|
}
|
2013-03-17 16:28:36 +00:00
|
|
|
// remove sequences we don't know about
|
|
|
|
foreach($fromSchema->getSequences() as $table) {
|
|
|
|
if (!$toSchema->hasSequence($table->getName())) {
|
|
|
|
$fromSchema->dropSequence($table->getName());
|
|
|
|
}
|
|
|
|
}
|
2012-10-10 18:49:47 +00:00
|
|
|
|
|
|
|
$comparator = new \Doctrine\DBAL\Schema\Comparator();
|
|
|
|
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
|
|
|
|
|
2013-10-21 19:31:57 +00:00
|
|
|
$platform = $this->conn->getDatabasePlatform();
|
|
|
|
foreach($schemaDiff->changedTables as $tableDiff) {
|
|
|
|
$tableDiff->name = $platform->quoteIdentifier($tableDiff->name);
|
2014-02-26 15:26:16 +00:00
|
|
|
foreach($tableDiff->changedColumns as $column) {
|
|
|
|
$column->oldColumnName = $platform->quoteIdentifier($column->oldColumnName);
|
|
|
|
}
|
2013-10-21 19:31:57 +00:00
|
|
|
}
|
2014-05-19 15:50:53 +00:00
|
|
|
|
2013-10-17 10:51:30 +00:00
|
|
|
if ($generateSql) {
|
|
|
|
return $this->generateChangeScript($schemaDiff);
|
|
|
|
}
|
|
|
|
|
2013-07-29 15:46:20 +00:00
|
|
|
return $this->executeSchemaChange($schemaDiff);
|
2012-10-10 18:49:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* remove all tables defined in a database structure xml file
|
|
|
|
* @param string $file the xml file describing the tables
|
|
|
|
*/
|
2013-07-29 15:46:20 +00:00
|
|
|
public function removeDBStructure($file) {
|
2013-08-02 13:09:50 +00:00
|
|
|
$schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform());
|
2013-07-29 14:33:00 +00:00
|
|
|
$fromSchema = $schemaReader->loadSchemaFromFile($file);
|
2012-10-10 18:49:47 +00:00
|
|
|
$toSchema = clone $fromSchema;
|
2013-10-17 12:54:37 +00:00
|
|
|
/** @var $table \Doctrine\DBAL\Schema\Table */
|
2012-10-10 18:49:47 +00:00
|
|
|
foreach($toSchema->getTables() as $table) {
|
|
|
|
$toSchema->dropTable($table->getName());
|
|
|
|
}
|
|
|
|
$comparator = new \Doctrine\DBAL\Schema\Comparator();
|
|
|
|
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
|
2013-07-29 15:46:20 +00:00
|
|
|
$this->executeSchemaChange($schemaDiff);
|
2012-10-10 18:49:47 +00:00
|
|
|
}
|
|
|
|
|
2013-07-29 14:33:00 +00:00
|
|
|
/**
|
|
|
|
* @param \Doctrine\DBAL\Schema\Schema $schema
|
|
|
|
* @return bool
|
|
|
|
*/
|
2013-07-29 15:46:20 +00:00
|
|
|
private function executeSchemaChange($schema) {
|
|
|
|
$this->conn->beginTransaction();
|
|
|
|
foreach($schema->toSql($this->conn->getDatabasePlatform()) as $sql) {
|
|
|
|
$this->conn->query($sql);
|
2012-10-10 18:49:47 +00:00
|
|
|
}
|
2013-07-29 15:46:20 +00:00
|
|
|
$this->conn->commit();
|
2013-07-29 14:33:00 +00:00
|
|
|
return true;
|
2012-10-10 18:49:47 +00:00
|
|
|
}
|
2013-10-17 10:51:30 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param \Doctrine\DBAL\Schema\Schema $schema
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function generateChangeScript($schema) {
|
|
|
|
|
|
|
|
$script = '';
|
|
|
|
$sqls = $schema->toSql($this->conn->getDatabasePlatform());
|
|
|
|
foreach($sqls as $sql) {
|
|
|
|
$script .= $sql . ';';
|
|
|
|
$script .= PHP_EOL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $script;
|
|
|
|
}
|
2012-10-10 18:49:47 +00:00
|
|
|
}
|