SQLite
 sql >> база данни >  >> RDS >> SQLite

Как да обработваме булеви стойности в SQLite с помощта на прокси сървъри на JavaScript

Проблемът с булевите стойности в SQLite

Ако някога сте работили със SQLite, трябва да сте наясно с поддържаните типове данни и Boolean не е един от тях. По-конкретно, както е посочено тук:

2.1. Булев тип данни

SQLite няма отделен булев клас за съхранение. Вместо това булевите стойности се съхраняват като цели числа 0 (false) и 1 (true).

SQLite разпознава ключовите думи „TRUE“ и „FALSE“ от версия 3.23.0 (2018-04-02), но тези ключови думи всъщност са просто алтернативни изписвания за целочислените литерали 1 и 0 съответно.

Повечето JavaScript библиотеки за SQLite3 не поддържат TRUE и FALSE ключови думи и те изискват от вас да подготвите изразите във вашия код, като използвате цели числа. Например, в по-добър sqlite3 ще трябва да направите това:

const payload = {
  isActive: 1, // <======
  username: 'Brad',
  password: '1234',
  email: '[email protected]',
};

const result = database
  .prepare(
    `INSERT INTO accounts(isActive, username, password, email) VALUES(@isActive, @username, @password, @email) `
  )
  .run({ bucketID, taskSiteID, name, username, password, email }).changes;

Използване на number вместо boolean в цялото ви приложение би довело до ужасно изживяване за разработчиците (плюс вероятно да използвате повече памет).

Можете да използвате помощна функция, за да преобразувате логически обекти на полезен товар свойства към числа (Всъщност бях направил това веднъж, в миналото), но тогава ще трябва да го стартирате ръчно преди всяка заявка. Мда. Не би ли било чудесно, ако тази логика се изпълняваше на заден план всеки път, когато подготвяхме и изпълнявахме изявление?

Добре дошли ES6 прокси сървъри 👋 

Една от по-новите функции на JavaScript е Proxy обект. Проксита са по същество "капани", които прихващат операции с обекти като getters, setters и извиквания на функции. Използване на проксита можем да модифицираме библиотеката на обвивката на SQLite JS, за да изпълни нашата собствена логика, нещо като междинен софтуер.

Написване на помощната функция

За улеснение на разработката ще използваме mapValues &isPlainObject помощни функции от lodash, но вие, разбира се, можете да кодирате свой собствен. Функцията по-долу ще преобразува през обект (дълбоко едно ниво) и ще преобразува стойности от тип boolean за да въведете number .

import { mapValues } from 'lodash';

const booleanEntriesToNumbers = (object) =>
  mapValues(object, (value) =>
    typeof value === 'boolean' ? Number(value) : value
  );

Използване на прокси сървъри за прихващане на повиквания на заявка

По-долу импортираме better-sqlite3 библиотека и създайте нов екземпляр на база данни. След това заменяме стандартния prepare метод с нашия собствен, който от своя страна отменя методите run , get и all , като създадете нов прокси за всеки от тях. Разбира се, можете да създадете прокси за всеки друг метод, който искате.

import Database from 'better-sqlite3';

// Create new database instance
const db = new Database(dbFilePath);

// We will use this function to override the default "prepare" method
const proxiedPrepare = new Proxy(db.prepare, {
    apply: (prepare, prepareThisArg, [stringStatement]) => {
      const statement = prepare.call(prepareThisArg, stringStatement);

      // Override the default "run" method
      statement.run = new Proxy(statement.run, {
        apply: (run, runThisArg, args) => {
          const mappedArgs = args.map((arg) =>
            isPlainObject(arg) ? booleanEntriesToNumbers(arg) : arg
          );

          return run.call(runThisArg, ...mappedArgs);
        },
      });

      // Override the default "get" method
      statement.get = new Proxy(statement.get, {
        apply: (get, getThisArg, args) => {
          const mappedArgs = args.map((arg) =>
            isPlainObject(arg) ? booleanEntriesToNumbers(arg) : arg
          );

          return get.call(getThisArg, ...mappedArgs);
        },
      });

      // Override the default "all" method
      statement.all = new Proxy(statement.all, {
        apply: (all, allThisArg, args) => {
          const mappedArgs = args.map((arg) =>
            isPlainObject(arg) ? booleanEntriesToNumbers(arg) : arg
          );

          return all.call(allThisArg, ...mappedArgs);
        },
      });

      return statement;
    },
  });

// Override the default "prepare" method
db.prepare = proxiedPrepare;

По същество, веднъж извикване на prepare се задейства, казваме на JavaScript:Изчакайте! Искаме да променим това извикване на функция. Вместо да изпълняваме логиката, която първоначалният разработчик е възнамерявал, ние вместо това искаме първо да изпълним нашата собствена логика (която е картографирането на полезния товар на обекта). След като изпълним нашата собствена логика, ние връщаме резултата от извикването на оригиналния метод, като използваме call за да свържете this аргумент. Ако искате да прочетете повече за това как работят прокси сървърите, прочетете тук. За нашата реализация използвахме apply метод тук.

Благодаря, че прочетохте тази публикация, надявам се, че е помогнала на някой, който работи със SQLite в JavaScript 👊


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Форматирайте число като валута в SQLite

  2. Архивирайте SQLite база данни

  3. Когато се извика методът SQLiteOpenHelper onCreate?

  4. Как да получите текущото време в SQLite

  5. Как работи SQLite Trim().