Система управления «Сайт PRO»
Версия 20240107

Класс MySQL

Объект $Data: Cms\Root\Data\MySQL наследует Cms\Site\Data\Base

Драйвер для работы с базой данных MySQL.

Исходный код
class MySQL extends \Cms\Site\Data\Base { … }

Методы

init()

$Data->init();

Открытие соединения с базой данных

Возвращает: true; null

Исходный код
    function init() {
        $Conf = $this->Conf();
        if (!extension_loaded('PDO_mysql')) {
            $this->addError('Невозможно открыть базу данных');
            return;
        }
        try {
            $this->data = new \PDO(
                sprintf('mysql:host=%s;' . (($port = $Conf->get('sql_port')) ? 'port=' . $port . ';' : '') . 'dbname=%s', ($host = $Conf->get('sql_server')) ? $host : 'localhost', $Conf->get('sql_database')),
                $Conf->get('sql_login'),
                $Conf->get('sql_password'),
                array()
            );
        } catch (\PDOException $e) {
            $this->addError('Невозможно открыть базу данных');
            $this->addError($e->getMessage());
            return;
        }
        $this->data->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
        $this->data->query("SET NAMES utf8mb4");
        $this->data->query("SET sql_mode=''");
        $this->database = $database;
        return true;
    }

quote()

$Data->quote($text, $stringNull=true);

Экранирование специальных символов в строке и добавление кавычек

Параметры:

ИмяОписание
$text

строка

$stringNull

конвертировать NULL в пустую строку ''

Возвращает: string

Исходный код
    function quote($text, $stringNull = true) {
        if ($text === null && !$stringNull) return 'NULL';
        if ($this->data instanceof \PDO) return $this->data->quote(strval($text));
        return $this->quoteMySQL(strval($text));
    }

query()

$Data->query($q);

Выполнение запроса и получение результата

Параметры:

ИмяОписание
$q

запрос

Возвращает: object; false

Исходный код
    function query($q) {
        if ($this->data instanceof \PDO) {
            $this->clearError();
            if (func_num_args() > 1) {
                $args = func_get_args();
                array_shift($args);
                $q = $this->queryParamsArrayMySQL($q, $args);
            }
            $this->query = $q;
            try {
                $result = $this->data->query($q);
            } catch (\PDOException $e) {
                $this->addError('Ошибка запроса «' . $q . '»');
                $this->addError($e->getMessage());
                return false;
            }
            if (!$result) {
                $this->addError('Ошибка запроса «' . $q . '»');
                $this->addError(implode(' ', $this->data->errorInfo()));
            }
            return $result;
        }
        return false;
    }

queryParamsArray()

$Data->queryParamsArray($query, $params);

Добавление параметров к запросу

Параметры:

ИмяОписание
$query

запрос

$params

параметры

Возвращает: string

Исходный код
    function queryParamsArray($query, $params) {
        return $this->queryParamsArrayMySQL($query, $params);
    }

numRows()

$Data->numRows(&$result);

Количество строк результата запроса

Параметры:

ИмяОписание
$result

результат запроса

Возвращает: int

Исходный код
    function numRows(&$result) {
        if ($result instanceof \PDOStatement) return $result->rowCount();
        if (is_array($result)) return count($result);
        return 0;
    }

fetch()

$Data->fetch(&$result);

Получение следующей строки результата запроса

Параметры:

ИмяОписание
$result

результат запроса

Возвращает: array; false; null

Исходный код
    function fetch(&$result) {
        if ($result instanceof \PDOStatement) return $result->fetch(\PDO::FETCH_ASSOC);
        if (is_array($result)) return array_shift($result);
        return false;
    }

fetchArray()

$Data->fetchArray(&$result);

Получение следующей строки результата запроса

Параметры:

ИмяОписание
$result

результат запроса

Возвращает: array; false; null

Исходный код
    function fetchArray(&$result) {
        if ($result instanceof \PDOStatement) return $result->fetch(\PDO::FETCH_NUM);
        if (is_array($result)) return array_values(array_shift($result));
        return false;
    }

tables()

$Data->tables();

Список таблиц и их определений

Возвращает: array

Исходный код
    function tables() {
        $r = array();
        if ($result = $this->query("SHOW TABLES")) {
            while ($row = $this->fetch($result)) {
                $table = array_shift($row);
                if ($_result = $this->query("SHOW CREATE TABLE `$table`")) {
                    if ($row = $this->fetch($_result)) {
                        array_shift($row);
                        $r[$table] = array_shift($row);
                    }
                }
            }
        }
        return $r;
    }

