diff --git a/lib/kysely-deno-sqlite.ts b/lib/kysely-deno-sqlite.ts new file mode 100644 index 00000000..4a0467ef --- /dev/null +++ b/lib/kysely-deno-sqlite.ts @@ -0,0 +1,88 @@ +import { + type DatabaseIntrospector, + type Dialect, + type DialectAdapter, + type Driver, + Kysely, + type QueryCompiler, + SqliteAdapter, + type SqliteDatabase, + type SqliteDialectConfig, + SqliteDriver, + SqliteIntrospector, + SqliteQueryCompiler, + type SqliteStatement, +} from 'npm:kysely@^0.25.0'; + +import type { DB as DenoSqlite } from 'https://deno.land/x/sqlite@v3.7.3/mod.ts'; + +class DenoSqliteDatabase implements SqliteDatabase { + #db: DenoSqlite; + + constructor(db: DenoSqlite) { + this.#db = db; + } + + close(): void { + this.#db.close(); + } + + prepare(sql: string): SqliteStatement { + return { + reader: true, + all: (parameters: ReadonlyArray) => { + console.log(sql); + return this.#db.query(sql, parameters as any); + }, + run: (parameters: ReadonlyArray) => { + this.#db.query(sql, parameters as any); + return { + changes: this.#db.changes, + lastInsertRowid: this.#db.lastInsertRowId, + }; + }, + }; + } +} + +interface DenoSqliteDialectConfig extends Omit { + database: DenoSqlite | (() => Promise); +} + +class DenoSqliteDriver extends SqliteDriver { + constructor(config: DenoSqliteDialectConfig) { + super({ + ...config, + database: async () => + new DenoSqliteDatabase( + typeof config.database === 'function' ? await config.database() : config.database, + ), + }); + } +} + +class DenoSqliteDialect implements Dialect { + readonly #config: DenoSqliteDialectConfig; + + constructor(config: DenoSqliteDialectConfig) { + this.#config = Object.freeze({ ...config }); + } + + createDriver(): Driver { + return new DenoSqliteDriver(this.#config); + } + + createQueryCompiler(): QueryCompiler { + return new SqliteQueryCompiler(); + } + + createAdapter(): DialectAdapter { + return new SqliteAdapter(); + } + + createIntrospector(db: Kysely): DatabaseIntrospector { + return new SqliteIntrospector(db); + } +} + +export { DenoSqliteDatabase, DenoSqliteDialect, type DenoSqliteDialectConfig, DenoSqliteDriver }; diff --git a/src/db.ts b/src/db.ts index 46115245..08f83413 100644 --- a/src/db.ts +++ b/src/db.ts @@ -1,4 +1,5 @@ -import { Sqlite } from '@/deps.ts'; +import { builder } from '@/db/builder.ts'; +import { type Filter, Sqlite } from '@/deps.ts'; import { SignedEvent } from '@/event.ts'; interface User { @@ -101,9 +102,15 @@ class DittoDB { } }); } + + getFilter(filter: Filter) { + } } const db = new DittoDB( new Sqlite('data/db.sqlite3'), ); + +console.log(await builder.selectFrom('events').selectAll().limit(1).execute()) + export { db }; diff --git a/src/db/builder.ts b/src/db/builder.ts new file mode 100644 index 00000000..dec5debe --- /dev/null +++ b/src/db/builder.ts @@ -0,0 +1,40 @@ +import { Kysely, Sqlite } from '@/deps.ts'; +import { DenoSqliteDialect } from '../../lib/kysely-deno-sqlite.ts'; + +interface Tables { + events: EventsTable; + tags: TagsTable; + users: UsersTable; +} + +interface EventsTable { + id: string; + kind: number; + pubkey: string; + content: string; + created_at: number; + tags: string; + sig: string; +} + +interface TagsTable { + tag: string; + value_1: string | null; + value_2: string | null; + value_3: string | null; + event_id: string; +} + +interface UsersTable { + pubkey: string; + username: string; + inserted_at: Date; +} + +const builder = new Kysely({ + dialect: new DenoSqliteDialect({ + database: new Sqlite('data/db.sqlite3'), + }), +}); + +export { builder }; diff --git a/src/deps.ts b/src/deps.ts index 12800d2a..b721ec9a 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -50,3 +50,4 @@ export * as secp from 'npm:@noble/secp256k1@^2.0.0'; export { LRUCache } from 'npm:lru-cache@^10.0.0'; export { DB as Sqlite } from 'https://deno.land/x/sqlite@v3.7.3/mod.ts'; export * as dotenv from 'https://deno.land/std@0.197.0/dotenv/mod.ts'; +export { DummyDriver, Kysely, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from 'npm:kysely@^0.25.0';