Unverified Commit 0c042221 authored by An Nyeong's avatar An Nyeong
Browse files

Add SQLite adapter abstraction layer

- Create adapter.ts for common SQLite interface
- Update kv.ts to use the adapter interface instead of `node:sqlite`
- Add Node.js implementation in node.ts
parent c71ee4e5
Loading
Loading
Loading
Loading

sqlite/adapter.ts

0 → 100644
+46 −0
Original line number Diff line number Diff line
/**
 * SQLite adapter
 */

export interface SQLiteDatabase {
  /**
   * Prepares a SQL statement.
   * @param sql - The SQL statement to prepare.
   */
  prepare(sql: string): SQLiteStatement;

  /**
   * Executes a SQL statement.
   * @param sql - The SQL statement to execute.
   */
  exec(sql: string): void;

  /**
   * Closes the database connection.
   */
  close(): void;
}

export interface SQLiteStatement {
  /**
   * Executes a SQL statement and returns the number of changes made to the database.
   * @param params - The parameters to bind to the SQL statement.
   */
  run(...params: unknown[]): { changes: number; lastInsertRowid: number };

  /**
   * Executes a SQL statement and returns the first row of the result set.
   * @param params - The parameters to bind to the SQL statement.
   */
  get(...params: unknown[]): unknown;

  /**
   * Executes a SQL statement and returns all rows of the result set.
   * @param params - The parameters to bind to the SQL statement.
   */
  all(...params: unknown[]): unknown[];
}

export function createSQLiteDatabase(db: unknown): SQLiteDatabase {
  throw new Error("Unsupported database type");
}
+3 −3
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ import type { KvKey, KvStore, KvStoreSetOptions } from "@fedify/fedify";
import { Temporal } from "@js-temporal/polyfill";
import { getLogger } from "@logtape/logtape";
import { isEqual } from "es-toolkit";
import type { DatabaseSync } from "node:sqlite";
import type { SQLiteDatabase } from "./adapter.ts";

const logger = getLogger(["fedify", "sqlite", "kv"]);

@@ -44,12 +44,12 @@ export interface SqliteKvStoreOptions {
export class SqliteKvStore implements KvStore {
  static readonly #defaultTableName = "fedify_kv";
  static readonly #tableNameRegex = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/;
  readonly #db: DatabaseSync;
  readonly #db: SQLiteDatabase;
  readonly #tableName: string;
  #initialized: boolean;

  constructor(
    readonly db: DatabaseSync,
    readonly db: SQLiteDatabase,
    readonly options: SqliteKvStoreOptions = {},
  ) {
    this.#db = db;
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ import { delay } from "@std/async/delay";
import assert from "node:assert/strict";
import { DatabaseSync } from "node:sqlite";
import { test } from "node:test";
import { SqliteKvStore } from "./kv.ts";
import { SqliteKvStore } from "./node.ts";

let Temporal: typeof temporal.Temporal;
if ("Temporal" in globalThis) {

sqlite/node.ts

0 → 100644
+42 −0
Original line number Diff line number Diff line
import { DatabaseSync, StatementSync } from "node:sqlite";
import type { SQLiteDatabase, SQLiteStatement } from "./adapter.ts";
import type { SqliteKvStoreOptions } from "./kv.ts";
import { SqliteKvStore as BaseSqliteKvStore } from "./kv.ts";

class NodeSqliteDatabase implements SQLiteDatabase {
  constructor(private readonly db: DatabaseSync) {}

  prepare(sql: string): NodeSqliteStatement {
    return new NodeSqliteStatement(this.db.prepare(sql));
  }

  exec(sql: string): void {
    this.db.exec(sql);
  }

  close(): void {
    this.db.close();
  }
}

class NodeSqliteStatement implements SQLiteStatement {
  constructor(private readonly stmt: StatementSync) {}

  run(...params: unknown[]): { changes: number; lastInsertRowid: number } {
    return this.stmt.run(...params);
  }

  get(...params: unknown[]): unknown {
    return this.stmt.get(...params);
  }

  all(...params: unknown[]): unknown[] {
    return this.stmt.all(...params);
  }
}

export class SqliteKvStore extends BaseSqliteKvStore {
  constructor(db: DatabaseSync, options: SqliteKvStoreOptions = {}) {
    super(new NodeSqliteDatabase(db), options);
  }
}