|
@@ -59,7 +59,7 @@ class Mysql
|
|
|
{
|
|
|
$this->db = $db;
|
|
|
|
|
|
- $this->testStr($prefix);
|
|
|
+ $this->nameCheck($prefix);
|
|
|
|
|
|
$this->dbPrefix = $prefix;
|
|
|
}
|
|
@@ -73,9 +73,9 @@ class Mysql
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Проверяет строку на допустимые символы
|
|
|
+ * Проверяет имя таблицы/индекса/поля на допустимые символы
|
|
|
*/
|
|
|
- protected function testStr(string $str): void
|
|
|
+ protected function nameCheck(string $str): void
|
|
|
{
|
|
|
if (\preg_match('%[^a-zA-Z0-9_]%', $str)) {
|
|
|
throw new PDOException("Name '{$str}' have bad characters.");
|
|
@@ -89,11 +89,11 @@ class Mysql
|
|
|
{
|
|
|
foreach ($arr as &$value) {
|
|
|
if (\preg_match('%^(.*)\s*(\(\d+\))$%', $value, $matches)) {
|
|
|
- $this->testStr($matches[1]);
|
|
|
+ $this->nameCheck($matches[1]);
|
|
|
|
|
|
$value = "`{$matches[1]}`{$matches[2]}";
|
|
|
} else {
|
|
|
- $this->testStr($value);
|
|
|
+ $this->nameCheck($value);
|
|
|
|
|
|
$value = "`{$value}`";
|
|
|
}
|
|
@@ -128,6 +128,41 @@ class Mysql
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Формирует строку для одного поля таблицы
|
|
|
+ */
|
|
|
+ protected function buildColumn(string $name, array $data): string
|
|
|
+ {
|
|
|
+ $this->nameCheck($name);
|
|
|
+ // имя и тип
|
|
|
+ $query = '`' . $name . '` ' . $this->replType($data[0]);
|
|
|
+ // не NULL
|
|
|
+ if (empty($data[1])) {
|
|
|
+ $query .= ' NOT NULL';
|
|
|
+ }
|
|
|
+ // значение по умолчанию
|
|
|
+ if (isset($data[2])) {
|
|
|
+ $query .= ' DEFAULT ' . $this->convToStr($data[2]);
|
|
|
+ }
|
|
|
+ // сравнение
|
|
|
+ if (\preg_match('%^(?:CHAR|VARCHAR|TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|ENUM|SET)\b%i', $data[0])) {
|
|
|
+ $query .= ' CHARACTER SET utf8mb4 COLLATE utf8mb4_';
|
|
|
+
|
|
|
+ if (
|
|
|
+ isset($data[3])
|
|
|
+ && \is_string($data[3])
|
|
|
+ ) {
|
|
|
+ $this->nameCheck($data[3]);
|
|
|
+
|
|
|
+ $query .= $data[3];
|
|
|
+ } else {
|
|
|
+ $query .= 'unicode_ci';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $query;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Проверяет наличие таблицы в базе
|
|
|
*/
|
|
@@ -197,40 +232,13 @@ class Mysql
|
|
|
*/
|
|
|
public function createTable(string $table, array $schema, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
+ $this->nameCheck($table);
|
|
|
|
|
|
$table = ($noPrefix ? '' : $this->dbPrefix) . $table;
|
|
|
$query = "CREATE TABLE IF NOT EXISTS `{$table}` (";
|
|
|
|
|
|
foreach ($schema['FIELDS'] as $field => $data) {
|
|
|
- $this->testStr($field);
|
|
|
- // имя и тип
|
|
|
- $query .= "`{$field}` " . $this->replType($data[0]);
|
|
|
- // сравнение
|
|
|
- if (\preg_match('%^(?:CHAR|VARCHAR|TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|ENUM|SET)%i', $data[0])) {
|
|
|
- $query .= ' CHARACTER SET utf8mb4 COLLATE utf8mb4_';
|
|
|
-
|
|
|
- if (
|
|
|
- isset($data[3])
|
|
|
- && \is_string($data[3])
|
|
|
- ) {
|
|
|
- $this->testStr($data[3]);
|
|
|
-
|
|
|
- $query .= $data[3];
|
|
|
- } else {
|
|
|
- $query .= 'unicode_ci';
|
|
|
- }
|
|
|
- }
|
|
|
- // не NULL
|
|
|
- if (empty($data[1])) {
|
|
|
- $query .= ' NOT NULL';
|
|
|
- }
|
|
|
- // значение по умолчанию
|
|
|
- if (isset($data[2])) {
|
|
|
- $query .= ' DEFAULT ' . $this->convToStr($data[2]);
|
|
|
- }
|
|
|
-
|
|
|
- $query .= ', ';
|
|
|
+ $query .= $this->buildColumn($field, $data) . ', ';
|
|
|
}
|
|
|
|
|
|
if (isset($schema['PRIMARY KEY'])) {
|
|
@@ -239,7 +247,7 @@ class Mysql
|
|
|
|
|
|
if (isset($schema['UNIQUE KEYS'])) {
|
|
|
foreach ($schema['UNIQUE KEYS'] as $key => $fields) {
|
|
|
- $this->testStr($key);
|
|
|
+ $this->nameCheck($key);
|
|
|
|
|
|
$query .= "UNIQUE `{$table}_{$key}` (" . $this->replIdxs($fields) . '), ';
|
|
|
}
|
|
@@ -247,7 +255,7 @@ class Mysql
|
|
|
|
|
|
if (isset($schema['INDEXES'])) {
|
|
|
foreach ($schema['INDEXES'] as $index => $fields) {
|
|
|
- $this->testStr($index);
|
|
|
+ $this->nameCheck($index);
|
|
|
|
|
|
$query .= "INDEX `{$table}_{$index}` (" . $this->replIdxs($fields) . '), ';
|
|
|
}
|
|
@@ -279,7 +287,7 @@ class Mysql
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- $this->testStr($engine);
|
|
|
+ $this->nameCheck($engine);
|
|
|
|
|
|
$query = \rtrim($query, ', ') . ") ENGINE={$engine} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
|
|
|
|
|
@@ -291,7 +299,7 @@ class Mysql
|
|
|
*/
|
|
|
public function dropTable(string $table, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
+ $this->nameCheck($table);
|
|
|
|
|
|
$table = ($noPrefix ? '' : $this->dbPrefix) . $table;
|
|
|
|
|
@@ -303,8 +311,8 @@ class Mysql
|
|
|
*/
|
|
|
public function renameTable(string $old, string $new, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($old);
|
|
|
- $this->testStr($new);
|
|
|
+ $this->nameCheck($old);
|
|
|
+ $this->nameCheck($new);
|
|
|
|
|
|
if (
|
|
|
$this->tableExists($new, $noPrefix)
|
|
@@ -324,26 +332,18 @@ class Mysql
|
|
|
*/
|
|
|
public function addField(string $table, string $field, string $type, bool $allowNull, /* mixed */ $default = null, string $after = null, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
- $this->testStr($field);
|
|
|
+ $this->nameCheck($table);
|
|
|
+ $this->nameCheck($field);
|
|
|
|
|
|
if ($this->fieldExists($table, $field, $noPrefix)) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
$table = ($noPrefix ? '' : $this->dbPrefix) . $table;
|
|
|
- $query = "ALTER TABLE `{$table}` ADD `{$field}` " . $this->replType($type);
|
|
|
-
|
|
|
- if (! $allowNull) {
|
|
|
- $query .= ' NOT NULL';
|
|
|
- }
|
|
|
-
|
|
|
- if (null !== $default) {
|
|
|
- $query .= ' DEFAULT ' . $this->convToStr($default);
|
|
|
- }
|
|
|
+ $query = "ALTER TABLE `{$table}` ADD " . $this->buildColumn($field, [$type, $allowNull, $default]);
|
|
|
|
|
|
if (null !== $after) {
|
|
|
- $this->testStr($after);
|
|
|
+ $this->nameCheck($after);
|
|
|
|
|
|
$query .= " AFTER `{$after}`";
|
|
|
}
|
|
@@ -356,22 +356,14 @@ class Mysql
|
|
|
*/
|
|
|
public function alterField(string $table, string $field, string $type, bool $allowNull, /* mixed */ $default = null, string $after = null, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
- $this->testStr($field);
|
|
|
+ $this->nameCheck($table);
|
|
|
+ $this->nameCheck($field);
|
|
|
|
|
|
$table = ($noPrefix ? '' : $this->dbPrefix) . $table;
|
|
|
- $query = "ALTER TABLE `{$table}` MODIFY `{$field}` " . $this->replType($type);
|
|
|
-
|
|
|
- if (! $allowNull) {
|
|
|
- $query .= ' NOT NULL';
|
|
|
- }
|
|
|
-
|
|
|
- if (null !== $default) {
|
|
|
- $query .= ' DEFAULT ' . $this->convToStr($default);
|
|
|
- }
|
|
|
+ $query = "ALTER TABLE `{$table}` MODIFY " . $this->buildColumn($field, [$type, $allowNull, $default]);
|
|
|
|
|
|
if (null !== $after) {
|
|
|
- $this->testStr($after);
|
|
|
+ $this->nameCheck($after);
|
|
|
|
|
|
$query .= " AFTER `{$after}`";
|
|
|
}
|
|
@@ -384,8 +376,8 @@ class Mysql
|
|
|
*/
|
|
|
public function dropField(string $table, string $field, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
- $this->testStr($field);
|
|
|
+ $this->nameCheck($table);
|
|
|
+ $this->nameCheck($field);
|
|
|
|
|
|
if (! $this->fieldExists($table, $field, $noPrefix)) {
|
|
|
return true;
|
|
@@ -401,9 +393,9 @@ class Mysql
|
|
|
*/
|
|
|
public function renameField(string $table, string $old, string $new, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
- $this->testStr($old);
|
|
|
- $this->testStr($new);
|
|
|
+ $this->nameCheck($table);
|
|
|
+ $this->nameCheck($old);
|
|
|
+ $this->nameCheck($new);
|
|
|
|
|
|
if (
|
|
|
$this->fieldExists($table, $new, $noPrefix)
|
|
@@ -431,15 +423,7 @@ class Mysql
|
|
|
$allowNull = 'YES' == $result['IS_NULLABLE'];
|
|
|
$default = $result['COLUMN_DEFAULT'];
|
|
|
|
|
|
- $query = "ALTER TABLE `{$table}` CHANGE COLUMN `{$old}` `{$new}` " . $this->replType($type);
|
|
|
-
|
|
|
- if (! $allowNull) {
|
|
|
- $query .= ' NOT NULL';
|
|
|
- }
|
|
|
-
|
|
|
- if (null !== $default) {
|
|
|
- $query .= ' DEFAULT ' . $this->convToStr($default);
|
|
|
- }
|
|
|
+ $query = "ALTER TABLE `{$table}` CHANGE COLUMN `{$old}` " . $this->buildColumn($new, [$type, $allowNull, $default]);
|
|
|
|
|
|
return false !== $this->db->exec($query);
|
|
|
}
|
|
@@ -449,7 +433,7 @@ class Mysql
|
|
|
*/
|
|
|
public function addIndex(string $table, string $index, array $fields, bool $unique = false, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
+ $this->nameCheck($table);
|
|
|
|
|
|
if ($this->indexExists($table, $index, $noPrefix)) {
|
|
|
return true;
|
|
@@ -463,7 +447,7 @@ class Mysql
|
|
|
} else {
|
|
|
$index = $table . '_' . $index;
|
|
|
|
|
|
- $this->testStr($index);
|
|
|
+ $this->nameCheck($index);
|
|
|
|
|
|
if ($unique) {
|
|
|
$query .= "UNIQUE `{$index}`";
|
|
@@ -482,7 +466,7 @@ class Mysql
|
|
|
*/
|
|
|
public function dropIndex(string $table, string $index, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
+ $this->nameCheck($table);
|
|
|
|
|
|
if (! $this->indexExists($table, $index, $noPrefix)) {
|
|
|
return true;
|
|
@@ -496,7 +480,7 @@ class Mysql
|
|
|
} else {
|
|
|
$index = $table . '_' . $index;
|
|
|
|
|
|
- $this->testStr($index);
|
|
|
+ $this->nameCheck($index);
|
|
|
|
|
|
$query .= "DROP INDEX `{$index}`";
|
|
|
}
|
|
@@ -509,7 +493,7 @@ class Mysql
|
|
|
*/
|
|
|
public function truncateTable(string $table, bool $noPrefix = false): bool
|
|
|
{
|
|
|
- $this->testStr($table);
|
|
|
+ $this->nameCheck($table);
|
|
|
|
|
|
$table = ($noPrefix ? '' : $this->dbPrefix) . $table;
|
|
|
|