Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions Core/Base/DataBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -297,17 +297,38 @@ public function getEngine()
*
* @return array
*/
public function getIndexes(string $tableName): array
public function getAllIndexes(string $tableName): array
{
$result = [];
$data = $this->select(self::$engine->getSQL()->sqlIndexes($tableName));
foreach ($data as $row) {
$result[] = ['name' => $row['Key_name'] ?? $row['key_name'] ?? ''];
$result[] = [
'name' => $row['Key_name'] ?? $row['key_name'] ?? '',
'column' => $row['Column_name'] ?? $row['column_name'] ?? '',
];
}

return $result;
}

/**
* Returns an array with the FacturaScripts indexes of a given table.
*
* @param string $tableName
*
* @return array
*/
public function getIndexes(string $tableName): array
{
$result = array_filter($this->getAllIndexes($tableName), function ($dbIdx) {
return false !== strpos($dbIdx['name'], 'fs_');
});

$result = array_values($result);

return $result;
}

/**
* Gets the operator for the database engine
*
Expand Down
3 changes: 2 additions & 1 deletion Core/Base/DataBase/DataBaseQueries.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,11 @@ public function sqlConstraintsExtended(string $tableName): string;
* @param string $tableName
* @param array $columns
* @param array $constraints
* @param array $indexes
*
* @return string
*/
public function sqlCreateTable(string $tableName, array $columns, array $constraints): string;
public function sqlCreateTable(string $tableName, array $columns, array $constraints, array $indexes): string;

