Mahdyar's Blog

My Thoughts

میزبانی دیتابیس اس‌کیوالایت به صورت استاتیک

تا حالا به این فکر کرده بودید که چقدر خوب می‌شد اگر می‌شد اس‌کیوالایت به صورت استاتیک سرو می‌شد و می‌شد سمت کلاینت کوئری زد و نیازی به سرور و api نداشت؟ ظاهراً یکی فکر کرده و اون رو پیاده‌سازی کرده. و ما توی این پست با هم بررسی‌ش می‌کنیم.

چند وقت پیش بود که دیتای عظیمی از کاربران ایرانی تلگرام از پروژهٔ «شکار» فتای ج.ا لیک شد. این دیتا شامل شماره‌ تلفن‌های مرتبط به هر یوزرنیم با یوزرآیدی می‌شد که شما می‌تونستید با استفاده از یکی‌شون به شمارهٔ شخص موردنظرتون برسید. یوزرنیم‌هایی که تو این لیک بودن رو اینجا گذاشتم و در دسترسه. حالا این اطلاعات، بدون نیاز به سرور و با GitHub Pages قابل جستجو هم شدن که از اینجا در دسترسه.

۱. تبدیل .txt به .sqlite3

قدم اول تبدیل دیتای خام به دیتابیس sqlite بود، بخشی از کد رو اینجا می‌ذارم:

import sqlite3
con = sqlite3.connect('usernames.db')
usernamesFile = open('usernames.txt', 'r')
usernames = usernamesFile.readlines()
c = con.cursor()
for username in usernames:
    username = username.rstrip()
    c.execute('INSERT INTO usernames(username) VALUES (?)', (username,))
con.commit();

۲. استفاده از sql.js-httpvfs و سرو اس‌کیوالایت به صورت استاتیک

برای شروع استفاده از sql.js مراحل زیر رو انجام بدید:

mkdir example
cd example
echo '{}' > package.json
npm install --save-dev webpack webpack-cli typescript ts-loader http-server
npm install --save sql.js-httpvfs
npx tsc --init

و فایل .tsconfig رو ادیت کنید:

...
"target": "es2020",
"module": "es2020",
"moduleResolution": "node",
...

فایل کانفیگ وب‌پک رو در مسیر /webpack.config.js بسازید:

module.exports = {
  entry: "./src/index.ts",
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: "ts-loader",
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
  output: {
    filename: "bundle.js",
  },
  devServer: {
    publicPath: "/dist",
  },
};

فایل index.html رو هم در مسیر /index.html بسازید:

<!DOCTYPE html>
<title>دموی sql.js-httpvfs</title>
<script src="./dist/bundle.js"></script>
<div>سلام دنیا!</div>

و فایل ایندکس تایپ‌اسکریپت رو هم در مسیر /src/index.ts بسازید:

import { createDbWorker } from "sql.js-httpvfs";

const workerUrl = new URL(
  "sql.js-httpvfs/dist/sqlite.worker.js",
  import.meta.url
);
const wasmUrl = new URL("sql.js-httpvfs/dist/sql-wasm.wasm", import.meta.url);

async function load() {
  const worker = await createDbWorker(
    [
      {
        from: "inline",
        config: {
          serverMode: "full",
          url: "/usernames.sqlite3",
          requestChunkSize: 4096,
        },
      },
    ],
    workerUrl.toString(),
    wasmUrl.toString()
  );

  const result = await worker.db.query(`select username from usernames where username = ''`);

  document.body.textContent = JSON.stringify(result);
}

load();

و تمام! حالا برای کامپایل کردن توی حالت توسعه، از دستور زیر استفاده کنید:

./node_modules/.bin/webpack --mode=development

و با دستور وب‌سرور رو اجرا کنید:

./node_modules/.bin/http-server

وب‌سرور روی پورت 8080 در حال اجراست. حالا به لینک زیر برید:

http://localhost:8080

سورس کد shekar.thegoat.ir از اینجا در دسترسه و می‌تونید یک مثال عملی از اس‌کیوالایت به صورت استاتیک و به کمک sql.js رو ببینید. 🙂