Add kysely migrations
This commit is contained in:
parent
eb78a213f6
commit
97a250c1f7
58
src/db.ts
58
src/db.ts
|
@ -1,4 +1,7 @@
|
|||
import { DenoSqliteDialect, Kysely, Sqlite } from '@/deps.ts';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
import { DenoSqliteDialect, FileMigrationProvider, Kysely, Migrator, Sqlite } from '@/deps.ts';
|
||||
|
||||
interface Tables {
|
||||
events: EventRow;
|
||||
|
@ -30,49 +33,22 @@ interface UserRow {
|
|||
inserted_at: Date;
|
||||
}
|
||||
|
||||
const sqlite = new Sqlite('data/db.sqlite3');
|
||||
|
||||
// TODO: move this into a proper migration
|
||||
sqlite.execute(`
|
||||
CREATE TABLE IF NOT EXISTS events (
|
||||
id TEXT PRIMARY KEY,
|
||||
kind INTEGER NOT NULL,
|
||||
pubkey TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL,
|
||||
tags TEXT NOT NULL,
|
||||
sig TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_events_kind ON events(kind);
|
||||
CREATE INDEX IF NOT EXISTS idx_events_pubkey ON events(pubkey);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tags (
|
||||
tag TEXT NOT NULL,
|
||||
value_1 TEXT,
|
||||
value_2 TEXT,
|
||||
value_3 TEXT,
|
||||
event_id TEXT NOT NULL,
|
||||
FOREIGN KEY(event_id) REFERENCES events(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_tags_tag ON tags(tag);
|
||||
CREATE INDEX IF NOT EXISTS idx_tags_value_1 ON tags(value_1);
|
||||
CREATE INDEX IF NOT EXISTS idx_tags_event_id ON tags(event_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
pubkey TEXT PRIMARY KEY,
|
||||
username TEXT NOT NULL,
|
||||
inserted_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_username ON users(username);
|
||||
`);
|
||||
|
||||
const db = new Kysely<Tables>({
|
||||
dialect: new DenoSqliteDialect({
|
||||
database: sqlite,
|
||||
database: new Sqlite('data/db.sqlite3'),
|
||||
}),
|
||||
});
|
||||
|
||||
const migrator = new Migrator({
|
||||
db,
|
||||
provider: new FileMigrationProvider({
|
||||
fs,
|
||||
path,
|
||||
migrationFolder: new URL(import.meta.resolve('./db/migrations')).pathname,
|
||||
}),
|
||||
});
|
||||
|
||||
console.log('Running migrations...');
|
||||
await migrator.migrateToLatest();
|
||||
|
||||
export { db, type EventRow, type TagRow, type UserRow };
|
||||
|
|
|
@ -26,9 +26,11 @@ function insertEvent(event: SignedEvent): Promise<void> {
|
|||
return results;
|
||||
}, []);
|
||||
|
||||
await trx.insertInto('tags')
|
||||
.values(tags)
|
||||
await Promise.all(tags.map((tag) => {
|
||||
return trx.insertInto('tags')
|
||||
.values(tag)
|
||||
.execute();
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
import { Kysely, sql } from '@/deps.ts';
|
||||
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await db.schema
|
||||
.createTable('events')
|
||||
.addColumn('id', 'text', (col) => col.primaryKey())
|
||||
.addColumn('kind', 'integer', (col) => col.notNull())
|
||||
.addColumn('pubkey', 'text', (col) => col.notNull())
|
||||
.addColumn('content', 'text', (col) => col.notNull())
|
||||
.addColumn('created_at', 'integer', (col) => col.notNull())
|
||||
.addColumn('tags', 'text', (col) => col.notNull())
|
||||
.addColumn('sig', 'text', (col) => col.notNull())
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('tags')
|
||||
.addColumn('tag', 'text', (col) => col.notNull())
|
||||
.addColumn('value_1', 'text')
|
||||
.addColumn('value_2', 'text')
|
||||
.addColumn('value_3', 'text')
|
||||
.addColumn('event_id', 'text', (col) => col.notNull().references('events.id'))
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('users')
|
||||
.addColumn('pubkey', 'text', (col) => col.primaryKey())
|
||||
.addColumn('username', 'text', (col) => col.notNull().unique())
|
||||
.addColumn('inserted_at', 'datetime', (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`))
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex('idx_events_kind')
|
||||
.on('events')
|
||||
.column('kind')
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex('idx_events_pubkey')
|
||||
.on('events')
|
||||
.column('pubkey')
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex('idx_tags_tag')
|
||||
.on('tags')
|
||||
.column('tag')
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex('idx_tags_value_1')
|
||||
.on('tags')
|
||||
.column('value_1')
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex('idx_tags_event_id')
|
||||
.on('tags')
|
||||
.column('event_id')
|
||||
.execute();
|
||||
}
|
||||
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await db.schema.dropTable('events').execute();
|
||||
await db.schema.dropTable('tags').execute();
|
||||
await db.schema.dropTable('users').execute();
|
||||
}
|
|
@ -50,5 +50,12 @@ 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 { type Insertable, Kysely, type NullableInsertKeys } from 'npm:kysely@^0.25.0';
|
||||
export {
|
||||
FileMigrationProvider,
|
||||
type Insertable,
|
||||
Kysely,
|
||||
Migrator,
|
||||
type NullableInsertKeys,
|
||||
sql,
|
||||
} from 'npm:kysely@^0.25.0';
|
||||
export { DenoSqliteDialect } from 'https://gitlab.com/soapbox-pub/kysely-deno-sqlite/-/raw/76748303a45fac64a889cd2b9265c6c9b8ef2e8b/mod.ts';
|
||||
|
|
Loading…
Reference in New Issue