This repository has been archived on 2026-07-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
espocrm-base/application/Espo/Core/Utils/Database/Schema.php
T
2013-12-20 18:34:34 +02:00

185 lines
4.1 KiB
PHP

<?php
namespace Espo\Core\Utils\Database;
use \Doctrine\DBAL\Types\Type;
class Schema
{
private $config;
private $metadata;
private $fileManager;
private $comparator;
private $converter;
private $connection;
public function __construct(\Espo\Core\Utils\Config $config, \Espo\Core\Utils\Metadata $metadata, \Espo\Core\Utils\File\Manager $fileManager)
{
$this->config = $config;
$this->metadata = $metadata;
$this->fileManager = $fileManager;
$this->comparator = new \Doctrine\DBAL\Schema\Comparator();
$this->initFieldTypes();
$this->converter = new \Espo\Core\Utils\Database\Converter($this->metadata);
}
protected function getConfig()
{
return $this->config;
}
protected function getMetadata()
{
return $this->metadata;
}
protected function getFileManager()
{
return $this->fileManager;
}
protected function getComparator()
{
return $this->comparator;
}
protected function getConverter()
{
return $this->converter;
}
public function getPlatform()
{
return $this->getConnection()->getDatabasePlatform();
}
public function getConnection()
{
if (isset($this->connection)) {
return $this->connection;
}
$dbalConfig = new \Doctrine\DBAL\Configuration();
$connectionParams = (array) $this->getConfig()->get('database');
$this->connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $dbalConfig);
return $this->connection;
}
protected function initFieldTypes()
{
$typePaths = array(
'Espo/Core/Utils/Database/FieldTypes',
'Espo/Custom/Core/Utils/Database/FieldTypes',
);
foreach($typePaths as $path) {
$typeList = $this->getFileManager()->getFileList('application/'.$path, false, '\.php$');
if ($typeList !== false) {
foreach($typeList as $name) {
$typeName = preg_replace('/\.php$/i', '', $name);
$dbalTypeName = strtolower($typeName);
$class = \Espo\Core\Utils\Util::toFormat($path, '\\').'\\'.$typeName;
if( ! Type::hasType($dbalTypeName) ) {
Type::addType($dbalTypeName, $class);
} else {
Type::overrideType($dbalTypeName, $class);
}
$dbTypeName = method_exists($class, 'getDbTypeName') ? $class::getDbTypeName() : $dbalTypeName;
$this->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping($dbTypeName, $dbalTypeName);
}
}
}
}
/*
* Rebuild database schema
*/
public function rebuild()
{
if ($this->getConverter()->process() === false) {
return false;
}
$currentSchema = $this->getCurrentSchema();
$metadataSchema = $this->getConverter()->getSchemaFromMetadata();
$queries = $this->getDiffSql($currentSchema, $metadataSchema);
$result = true;
$connection = $this->getConnection();
foreach ($queries as $sql) {
$GLOBALS['log']->add('DEBUG', 'SCHEMA, Execute Query: '.$sql);
try {
$result &= (bool) $connection->executeQuery($sql);
} catch (\Exception $e) {
$GLOBALS['log']->add('EXCEPTION', 'Rebuild database fault: '.$e);
$result = false;
}
}
return (bool) $result;
}
/*
* Get current database schema
*
* @return \Doctrine\DBAL\Schema\Schema
*/
protected function getCurrentSchema()
{
return $this->getConnection()->getSchemaManager()->createSchema();
}
/*
* Get SQL queries of database schema
*
* @params \Doctrine\DBAL\Schema\Schema $schema
*
* @return array - array of SQL queries
*/
public function toSql(\Doctrine\DBAL\Schema\SchemaDiff $schema) //Doctrine\DBAL\Schema\SchemaDiff | \Doctrine\DBAL\Schema\Schema
{
return $schema->toSaveSql($this->getPlatform());
//return $schema->toSql($this->getPlatform()); //it can return with DROP TABLE
}
/*
* Get SQL queries to get from one to another schema
*
* @return array - array of SQL queries
*/
public function getDiffSql(\Doctrine\DBAL\Schema\Schema $fromSchema, \Doctrine\DBAL\Schema\Schema $toSchema)
{
$schemaDiff = $this->getComparator()->compare($fromSchema, $toSchema);
return $this->toSql($schemaDiff); //$schemaDiff->toSql($this->getPlatform());
}
}