From 31dcf99e618ac34c42b40eb5b95e9e1f1af6064e Mon Sep 17 00:00:00 2001 From: Alexei Sorokin Date: Thu, 23 Jul 2020 18:12:01 +0300 Subject: [PATCH] [DATABASE] Make unprefixed schema.php a bit more DBMS-neutral --- lib/database/mysqlschema.php | 32 +++++++++++++++++++++++++ lib/database/pgsqlschema.php | 45 ------------------------------------ lib/database/schema.php | 43 +++++++++++++++++++++++++--------- 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/lib/database/mysqlschema.php b/lib/database/mysqlschema.php index f86abf26b9..4572467937 100644 --- a/lib/database/mysqlschema.php +++ b/lib/database/mysqlschema.php @@ -379,6 +379,25 @@ class MysqlSchema extends Schema return "{$tableName}_{$columnName}_idx"; } + /** + * Append phrase(s) to an array of partial ALTER TABLE chunks in order + * to alter the given column from its old state to a new one. + * + * @param array $phrase + * @param string $columnName + * @param array $old previous column definition as found in DB + * @param array $cd current column definition + */ + public function appendAlterModifyColumn( + array &$phrase, + string $columnName, + array $old, + array $cd + ): void { + $phrase[] = 'MODIFY COLUMN ' . $this->quoteIdentifier($columnName) + . ' ' . $this->columnSql($columnName, $cd); + } + /** * MySQL doesn't take 'DROP CONSTRAINT', need to treat primary keys as * if they were indexes here, but can use 'PRIMARY KEY' special name. @@ -427,6 +446,19 @@ class MysqlSchema extends Schema } } + /** + * Append an SQL statement to drop an index from a table. + * Note that in MariaDB index names are relation-specific. + * + * @param array $statements + * @param string $table + * @param string $name + */ + public function appendDropIndex(array &$statements, $table, $name) + { + $statements[] = "DROP INDEX {$name} ON {$this->quoteIdentifier($table)}"; + } + private function isNumericType(array $cd): bool { $ints = array_map( diff --git a/lib/database/pgsqlschema.php b/lib/database/pgsqlschema.php index c47728865b..046a3bd43d 100644 --- a/lib/database/pgsqlschema.php +++ b/lib/database/pgsqlschema.php @@ -316,57 +316,12 @@ class PgsqlSchema extends Schema return implode(' ', $line); } - /** - * Append phrase(s) to an array of partial ALTER TABLE chunks in order - * to alter the given column from its old state to a new one. - * - * @param array $phrase - * @param string $columnName - * @param array $old previous column definition as found in DB - * @param array $cd current column definition - */ - public function appendAlterModifyColumn(array &$phrase, $columnName, array $old, array $cd) - { - $prefix = 'ALTER COLUMN ' . $this->quoteIdentifier($columnName) . ' '; - - $oldType = $this->typeAndSize($columnName, $old); - $newType = $this->typeAndSize($columnName, $cd); - if ($oldType != $newType) { - $phrase[] = $prefix . 'TYPE ' . $newType; - } - - if (!empty($old['not null']) && empty($cd['not null'])) { - $phrase[] = $prefix . 'DROP NOT NULL'; - } elseif (empty($old['not null']) && !empty($cd['not null'])) { - $phrase[] = $prefix . 'SET NOT NULL'; - } - - if (isset($old['default']) && !isset($cd['default'])) { - $phrase[] = $prefix . 'DROP DEFAULT'; - } elseif (!isset($old['default']) && isset($cd['default'])) { - $phrase[] = $prefix . 'SET DEFAULT ' . $this->quoteDefaultValue($cd); - } - } - public function appendAlterDropPrimary(array &$phrase, string $tableName) { // name hack -- is this reliable? $phrase[] = 'DROP CONSTRAINT ' . $this->quoteIdentifier($tableName . '_pkey'); } - /** - * Append an SQL statement to drop an index from a table. - * Note that in PostgreSQL, index names are DB-unique. - * - * @param array $statements - * @param string $table - * @param string $name - */ - public function appendDropIndex(array &$statements, $table, $name) - { - $statements[] = "DROP INDEX $name"; - } - public function mapType($column) { $map = [ diff --git a/lib/database/schema.php b/lib/database/schema.php index 64d53d2330..2950b54a9b 100644 --- a/lib/database/schema.php +++ b/lib/database/schema.php @@ -311,7 +311,7 @@ class Schema */ public function appendDropIndex(array &$statements, $table, $name) { - $statements[] = "DROP INDEX $name ON " . $this->quoteIdentifier($table); + $statements[] = "DROP INDEX {$name}"; } public function buildIndexList(array $def) @@ -406,10 +406,10 @@ class Schema { global $_PEAR; - $res = $this->conn->query( - 'ALTER TABLE ' . $this->quoteIdentifier($table) . - ' DROP INDEX ' . $name - ); + $statements = []; + $this->appendDropIndex($statements, $table, $name); + + $res = $this->conn->query(implode(";\n", $statements)); if ($_PEAR->isError($res)) { PEAR_ErrorToPEAR_Exception($res); @@ -448,6 +448,7 @@ class Schema * Modifies a column in the schema. * * The name must match an existing column and table. + * @fixme Relies on MODIFY COLUMN, which is specific to MariaDB/MySQL * * @param string $table name of the table * @param ColumnDef $columndef new definition of the column. @@ -724,12 +725,32 @@ class Schema * @param array $old previous column definition as found in DB * @param array $cd current column definition */ - public function appendAlterModifyColumn(array &$phrase, string $columnName, array $old, array $cd) - { - $phrase[] = 'MODIFY COLUMN ' . - $this->quoteIdentifier($columnName) . - ' ' . - $this->columnSql($columnName, $cd); + public function appendAlterModifyColumn( + array &$phrase, + string $columnName, + array $old, + array $cd + ): void { + $prefix = 'ALTER COLUMN ' . $this->quoteIdentifier($columnName); + + // @fixme TYPE is a PostgreSQL extension + $oldType = $this->typeAndSize($columnName, $old); + $newType = $this->typeAndSize($columnName, $cd); + if ($oldType !== $newType) { + $phrase[] = $prefix . ' TYPE ' . $newType; + } + + if (!($old['not null'] ?? false) && ($cd['not null'] ?? false)) { + $phrase[] = $prefix . ' SET NOT NULL'; + } elseif (($old['not null'] ?? false) && !($cd['not null'] ?? false)) { + $phrase[] = $prefix . ' DROP NOT NULL'; + } + + if (!($old['default'] ?? false) && ($cd['default'] ?? false)) { + $phrase[] = $prefix . ' SET DEFAULT ' . $this->quoteDefaultValue($cd); + } elseif (($old['default'] ?? false) && !($cd['default'] ?? false)) { + $phrase[] = $prefix . ' DROP DEFAULT'; + } } /**