Add kysely migrations

This commit is contained in:
Alex Gleason 2023-08-07 01:45:02 -05:00
parent eb78a213f6
commit 97a250c1f7
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
4 changed files with 96 additions and 45 deletions

View File

@ -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 };

View File

@ -26,9 +26,11 @@ function insertEvent(event: SignedEvent): Promise<void> {
return results;
}, []);
await trx.insertInto('tags')
.values(tags)
.execute();
await Promise.all(tags.map((tag) => {
return trx.insertInto('tags')
.values(tag)
.execute();
}));
});
}

View File

@ -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();
}

View File

@ -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';