Scratch space for learning atproto app development
1import SqliteDb from 'better-sqlite3'
2import {
3 Kysely,
4 Migrator,
5 SqliteDialect,
6 Migration,
7 MigrationProvider,
8} from 'kysely'
9
10// Types
11
12export type DatabaseSchema = {
13 status: Status
14 auth_session: AuthSession
15 auth_state: AuthState
16}
17
18export type Status = {
19 uri: string
20 authorDid: string
21 status: string
22 createdAt: string
23 indexedAt: string
24}
25
26export type AuthSession = {
27 key: string
28 session: AuthSessionJson
29}
30
31export type AuthState = {
32 key: string
33 state: AuthStateJson
34}
35
36type AuthStateJson = string
37
38type AuthSessionJson = string
39
40// Migrations
41
42const migrations: Record<string, Migration> = {}
43
44const migrationProvider: MigrationProvider = {
45 async getMigrations() {
46 return migrations
47 },
48}
49
50migrations['001'] = {
51 async up(db: Kysely<unknown>) {
52 await db.schema
53 .createTable('status')
54 .addColumn('uri', 'varchar', (col) => col.primaryKey())
55 .addColumn('authorDid', 'varchar', (col) => col.notNull())
56 .addColumn('status', 'varchar', (col) => col.notNull())
57 .addColumn('createdAt', 'varchar', (col) => col.notNull())
58 .addColumn('indexedAt', 'varchar', (col) => col.notNull())
59 .execute()
60 await db.schema
61 .createTable('auth_session')
62 .addColumn('key', 'varchar', (col) => col.primaryKey())
63 .addColumn('session', 'varchar', (col) => col.notNull())
64 .execute()
65 await db.schema
66 .createTable('auth_state')
67 .addColumn('key', 'varchar', (col) => col.primaryKey())
68 .addColumn('state', 'varchar', (col) => col.notNull())
69 .execute()
70 },
71 async down(db: Kysely<unknown>) {
72 await db.schema.dropTable('auth_state').execute()
73 await db.schema.dropTable('auth_session').execute()
74 await db.schema.dropTable('status').execute()
75 },
76}
77
78// APIs
79
80export const createDb = (location: string): Database => {
81 return new Kysely<DatabaseSchema>({
82 dialect: new SqliteDialect({
83 database: new SqliteDb(location),
84 }),
85 })
86}
87
88export const migrateToLatest = async (db: Database) => {
89 const migrator = new Migrator({ db, provider: migrationProvider })
90 const { error } = await migrator.migrateToLatest()
91 if (error) throw error
92}
93
94export type Database = Kysely<DatabaseSchema>