Визуализация sqlite в node.js

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.


Довольно часто на этапе прототипирования (и всегда — в пет-проектах) я не запариваюсь с бэкэндом и поднимаю апи на 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/


Интересные статьи

Интересные статьи

Здравствуйте! Меня зовут Ренат Саматов, я возглавляю фронтенд-направление в линейке продуктов Витрина. Большая часть наших проектов рендерится на сервере. Сегодня мы побеседуем об...
Ох, не зря в названии намёк на нетленку Фаулера. И когда фронтенд-приложения успели стать настолько сложными, что мы начали рассуждать о высоких материях? Node.js… фронтенд… погодите,...
GeoJSON — это стандартизованный формат представления географических структур данных, основанный на JSON. Существует множество замечательных инструментов для визуализации GeoJSON-данных. При этом ...
В компании Klarna прилагают большие усилия к тому, чтобы помочь разработчикам в создании высококачественных и безопасных сервисов. Один из инструментов, который предназначен для разработчиков, пр...
Cтатья будет полезна тем, кто думает какую выбрать CMS для интернет-магазина, сравнивает различные движки, ищет в них плюсы и минусы важные для себя.