X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fmysqlschema.php;h=e284d1eb1851542ff573aff36cc77745f80b710b;hb=586fb5a5175d7a10f5f78dd026434e48202e5451;hp=937c20ea8baa87fd4be049fed5b4b95b09790acc;hpb=e7c7fd39fc948f1169512916077185dd29973b60;p=quix0rs-gnu-social.git diff --git a/lib/mysqlschema.php b/lib/mysqlschema.php index 937c20ea8b..e284d1eb18 100644 --- a/lib/mysqlschema.php +++ b/lib/mysqlschema.php @@ -58,10 +58,10 @@ class MysqlSchema extends Schema * @return Schema the (single) Schema object */ - static function get() + static function get($conn = null) { if (empty(self::$_single)) { - self::$_single = new Schema(); + self::$_single = new Schema($conn); } return self::$_single; } @@ -117,9 +117,14 @@ class MysqlSchema extends Schema $field['not null'] = true; } if ($row['COLUMN_DEFAULT'] !== null) { - $field['default'] = $row['COLUMN_DEFAULT']; - if ($this->isNumericType($type)) { - $field['default'] = intval($field['default']); + // Hack for timestamp cols + if ($type == 'timestamp' && $row['COLUMN_DEFAULT'] == 'CURRENT_TIMESTAMP') { + // skip + } else { + $field['default'] = $row['COLUMN_DEFAULT']; + if ($this->isNumericType($type)) { + $field['default'] = intval($field['default']); + } } } if ($row['COLUMN_KEY'] !== null) { @@ -239,6 +244,20 @@ class MysqlSchema extends Schema return $this->fetchQueryData($sql); } + /** + * 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) + { + $statements[] = "CREATE FULLTEXT INDEX $name ON $table " . $this->buildIndexList($def); + } + /** * Close out a 'create table' SQL statement. * @@ -246,12 +265,21 @@ class MysqlSchema extends Schema * @param array $def * @return string; * - * @fixme ENGINE may need to be set differently in some cases, - * such as to support fulltext index. */ function endCreateTable($name, array $def) { - return ") ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin"; + $engine = $this->preferredEngine($def); + return ") ENGINE=$engine CHARACTER SET utf8mb4 COLLATE utf8mb4_bin"; + } + + function preferredEngine($def) + { + /* MyISAM is no longer required for fulltext indexes, fortunately + if (!empty($def['fulltext indexes'])) { + return 'MyISAM'; + } + */ + return 'InnoDB'; } /** @@ -270,6 +298,16 @@ class MysqlSchema extends Schema return "{$tableName}_{$columnName}_idx"; } + /** + * MySQL doesn't take 'DROP CONSTRAINT', need to treat primary keys as + * if they were indexes here, but can use 'PRIMARY KEY' special name. + * + * @param array $phrase + */ + function appendAlterDropPrimary(array &$phrase) + { + $phrase[] = 'DROP PRIMARY KEY'; + } /** * MySQL doesn't take 'DROP CONSTRAINT', need to treat unique keys as @@ -287,18 +325,20 @@ class MysqlSchema extends Schema * Throw some table metadata onto the ALTER TABLE if we have a mismatch * in expected type, collation. */ - function appendAlterExtras(array &$phrase, $tableName) + function appendAlterExtras(array &$phrase, $tableName, array $def) { // Check for table properties: make sure we're using a sane // engine type and charset/collation. // @fixme make the default engine configurable? $oldProps = $this->getTableProperties($tableName, array('ENGINE', 'TABLE_COLLATION')); - if (strtolower($oldProps['ENGINE']) != 'innodb') { - $phrase[] = 'ENGINE=InnoDB'; + $engine = $this->preferredEngine($def); + if (strtolower($oldProps['ENGINE']) != strtolower($engine)) { + $phrase[] = "ENGINE=$engine"; } - if (strtolower($oldProps['TABLE_COLLATION']) != 'utf8_bin') { - $phrase[] = 'DEFAULT CHARSET=utf8'; - $phrase[] = 'COLLATE=utf8_bin'; + if (strtolower($oldProps['TABLE_COLLATION']) != 'utf8mb4_bin') { + $phrase[] = 'CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin'; + $phrase[] = 'DEFAULT CHARACTER SET = utf8mb4'; + $phrase[] = 'DEFAULT COLLATE = utf8mb4_bin'; } } @@ -346,7 +386,7 @@ class MysqlSchema extends Schema $map = array('serial' => 'int', 'integer' => 'int', 'numeric' => 'decimal'); - + $type = $column['type']; if (isset($map[$type])) { $type = $map[$type]; @@ -372,7 +412,14 @@ class MysqlSchema extends Schema $vals = array_map(array($this, 'quote'), $column['enum']); return 'enum(' . implode(',', $vals) . ')'; } else if ($this->_isString($column)) { - return parent::typeAndSize($column) . ' CHARSET utf8'; + $col = parent::typeAndSize($column); + if (!empty($column['charset'])) { + $col .= ' CHARSET ' . $column['charset']; + } + if (!empty($column['collate'])) { + $col .= ' COLLATE ' . $column['collate']; + } + return $col; } else { return parent::typeAndSize($column); } @@ -389,13 +436,32 @@ class MysqlSchema extends Schema */ function filterDef(array $tableDef) { + $version = $this->conn->getVersion(); foreach ($tableDef['fields'] as $name => &$col) { if ($col['type'] == 'serial') { $col['type'] = 'int'; $col['auto_increment'] = true; } - if ($col['type'] == 'datetime' && isset($col['default']) && $col['default'] == 'CURRENT_TIMESTAMP') { - $col['type'] = 'timestamp'; + + // Avoid invalid date errors in MySQL 5.7+ + if ($col['type'] == 'timestamp' && !isset($col['default']) + && $version >= 50605) { + $col['default'] = 'CURRENT_TIMESTAMP'; + } + if ($col['type'] == 'datetime') { + // Avoid invalid date errors in MySQL 5.7+ + if (!isset($col['default']) && $version >= 50605) { + $col['default'] = 'CURRENT_TIMESTAMP'; + } + + // If we are using MySQL 5.5, convert datetime to timestamp if + // default value is CURRENT_TIMESTAMP. Not needed for MySQL 5.6+ + // and MariaDB 10.0+ + if (isset($col['default']) + && $col['default'] == 'CURRENT_TIMESTAMP' + && $version < 50605) { + $col['type'] = 'timestamp'; + } } $col['type'] = $this->mapType($col); unset($col['size']);