fields()

$Data->fields($result);

Получение полей запроса

Параметры:

ИмяОписание
$result

результат запроса

Возвращает: array

Исходный код
    function fields($result) {
        $r = array();
        if (is_array($result)) return array_keys(array_shift(array_values($result)));
        if (!$result instanceof \PDOStatement) $result = $this->query("SELECT * FROM `$result` LIMIT 0");
        if ($result) {
            if ($count = $result->columnCount()) for ($i = 0; $i < $count; $i ++) {
                if ($a = $result->getColumnMeta($i)) {
                    $r[] = $a['name'];
                }
            }
        }
        return $r;
    }

tableExists()

$Data->tableExists(Table $Table);
Исходный код
    function tableExists(Table $Table) {
        if ($this->query("SELECT * FROM `{$Table->getName()}` LIMIT 0")) return true;
        return false;
    }

tableFieldExists()

$Data->tableFieldExists(Field $Field);
Исходный код
    function tableFieldExists(Field $Field) {
        if ($this->query("SELECT `{$Field->getName()}` FROM `{$Field->getTable()}` LIMIT 0")) return true;
        return false;
    }

tablePrimaryKey()

$Data->tablePrimaryKey(Table $Table);
Исходный код
    function tablePrimaryKey(Table $Table) {
        $r = array();
        foreach ($this->getRows("SHOW KEYS FROM `{$Table->getName()}` WHERE `Key_name`='PRIMARY'") as $row) {
            $r[] = $row['Column_name'];
        }
        switch (count($r)) {
            case 0:
                return;
            case 1:
                return $r[0];
            default:
                return $r;
        }
    }

tableUniqueExists()

$Data->tableUniqueExists(Field $Field);
Исходный код
    function tableUniqueExists(Field $Field) {
        if ($this->getRow("SHOW KEYS FROM `{$Field->getTable()}` WHERE `Key_name`={$this->quote($Field->getName())} AND `Non_unique`=0")) return true;
        return false;
    }

tableIndexExists()

$Data->tableIndexExists(Field $Field);
Исходный код
    function tableIndexExists(Field $Field) {
        if ($this->getRow("SHOW KEYS FROM `{$Field->getTable()}` WHERE `Key_name`={$this->quote($Field->getName())}")) return true;
        return false;
    }

tableCreate()

$Data->tableCreate(Table $Table);
Исходный код
    function tableCreate(Table $Table) {
        $query = array();
        foreach ($Table->getEnabledFieldList() as $Field) {
            $_query = array( "`{$Field->getName()}`" );
            if ($type = $Field->getType()) {
                if ($length = $Field->getLength()) {
                    if ($length2 = $Field->getLength2()) {
                        $_query[] = $type . '(' . $length . ', ' . $length2 . ')';
                    } else {
                        $_query[] = $type . '(' . $length . ')';
                    }
                } else {
                    $_query[] = $type;
                }
            }
            if (!$Field->isNull()) {
                $_query[] = 'NOT NULL';
                $default = strval($Field->getDefault());
                if ($default === 'N') {
                    $_query[] = "DEFAULT '0'";
                } elseif ($default === 'ID') {
                    $_query[] = "DEFAULT ''";
                } elseif ($default === 'UUID') {
                    $_query[] = "DEFAULT ''";
                } elseif ($default === 'URL') {
                    $_query[] = "DEFAULT ''";
                } elseif ($default === 'VERSION') {
                    $_query[] = "DEFAULT '1'";
                } elseif ($default === 'ORDER') {
                    $_query[] = "DEFAULT '0'";
                } elseif ($default === 'LOGIN') {
                    $_query[] = "DEFAULT ''";
                } elseif ($default === 'NOW') {
                    $_query[] = "DEFAULT '0000-00-00 00:00:00'";
                } elseif ($default === 'AUTO_INCREMENT') {
                    $_query[] = $default;
                } elseif ($default === 'CURRENT_TIMESTAMP') {
                    $_query[] = 'DEFAULT ' . $default;
                    if ($type === 'timestamp') {
                        $_query[] = 'ON UPDATE CURRENT_TIMESTAMP';
                    }
                } else {
                    $_query[] = 'DEFAULT ' . $this->quote($default);
                }
            }
            $query[] = implode(' ', $_query);
        }
        if ($primary = $Table->getPrimaryKey()) {
            if (is_array($primary)) $query[] = "PRIMARY KEY (`" . implode("`, `", $primary) . "`)";
            else $query[] = "PRIMARY KEY (`" . $primary . "`)";
        }
        foreach ($Table->getEnabledFieldList() as $Field) {
            if ($Field->isUnique()) {
                $query[] = "UNIQUE KEY `{$Field->getName()}` (`{$Field->getName()}`)";
            } elseif ($Field->isIndex()) {
                $query[] = "KEY `{$Field->getName()}` (`{$Field->getName()}`" . (in_array($Field->getType(), array('text', 'longtext')) ? '(255)' : '') . ")";
            }
        }
        $query = "CREATE TABLE `{$Table->getName()}` (" . implode(', ', $query) . ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
        if ($this->query($query)) return true;
        return false;
    }

