X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fschema.php;h=94cde28f9d4692610a5b00cafd11c693ca61f1b5;hb=627d84a1e2db2aca5d2ce1272f6e83fb7faa8ad2;hp=c32e6b5230ccb39eb6210e0a05a871a532151d47;hpb=a67160e01ecd320b263923cd0a69a68e946a1937;p=quix0rs-gnu-social.git diff --git a/lib/schema.php b/lib/schema.php index c32e6b5230..94cde28f9d 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -107,9 +107,11 @@ class Schema { $td = $this->getTableDef($table); - foreach ($td->columns as $cd) { - if ($cd->name == $column) { - return $cd; + if (!empty($td) && !empty($td->columns)) { + foreach ($td->columns as $cd) { + if ($cd->name == $column) { + return $cd; + } } } @@ -142,6 +144,7 @@ class Schema */ public function buildCreateTable($name, $def) { + $def = $this->validateDef($name, $def); $def = $this->filterDef($def); $sql = array(); @@ -167,17 +170,24 @@ class Schema } } - // Multi-value indexes are advisory and for best portability - // should be created as separate statements. + // Wrap the CREATE TABLE around the main body chunks... $statements = array(); $statements[] = $this->startCreateTable($name, $def) . "\n" . implode($sql, ",\n") . "\n" . $this->endCreateTable($name, $def); + + // Multi-value indexes are advisory and for best portability + // should be created as separate statements. if (!empty($def['indexes'])) { foreach ($def['indexes'] as $col => $colDef) { $this->appendCreateIndex($statements, $name, $col, $colDef); } } + if (!empty($def['fulltext indexes'])) { + foreach ($def['fulltext indexes'] as $col => $colDef) { + $this->appendCreateFulltextIndex($statements, $name, $col, $colDef); + } + } return $statements; } @@ -253,6 +263,9 @@ class Schema */ function appendForeignKeyDef(array &$sql, $name, array $def) { + if (count($def) != 2) { + throw new Exception("Invalid foreign key def for $name: " . var_export($def, true)); + } list($refTable, $map) = $def; $srcCols = array_keys($map); $refCols = array_values($map); @@ -278,6 +291,20 @@ class Schema $statements[] = "CREATE INDEX $name ON $table " . $this->buildIndexList($def); } + /** + * Append an SQL statement with an index definition for a full-text search + * index over one or more columns on a table. + * + * @param array $statements + * @param string $table + * @param string $name + * @param array $def + */ + function appendCreateFulltextIndex(array &$statements, $table, $name, array $def) + { + throw new Exception("Fulltext index not supported in this database"); + } + /** * Append an SQL statement to drop an index from a table. * @@ -318,9 +345,11 @@ class Schema public function dropTable($name) { + global $_PEAR; + $res = $this->conn->query("DROP TABLE $name"); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); } @@ -345,6 +374,8 @@ class Schema public function createIndex($table, $columnNames, $name=null) { + global $_PEAR; + if (!is_array($columnNames)) { $columnNames = array($columnNames); } @@ -357,7 +388,7 @@ class Schema "ADD INDEX $name (". implode(",", $columnNames).")"); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); } @@ -375,9 +406,11 @@ class Schema public function dropIndex($table, $name) { + global $_PEAR; + $res = $this->conn->query("ALTER TABLE $table DROP INDEX $name"); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); } @@ -396,11 +429,13 @@ class Schema public function addColumn($table, $columndef) { + global $_PEAR; + $sql = "ALTER TABLE $table ADD COLUMN " . $this->_columnSql($columndef); $res = $this->conn->query($sql); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); } @@ -420,12 +455,14 @@ class Schema public function modifyColumn($table, $columndef) { + global $_PEAR; + $sql = "ALTER TABLE $table MODIFY COLUMN " . $this->_columnSql($columndef); $res = $this->conn->query($sql); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); } @@ -445,11 +482,13 @@ class Schema public function dropColumn($table, $columnName) { + global $_PEAR; + $sql = "ALTER TABLE $table DROP COLUMN $columnName"; $res = $this->conn->query($sql); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); } @@ -486,6 +525,8 @@ class Schema */ function runSqlSet(array $statements) { + global $_PEAR; + $ok = true; foreach ($statements as $sql) { if (defined('DEBUG_INSTALLER')) { @@ -493,7 +534,7 @@ class Schema } $res = $this->conn->query($sql); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); } } @@ -517,7 +558,7 @@ class Schema * @return array of SQL statements */ - function buildEnsureTable($tableName, $def) + function buildEnsureTable($tableName, array $def) { try { $old = $this->getTableDef($tableName); @@ -527,6 +568,7 @@ class Schema // Filter the DB-independent table definition to match the current // database engine's features and limitations. + $def = $this->validateDef($tableName, $def); $def = $this->filterDef($def); $statements = array(); @@ -534,12 +576,18 @@ class Schema $uniques = $this->diffArrays($old, $def, 'unique keys'); $indexes = $this->diffArrays($old, $def, 'indexes'); $foreign = $this->diffArrays($old, $def, 'foreign keys'); + $fulltext = $this->diffArrays($old, $def, 'fulltext indexes'); // Drop any obsolete or modified indexes ahead... foreach ($indexes['del'] + $indexes['mod'] as $indexName) { $this->appendDropIndex($statements, $tableName, $indexName); } + // Drop any obsolete or modified fulltext indexes ahead... + foreach ($fulltext['del'] + $fulltext['mod'] as $indexName) { + $this->appendDropIndex($statements, $tableName, $indexName); + } + // For efficiency, we want this all in one // query, instead of using our methods. @@ -553,6 +601,10 @@ class Schema $this->appendAlterDropUnique($phrase, $keyName); } + if (isset($old['primary key']) && (!isset($def['primary key']) || $def['primary key'] != $old['primary key'])) { + $this->appendAlterDropPrimary($phrase); + } + foreach ($fields['add'] as $columnName) { $this->appendAlterAddColumn($phrase, $columnName, $def['fields'][$columnName]); @@ -568,6 +620,10 @@ class Schema $this->appendAlterDropColumn($phrase, $columnName); } + if (isset($def['primary key']) && (!isset($old['primary key']) || $old['primary key'] != $def['primary key'])) { + $this->appendAlterAddPrimary($phrase, $def['primary key']); + } + foreach ($uniques['mod'] + $uniques['add'] as $keyName) { $this->appendAlterAddUnique($phrase, $keyName, $def['unique keys'][$keyName]); } @@ -576,7 +632,7 @@ class Schema $this->appendAlterAddForeign($phrase, $keyName, $def['foreign keys'][$keyName]); } - $this->appendAlterExtras($phrase, $tableName); + $this->appendAlterExtras($phrase, $tableName, $def); if (count($phrase) > 0) { $sql = 'ALTER TABLE ' . $tableName . ' ' . implode(",\n", $phrase); @@ -588,6 +644,11 @@ class Schema $this->appendCreateIndex($statements, $tableName, $indexName, $def['indexes'][$indexName]); } + foreach ($fulltext['mod'] + $fulltext['add'] as $indexName) { + $colDef = $def['fulltext indexes'][$indexName]; + $this->appendCreateFulltextIndex($statements, $tableName, $indexName, $colDef); + } + return $statements; } @@ -687,6 +748,19 @@ class Schema $phrase[] = implode(' ', $sql); } + function appendAlterAddPrimary(array &$phrase, array $def) + { + $sql = array(); + $sql[] = 'ADD'; + $this->appendPrimaryKeyDef($sql, $def); + $phrase[] = implode(' ', $sql); + } + + function appendAlterDropPrimary(array &$phrase) + { + $phrase[] = 'DROP CONSTRAINT PRIMARY KEY'; + } + function appendAlterDropUnique(array &$phrase, $keyName) { $phrase[] = 'DROP CONSTRAINT ' . $keyName; @@ -697,7 +771,7 @@ class Schema $phrase[] = 'DROP FOREIGN KEY ' . $keyName; } - function appendAlterExtras(array &$phrase, $tableName) + function appendAlterExtras(array &$phrase, $tableName, array $def) { // no-op } @@ -851,10 +925,10 @@ class Schema * with plugins written for 0.9.x. * * @param string $tableName - * @param array $defs + * @param array $defs: array of ColumnDef objects * @return array */ - function oldToNew($tableName, $defs) + protected function oldToNew($tableName, array $defs) { $table = array(); $prefixes = array( @@ -864,7 +938,6 @@ class Schema 'big', ); foreach ($defs as $cd) { - $cd->addToTableDef($table); $column = array(); $column['type'] = $cd->type; foreach ($prefixes as $prefix) { @@ -883,7 +956,7 @@ class Schema if (!$cd->nullable) { $column['not null'] = true; } - if ($cd->autoincrement) { + if ($cd->auto_increment) { $column['type'] = 'serial'; } if ($cd->default) { @@ -928,6 +1001,31 @@ class Schema return $tableDef; } + /** + * Validate a table definition array, checking for basic structure. + * + * If necessary, converts from an old-style array of ColumnDef objects. + * + * @param string $tableName + * @param array $def: table definition array + * @return array validated table definition array + * + * @throws Exception on wildly invalid input + */ + function validateDef($tableName, array $def) + { + if (isset($def[0]) && $def[0] instanceof ColumnDef) { + $def = $this->oldToNew($tableName, $def); + } + + // A few quick checks :D + if (!isset($def['fields'])) { + throw new Exception("Invalid table definition for $tableName: no fields."); + } + + return $def; + } + function isNumericType($type) { $type = strtolower($type); @@ -943,8 +1041,10 @@ class Schema */ protected function fetchQueryData($sql) { + global $_PEAR; + $res = $this->conn->query($sql); - if (PEAR::isError($res)) { + if ($_PEAR->isError($res)) { throw new Exception($res->getMessage()); }