Довольно часто на этапе прототипирования (и всегда — в пет-проектах) я не запариваюсь с бэкэндом и поднимаю апи на express с sqlite3. Это легко и довольно удобно для несложной логики, а для сложной есть бэкэндеры с их отдельным миром. Единственный геморрой, который долгое время меня преследовал на этапе написания апи — невозможность быстро заглянуть в базу и отследить изменения. Можно дебажить по памяти, конечно, но это как-то странно, когда можно просто вытащить содержимое по запросу и отобразить его на какой-нибудь страничке. Вот только каждый раз заново парсить json и распихивать его в таблицы по лучшим практикам очередного фреймворка мне не хотелось, поэтому я после недолгих поисков нашёл sqljs и набросал на нём простейший визуализатор.
Про sqljs
Это библиотека, позволяющая создавать sqlite базы, читать, писать и вообще строить любой апи на них. Он построен на wasm, поэтому работает медленнее чем тот же sqlite3, и использует emscripten для сборки. По умолчанию создаётся in-memory база, но можно читать из файла и экспортировать файл из памяти. Демо. В конце концов, sqljs не завязан на node или любое другое окружение и спокойно работает в браузере, но мне было проще запустить его из ноды, всё равно ж использую.
Ссылки
Вот сайт, документация и примеры. Есть легаси-версия с asm.js и web worker версия, все дистрибутивы доступны через CDN и на GitHub.
Использование
0. Подключаем библиотеку
CDN:
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.4.0/dist/sql-wasm.js" integrity="sha512-8oJoeo0ykAzuJzQFJDnwz9t4Rr+1xue7LFX+kr0NJMpOHH9QJPC563If+sakheUe3QbLwTTgXIGPC6YZTwp7Iw==" crossorigin="anonymous"></script>
npm:
npm install sqljs
1. Инициализация библиотеки
// Используя модуль: const initSqlJs = require('sql.js'); // При использовании в браузере: var initSqlJs = window.initSqlJs;
2. Загружаем инстанс
const SQL = await initSqlJs({ // Асинхронная загрузка бинарника wasm. Разумеется, его можно хранить и у себя // В node не требуется locateFile: file => `https://sql.js.org/dist/${file}` });
3. Создаём базу, выполняем INSERT/SELECT
var db = new SQL.Database(); // Также можно использовать new SQL.Database(data), где // data это Uint8Array с файлом sqlite sqlstr = "CREATE TABLE hello (a int, b char);"; sqlstr += "INSERT INTO hello VALUES (0, 'hello');" sqlstr += "INSERT INTO hello VALUES (1, 'world');" db.run(sqlstr); var res = db.exec("SELECT * FROM hello"); /* [ {columns:['a','b'], values:[[0,'hello'],[1,'world']]} ] */
4. Формируем смешанный запрос и привязываем переменные к значениям ответа
var stmt = db.prepare("SELECT * FROM hello WHERE a=:aval AND b=:bval"); var result = stmt.getAsObject({':aval' : 1, ':bval' : 'world'}); console.log(result); // {a:1, b:'world'} // Освобождаем память выражения stmt.free(); // После освобождения использовать выражение нельзя, // но бесконтрольное использование приведёт к утечкам памяти
Демо: https://jsfiddle.net/5f3ahx8o/
Визуализация
Из-за разницы в производительности и не особенно нужного in-memory, возможно и стоило изначально брать проверенный sqlite3, но надо было бы притянуть немного бойлерплейта, да и логично было бы пустить отображение через апи, а мне хотелось иметь отдельно работающий молчаливый сервис. Чтобы не плодить сущности я взял express-handlebars для отображения и прокинул в основную вьюху {{{renderedTables}}}.
Базу забирал из той же директории, но можно прописать любой путь.
var filebuffer = fs.readFileSync('sqlitedb'); /* ... */ initSqlJs().then(function(SQL){ var db = new SQL.Database(filebuffer);
Данные из всех таблиц получаются в две строчки:
var schema = db.exec('SELECT name, sql FROM sqlite_master WHERE type="table";')[0].values; schema.forEach(t => all[t[0]] = db.exec('SELECT * FROM ' + t[0]));
Дальше идёт скучный рендер таблицы и, наконец, отправка её на страницу. Полный код есть в репо.
Заключение
Меня на протяжении всего этого процесса не покидало ощущение, что я изобретаю какой-то тупейший велосипед и всё уже точно написано до меня, обмазано тестами и схемами, но топорного варианта для себя, «запустил и забыл», так и не обнаружил. Ну, тем забавнее будет, если эта штука кому-то окажется полезна. Можно ещё прикрутить хот-релоад и эти долбаные схемы, но зачем их заводить для mock database на пару таблиц, мне неочевидно.
На правах рекламы
Мощные виртуальные серверы с процессорами AMD EPYC для разработчиков. Частота ядра CPU до 3.4 GHz. Максимальная конфигурация позволит оторваться на полную — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe.
ссылка на оригинал статьи https://habr.com/ru/company/vdsina/blog/527146/

Добавить комментарий