tableAlter()

$Data->tableAlter(Table $Table);
Исходный код
    function tableAlter(Table $Table) {
        foreach ($Table->getEnabledFieldList() as $Field) {
            if ($this->tableFieldExists($Field)) {
                $this->tableAlterFieldChange($Field);
            } else {
                if (!$this->tableAlterFieldAdd($Field)) return false;
            }
        }
        if ($primary = $Table->getPrimaryKey()) {
            if ($_primary = $this->tablePrimaryKey($Table)) {
                if ($primary !== $_primary) {
                    if (!$this->tableAlterPrimaryKeyDrop($Table)) return false;
                    if (!$this->tableAlterPrimaryKeyAdd($Table)) return false;
                }
            } else {
                if (!$this->tableAlterPrimaryKeyAdd($Table)) return false;
            }
        } else {
            if ($_primary = $this->tablePrimaryKey($Table)) {
                if (!$this->tableAlterPrimaryKeyDrop($Table)) return false;
            }
        }
        foreach ($Table->getEnabledFieldList() as $Field) {
            if ($Field->isUnique()) {
                if (!$this->tableUniqueExists($Field)) {
                    if ($this->tableIndexExists($Field)) {
                        if (!$this->tableAlterIndexDrop($Field)) return false;
                    }
                    if (!$this->tableAlterUniqueAdd($Field)) return false;
                }
            } elseif ($Field->isIndex()) {
                if ($this->tableUniqueExists($Field)) {
                    if (!$this->tableAlterUniqueDrop($Field)) return false;
                }
                if (!$this->tableIndexExists($Field)) {
                    if (!$this->tableAlterIndexAdd($Field)) return false;
                }
            } else {
                if ($this->tableUniqueExists($Field)) {
                    if (!$this->tableAlterUniqueDrop($Field)) return false;
                }
                if ($this->tableIndexExists($Field)) {
                    if (!$this->tableAlterIndexDrop($Field)) return false;
                }
            }
        }
        return true;
    }

tableAlterFieldAdd()

$Data->tableAlterFieldAdd(Field $Field);
Исходный код
    function tableAlterFieldAdd(Field $Field) {
        $_query = array( "`{$Field->getName()}`" );
        if ($type = $Field->getType()) {
            if ($length = $Field->getLength()) {
                if ($length2 = $Field->getLength2()) {
                    $_query[] = $type . '(' . $length . ', ' . $length2 . ')';
                } else {
                    $_query[] = $type . '(' . $length . ')';
                }
            } else {
                $_query[] = $type;
            }
        }
        if (!$Field->isNull()) {
            $_query[] = 'NOT NULL';
            $default = strval($Field->getDefault());
            if ($default === 'N') {
                $_query[] = "DEFAULT '0'";
            } elseif ($default === 'ID') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'UUID') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'URL') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'VERSION') {
                $_query[] = "DEFAULT '1'";
            } elseif ($default === 'ORDER') {
                $_query[] = "DEFAULT '0'";
            } elseif ($default === 'LOGIN') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'NOW') {
                $_query[] = "DEFAULT '0000-00-00 00:00:00'";
            } elseif ($default === 'AUTO_INCREMENT') {
                $_query[] = $default;
            } elseif ($default === 'CURRENT_TIMESTAMP') {
                $_query[] = 'DEFAULT ' . $default;
                if ($type === 'timestamp') {
                    $_query[] = 'ON UPDATE CURRENT_TIMESTAMP';
                }
            } else {
                $_query[] = 'DEFAULT ' . $this->quote($default);
            }
        }
        $query = "ALTER TABLE `{$Field->getTable()}` ADD COLUMN " . implode(' ', $_query);
        if ($this->query($query)) return true;
        return false;
    }

tableAlterFieldChange()

