mysql
MySQL/MariaDB: удалённая база, не блокирующая кадр. Для той базы, которая не лежит рядом с сервером — сайт, панель, общий для нескольких серверов проекта аккаунт. Для локальных данных прощеdb: он синхронный и не тянет за собой внешний процесс.
http: запрос уходит на рабочий
поток, ответ возвращается в игровой — тем же проходом, которым тикают
таймеры и ходят HTTP-ответы. Ни одна строчка плагина не касается сокета.
Вызов :query/:exec ничего не ждёт: он возвращается сразу с id, кадр идёт
дальше, коллбэк приходит когда придёт.
Опциональные хелперы find / create / update / delete собирают
безопасный SQL сами: имена таблиц и колонок — только [A-Za-z0-9_],
значения идут через ?. Для JOIN, подзапросов и сложного WHERE остаётся
сырой :query / :exec. Миграции схемы — conn:migrate.
mysql.connect тоже не ждёт: соединение открывается лениво, на рабочем
потоке, при первом запросе — сам вызов connect кадр не блокирует и связку
не проверяет.
Значения через ?
Как в db, но экранирование делает рабочий поток на живом соединении, а не
драйвер напрямую:
Транспорт
Клиентская библиотека MySQL — не часть модуля: она открывается при первом запросе, как libcurl уhttp, а не линкуется в сборку.
Сервер без клиентской библиотеки нормально загрузит модуль:
res.error
скажет об этом при первом обращении к соединению, а не при старте.
Объект ответа
Коллбэк получает одну таблицу.
Строка в
res.rows — таблица с ключами по именам колонок; NULL приходит
как отсутствующий ключ, ровно как в db. Тип колонки в SQL решает, придёт
значение числом или строкой:
Даты и время остаются строкой не просто так: у них нет единого числового
представления, которое не потребовало бы
parse на другом конце — так же,
как в исходном TEXT-протоколе MySQL, откуда и приходит сырое значение.
Одно соединение — одна очередь
Два запроса на разных соединениях выполняются параллельно (рабочих потоков несколько). Два запроса на одном и том же соединении всегда идут по очереди — MySQL-соединение нельзя использовать из двух мест одновременно, поэтому нужен параллелизм — открывай второе соединение, а не жди на одном.Обрыв связи
Ошибка запроса закрывает соединение изнутри; следующий вызов:query/:exec/:find/:create/:update/:delete/:migrate
на этом же объекте переподключается заново сам, без явного :connect().
Платится это одним лишним переподключением и на обычную опечатку в SQL —
дёшево по сравнению с тем, чтобы намертво зависнуть на упавшем сайте.
Перезагрузка и выгрузка
Как иhttp: запросы, оставшиеся на проводе, переживают lua_reload и
выгрузку плагина, но их коллбэки не выполняются — ответ выбрасывается.
Перезагрузка не ждёт незавершённые запросы. Соединения при этом не рвутся:
сокет остаётся открытым и простаивает до остановки сервера, чтобы не ждать
рабочий поток на середине запроса.