SQLite
 sql >> Teknologi Basis Data >  >> RDS >> SQLite

Bagaimana menangani nilai boolean di SQLite menggunakan Proksi JavaScript

Masalah dengan Boolean di SQLite

Jika Anda pernah bekerja dengan SQLite, Anda harus mengetahui tipe data yang didukung dan Boolean bukan salah satunya. Lebih khusus seperti yang dinyatakan di sini:

2.1. Tipe Data Boolean

SQLite tidak memiliki kelas penyimpanan Boolean terpisah. Sebagai gantinya, nilai Boolean disimpan sebagai bilangan bulat 0 (salah) dan 1 (benar).

SQLite mengenali kata kunci "TRUE" dan "FALSE", pada versi 3.23.0 (2018-04-02) tetapi kata kunci tersebut sebenarnya hanyalah ejaan alternatif untuk literal integer 1 dan 0 masing-masing.

Sebagian besar pustaka JavaScript untuk SQLite3 tidak mendukung TRUE dan FALSE kata kunci dan mereka mengharuskan Anda untuk menyiapkan pernyataan dalam kode Anda menggunakan bilangan bulat. Misalnya, di better-sqlite3 Anda harus melakukan ini:

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;

Menggunakan number bukannya boolean di seluruh aplikasi Anda akan memberikan pengalaman pengembang yang buruk (ditambah mungkin menggunakan lebih banyak memori).

Anda dapat menggunakan fungsi pembantu untuk mengubah boolean objects objek muatan Anda properti ke angka (Saya sebenarnya pernah melakukan ini sekali, di masa lalu), tetapi kemudian Anda harus menjalankannya secara manual sebelum setiap kueri. Astaga. Bukankah lebih bagus jika logika ini dijalankan di latar belakang, setiap kali kita menyiapkan dan menjalankan sebuah pernyataan?

Selamat datang ES6 Proxy 👋 

Salah satu fitur JavaScript yang lebih baru adalah Proxy obyek. Proxy pada dasarnya adalah "perangkap" yang mencegat operasi objek seperti getter, setter, dan panggilan fungsi. Menggunakan Proxy kita dapat memodifikasi perpustakaan pembungkus SQLite JS untuk mengeksekusi logika kita sendiri, seperti middleware.

Menulis fungsi pembantu

Untuk kemudahan pengembangan, kita akan menggunakan mapValues &isPlainObject fungsi utilitas dari lodash , tetapi Anda tentu saja dapat membuat kode sendiri. Fungsi di bawah ini akan memetakan melalui objek (kedalaman satu tingkat) dan mengonversi nilai tipe boolean untuk mengetik number .

import { mapValues } from 'lodash';

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

Menggunakan proxy untuk mencegat panggilan kueri

Di bawah ini kami mengimpor better-sqlite3 library dan membuat instance database baru. Setelah itu, kami mengganti default prepare dengan metode kita sendiri, yang pada gilirannya menimpa metode run , get dan all , dengan membuat proxy baru untuk masing-masing proxy. Anda tentu saja dapat membuat proxy untuk metode lain yang Anda inginkan.

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;

Intinya, sekali panggilan ke prepare metode dipicu, kami memberi tahu JavaScript:Tunggu! Kami ingin mengubah panggilan fungsi ini. Alih-alih mengeksekusi logika yang dimaksudkan pengembang asli, kami ingin mengeksekusi logika kami sendiri terlebih dahulu (yang merupakan pemetaan muatan objek). Setelah menjalankan logika kita sendiri, kita mengembalikan hasil pemanggilan metode asli dengan menggunakan call untuk mengikat this argumen. Jika Anda ingin membaca lebih lanjut tentang cara kerja proxy, baca di sini. Untuk implementasi kami, kami menggunakan apply metode di sini.

Terima kasih telah membaca posting ini, saya harap ini membantu seseorang yang bekerja dengan SQLite di 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. Bagaimana SQLite Trim() Bekerja

  2. Menggunakan Room DB dalam proyek perpustakaan

  3. Bagaimana Coalesce() Bekerja di SQLite

  4. Bagaimana cara mengambil dua respons Json Objek dan Array Json

  5. Batasan UNIK SQLite