$Data->tableAlterFieldChange(Field $Field);
Исходный код
    function tableAlterFieldChange(Field $Field) {
        $_query = array( "`{$Field->getName()}`" );
        if ($type = $Field->getType()) {
            if ($length = $Field->getLength()) {
                if ($length2 = $Field->getLength2()) {
                    $_query[] = $type . '(' . $length . ', ' . $length2 . ')';
                } else {
                    $_query[] = $type . '(' . $length . ')';
                }
            } else {
                $_query[] = $type;
            }
        }
        if (!$Field->isNull()) {
            $_query[] = 'NOT NULL';
            $default = strval($Field->getDefault());
            if ($default === 'N') {
                $_query[] = "DEFAULT '0'";
            } elseif ($default === 'ID') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'UUID') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'URL') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'VERSION') {
                $_query[] = "DEFAULT '1'";
            } elseif ($default === 'ORDER') {
                $_query[] = "DEFAULT '0'";
            } elseif ($default === 'LOGIN') {
                $_query[] = "DEFAULT ''";
            } elseif ($default === 'NOW') {
                $_query[] = "DEFAULT '0000-00-00 00:00:00'";
            } elseif ($default === 'AUTO_INCREMENT') {
                $_query[] = $default;
            } elseif ($default === 'CURRENT_TIMESTAMP') {
                $_query[] = 'DEFAULT ' . $default;
                if ($type === 'timestamp') {
                    $_query[] = 'ON UPDATE CURRENT_TIMESTAMP';
                }
            } else {
                $_query[] = 'DEFAULT ' . $this->quote($default);
            }
        }
        $query = "ALTER TABLE `{$Field->getTable()}` CHANGE COLUMN `{$Field->getName()}` " . implode(' ', $_query);
        if ($this->query($query)) return true;
        return false;
    }

tableAlterFieldDrop()

$Data->tableAlterFieldDrop(Field $Field);
Исходный код
    function tableAlterFieldDrop(Field $Field) {
        if ($this->query("ALTER TABLE `{$Field->getTable()}` DROP COLUMN `{$Field->getName()}`")) return true;
        return false;
    }

tableAlterPrimaryKeyAdd()

$Data->tableAlterPrimaryKeyAdd(Table $Table);
Исходный код
    function tableAlterPrimaryKeyAdd(Table $Table) {
        if ($primary = $Table->getPrimaryKey()) {
            if ($this->query("ALTER TABLE `{$Table->getName()}` ADD PRIMARY KEY (`" . (is_array($primary) ? implode("`, `", $primary) : $primary) . "`)")) return true;
        } else {
            return true;
        }
        return false;
    }

tableAlterPrimaryKeyDrop()

$Data->tableAlterPrimaryKeyDrop(Table $Table);
Исходный код
    function tableAlterPrimaryKeyDrop(Table $Table) {
        if ($this->query("ALTER TABLE `{$Table->getName()}` DROP PRIMARY KEY")) return true;
        return false;
    }

tableAlterUniqueAdd()

$Data->tableAlterUniqueAdd(Field $Field);
Исходный код
    function tableAlterUniqueAdd(Field $Field) {
        if ($this->query("ALTER TABLE `{$Field->getTable()}` ADD UNIQUE KEY `{$Field->getName()}` (`{$Field->getName()}`)")) return true;
        return false;
    }

tableAlterUniqueDrop()

$Data->tableAlterUniqueDrop(Field $Field);
Исходный код
    function tableAlterUniqueDrop(Field $Field) {
        if ($this->query("ALTER TABLE `{$Field->getTable()}` DROP INDEX `{$Field->getName()}`")) return true;
        return false;
    }

tableAlterIndexAdd()

$Data->tableAlterIndexAdd(Field $Field);
Исходный код
    function tableAlterIndexAdd(Field $Field) {
        if ($this->query("ALTER TABLE `{$Field->getTable()}` ADD KEY `{$Field->getName()}` (`{$Field->getName()}`" . (in_array($Field->getType(), array('text', 'longtext')) ? '(255)' : '') . ")")) return true;
        return false;
    }

tableAlterIndexDrop()

$Data->tableAlterIndexDrop(Field $Field);
Исходный код
    function tableAlterIndexDrop(Field $Field) {
        if ($this->query("ALTER TABLE `{$Field->getTable()}` DROP INDEX `{$Field->getName()}`")) return true;
        return false;
    }

tableDrop()

$Data->tableDrop(Table $Table);
Исходный код
    function tableDrop(Table $Table) {
        if ($this->query("RENAME TABLE `{$Table->getName()}` TO `{$Table->getName()}_" . date('YmdHis') . "`")) return true;
        return false;
    }