/**
* SQL statement to delete a given table column's constraint
Expand Down
31 changes: 29 additions & 2 deletions Core/Base/DataBase/MysqlQueries.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public function sqlAlterColumnDefault(string $tableName, array $colData): string
return $colData['type'] === 'serial' ? '' : $this->sqlAlterModifyColumn($tableName, $colData);
}

public function sqlAddIndex(string $tableName, string $indexName, string $columns): string
{
return 'CREATE INDEX ' . $indexName . ' ON ' . $tableName . ' (' . $columns . ');';
}

/**
* SQL statement to alter a null constraint in a table column
*
Expand Down Expand Up @@ -173,10 +178,11 @@ public function sqlConstraintsExtended(string $tableName): string
* @param string $tableName
* @param array $columns
* @param array $constraints
* @param array $indexes
*
* @return string
*/
public function sqlCreateTable(string $tableName, array $columns, array $constraints): string
public function sqlCreateTable(string $tableName, array $columns, array $constraints, array $indexes): string
{
$fields = '';
foreach ($columns as $col) {
Expand All @@ -189,7 +195,8 @@ public function sqlCreateTable(string $tableName, array $columns, array $constra
$collate = defined('FS_MYSQL_COLLATE') ? FS_MYSQL_COLLATE : 'utf8_bin';
return 'CREATE TABLE ' . $tableName . ' (' . $sql
. $this->sqlTableConstraints($constraints) . ') '
. 'ENGINE=InnoDB DEFAULT CHARSET=' . $charset . ' COLLATE=' . $collate . ';';
. 'ENGINE=InnoDB DEFAULT CHARSET=' . $charset . ' COLLATE=' . $collate . ';'
. $this->sqlTableIndexes($tableName, $indexes);
}

/**
Expand All @@ -215,6 +222,11 @@ public function sqlDropConstraint(string $tableName, array $colData): string
}
}

public function sqlDropIndex(string $tableName, array $colData): string
{
return 'DROP INDEX IF EXISTS ' . $colData['name'] . ' ON ' . $tableName . ';';
}

/**
* SQL statement to drop a given table
*
Expand Down Expand Up @@ -249,6 +261,11 @@ public function sqlLastValue(): string
return 'SELECT LAST_INSERT_ID() as num;';
}

public function sqlRenameColumn(string $tableName, string $old_column, string $new_column): string
{
return 'ALTER TABLE ' . $tableName . ' RENAME COLUMN ' . $old_column . ' TO ' . $new_column . ';';
}

/**
* Generates the needed SQL to establish the given constraints
*
Expand All @@ -269,6 +286,16 @@ public function sqlTableConstraints(array $xmlCons): string
return $this->fixPostgresql($sql);
}

private function sqlTableIndexes(string $tableName, array $xmlIndexes)
{
$sql = '';
foreach ($xmlIndexes as $idx) {
$sql .= ' CREATE INDEX fs_' . $idx['name'] . ' ON ' . $tableName . ' (' . $idx['columns'] . ');';
}

return $sql;
}

/**
* Removes PostgreSQL's problematic code
*
Expand Down
49 changes: 46 additions & 3 deletions Core/Base/DataBase/PostgresqlQueries.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ public function sqlAlterColumnDefault(string $tableName, array $colData): string
return 'ALTER TABLE ' . $tableName . ' ALTER COLUMN ' . $colData['name'] . $action . ';';
}

public function sqlAddIndex(string $tableName, string $indexName, string $columns): string
{
return 'CREATE INDEX ' . $indexName . ' ON ' . $tableName . ' (' . $columns . ');';
}

/**
* SQL statement to alter a null constraint in a table column
*
Expand Down Expand Up @@ -199,10 +204,11 @@ public function sqlConstraintsExtended(string $tableName): string
* @param string $tableName
* @param array $columns
* @param array $constraints
* @param array $indexes
*
* @return string
*/
public function sqlCreateTable(string $tableName, array $columns, array $constraints): string
public function sqlCreateTable(string $tableName, array $columns, array $constraints, array $indexes): string
{
$serials = ['serial', 'bigserial'];
$fields = '';
Expand All @@ -223,7 +229,8 @@ public function sqlCreateTable(string $tableName, array $columns, array $constra
}

return 'CREATE TABLE ' . $tableName . ' (' . substr($fields, 2)
. $this->sqlTableConstraints($constraints) . ');';
. $this->sqlTableConstraints($constraints) . ');'
. $this->sqlTableIndexes($tableName, $indexes);
}

/**
Expand All @@ -239,6 +246,11 @@ public function sqlDropConstraint(string $tableName, array $colData): string
return 'ALTER TABLE ' . $tableName . ' DROP CONSTRAINT ' . $colData['name'] . ';';
}

public function sqlDropIndex(string $tableName, array $colData): string
{
return 'DROP INDEX IF EXISTS ' . $colData['name'] . ';';
}

/**
* SQL statement to drop a given table
*
Expand All @@ -260,7 +272,23 @@ public function sqlDropTable(string $tableName): string
*/
public function sqlIndexes(string $tableName): string
{
return "SELECT indexname as Key_name FROM pg_indexes WHERE tablename = '" . $tableName . "';";
return "SELECT
i.relname AS key_name,
a.attname AS column_name
FROM
pg_class t
JOIN
pg_index ix ON t.oid = ix.indrelid
JOIN
pg_class i ON i.oid = ix.indexrelid
JOIN
pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
WHERE
t.relkind = 'r'
AND t.relname = '" . $tableName . "'
ORDER BY
i.relname,
a.attname;";
}

/**
Expand All @@ -273,6 +301,11 @@ public function sqlLastValue(): string
return 'SELECT lastval() as num;';
}

public function sqlRenameColumn(string $tableName, string $old_column, string $new_column): string
{
return 'ALTER TABLE ' . $tableName . ' RENAME COLUMN ' . $old_column . ' TO ' . $new_column . ';';
}

/**
* Generates the needed SQL to establish the given constraints
*
Expand All @@ -298,4 +331,14 @@ public function sqlTableConstraints(array $xmlCons): string

return $sql;
}

private function sqlTableIndexes(string $tableName, array $xmlIndexes)
{
$sql = '';
foreach ($xmlIndexes as $idx) {
$sql .= ' CREATE INDEX fs_' . $idx['name'] . ' ON ' . $tableName . ' (' . $idx['columns'] . ');';
}

return $sql;
}
}
91 changes: 88 additions & 3 deletions Core/DbUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static function createTable(string $tableName, array $structure = [], str
$structure = self::readTableXml($filePath);
}

$sql = self::sqlTool()->sqlCreateTable($tableName, $structure['columns'], $structure['constraints']) . $sqlAfter;
$sql = self::sqlTool()->sqlCreateTable($tableName, $structure['columns'], $structure['constraints'], $structure['indexes']) . $sqlAfter;
if (self::db()->exec($sql)) {
self::save($tableName);
Tools::log()->debug('table-checked', ['%tableName%' => $tableName]);
Expand Down Expand Up @@ -118,7 +118,9 @@ public static function readTableXml(string $filePath): array
{
$structure = [
'columns' => [],
'constraints' => []
'constraints' => [],
'indexes' => [],
'rename' => [],
];

if (false === file_exists($filePath)) {
Expand Down Expand Up @@ -164,6 +166,28 @@ public static function readTableXml(string $filePath): array
}
}

if (isset($xml->index)) {
foreach ($xml->index as $col) {
$key = (string)$col->name;

$structure['indexes'][$key] = [
'name' => $key,
'columns' => (string)$col->columns
];
}
}

if (isset($xml->rename)) {
foreach ($xml->rename as $col) {
$key = (string)$col->old_column;

$structure['rename'][$key] = [
'old_column' => $key,
'new_column' => (string)$col->new_column
];
}
}

return $structure;
}

Expand Down Expand Up @@ -193,8 +217,11 @@ public static function updateTable(string $tableName, array $structure = []): bo
// compare table columns and constraints against xml definition
$dbCols = self::db()->getColumns($tableName);
$dbCons = self::db()->getConstraints($tableName);
$dbIndexes = self::db()->getIndexes($tableName);
$sql = self::compareColumns($tableName, $structure['columns'], $dbCols) .
self::compareConstraints($tableName, $structure['constraints'], $dbCons);
self::compareConstraints($tableName, $structure['constraints'], $dbCons) .
self::compareIndexes($tableName, $structure['indexes'], $dbIndexes) .
self::renameColums($tableName, $structure['rename'], $dbCols);
if (empty($sql)) {
self::save($tableName);
Tools::log()->debug('table-checked', ['%tableName%' => $tableName]);
Expand Down Expand Up @@ -299,11 +326,69 @@ private static function compareConstraints(string $tableName, array $xmlCons, ar
$sql;
}

private static function compareIndexes(string $tableName, array $xmlIndexes, array $dbIndexes)
{
// Agregamos fs_ al inicio del 'name'
// Así la comparacion es correcta al buscar los indices
foreach ($xmlIndexes as $key => $value) {
if (isset($value['name'])) {
$xmlIndexes[$key]['name'] = 'fs_' . $value['name'];
}
}

$sql = '';

// si no existen indices en el xml, borramos todos lo que existan en la base de datos.
if (empty($xmlIndexes)) {
foreach ($dbIndexes as $dbIdx) {
$sql .= self::sqlTool()->sqlDropIndex($tableName, $dbIdx);
}
return $sql;
}

// remove new indexes
foreach ($dbIndexes as $dbIdx) {
// delete if not found
$column = self::searchInArray($xmlIndexes, 'name', $dbIdx['name']);
if (empty($column)) {
$sql .= self::sqlTool()->sqlDropIndex($tableName, $dbIdx);
}
}

// add new indexes
foreach ($xmlIndexes as $xmlIdx) {
// add if not found
$column = self::searchInArray($dbIndexes, 'name', $xmlIdx['name']);
if (empty($column)) {
$sql .= self::sqlTool()->sqlAddIndex($tableName, $xmlIdx['name'], $xmlIdx['columns']);
}
}

return $sql;
}

private static function compareDataTypes(string $dbType, string $xmlType): bool
{
return self::db()->getEngine()->compareDataTypes($dbType, $xmlType);
}

private static function renameColums(string $tableName, array $xmlRenameColumns, array $dbCols)
{
if (empty($xmlRenameColumns)) {
return '';
}

$sql = '';
foreach ($xmlRenameColumns as $renameColumn) {
$column = self::searchInArray($dbCols, 'name', $renameColumn['old_column']);
if (!empty($column)) {
$sql .= self::sqlTool()->sqlRenameColumn($tableName, $renameColumn['old_column'], $renameColumn['new_column']);
}
}

return $sql;
}

private static function save(string $tableName): void
{
self::$checkedTables[] = $tableName;
Expand Down
Loading
Loading