Skip to content

Commit 7bed406

Browse files
committed
update database
1 parent da7e3ae commit 7bed406

File tree

24,562 files changed

+3798880
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

24,562 files changed

+3798880
-0
lines changed

database/config.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Kysely, sql } from 'kysely';
2+
import { ExpoDialect } from 'kysely-expo';
3+
import { BaseTable } from './types';
4+
5+
export function createDatabase<T extends Record<string, BaseTable>>(config: {
6+
name: string;
7+
debug?: boolean;
8+
onError?: (error: any) => void;
9+
}) {
10+
const dialect = new ExpoDialect({
11+
database: config.name,
12+
debug: config.debug ?? false,
13+
onError: config.onError,
14+
});
15+
16+
return new Kysely<T>({
17+
dialect,
18+
});
19+
}
20+
21+
export async function initializeTable(
22+
db: Kysely<any>,
23+
tableName: string
24+
) {
25+
await db.schema
26+
.createTable(tableName)
27+
.ifNotExists()
28+
.addColumn('parent_ulid', 'text')
29+
.addColumn('ulid', 'text', (col) => col.primaryKey())
30+
.addColumn('data', 'text')
31+
.addColumn('timestamp', 'integer', (col) =>
32+
col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
33+
)
34+
.addColumn('last_synced_at', 'integer')
35+
.addColumn('is_dirty', 'integer', (col) => col.notNull())
36+
.addColumn('is_deleted', 'integer', (col) => col.defaultTo(false).notNull())
37+
.execute();
38+
39+
await db.schema
40+
.createIndex(`${tableName}_timestamp`)
41+
.ifNotExists()
42+
.on(tableName)
43+
.column('timestamp')
44+
.execute();
45+
46+
await db.schema
47+
.createIndex(`${tableName}_parent_ulid`)
48+
.ifNotExists()
49+
.on(tableName)
50+
.column('parent_ulid')
51+
.execute();
52+
}

database/db.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { Kysely, sql } from 'kysely';
2+
import { ExpoDialect } from 'kysely-expo';
3+
4+
export const LOCAL_STORAGE_DB_NAME = 'app-database';
5+
6+
export interface Table {
7+
parent_ulid: string;
8+
ulid: string;
9+
data: string;
10+
timestamp: number;
11+
last_synced_at: number | null;
12+
is_dirty: number;
13+
is_deleted: number;
14+
}
15+
16+
export interface Database {
17+
exercises: Table;
18+
activities: Table;
19+
activity_exercises: Table;
20+
activity_segments: Table;
21+
programmed_workouts: Table;
22+
user_feed: Table;
23+
workout_routines: Table;
24+
training_programs: Table;
25+
}
26+
27+
const tables: Array<keyof Database> = [
28+
'exercises',
29+
'activities',
30+
'activity_exercises',
31+
'activity_segments',
32+
'programmed_workouts',
33+
'user_feed',
34+
'workout_routines',
35+
'training_programs',
36+
];
37+
38+
const dialect = new ExpoDialect({
39+
database: LOCAL_STORAGE_DB_NAME,
40+
// debug: __DEV__,
41+
debug: false,
42+
onError: (error) => {
43+
console.log(`SQLite Error: ${error}`);
44+
},
45+
});
46+
47+
const db = new Kysely<Database>({
48+
dialect,
49+
});
50+
51+
tables.forEach(async (table) => {
52+
await db.schema
53+
.createTable(table)
54+
.ifNotExists()
55+
.addColumn('parent_ulid', 'text')
56+
.addColumn('ulid', 'text', (col) => col.primaryKey())
57+
.addColumn('data', 'text')
58+
.addColumn('timestamp', 'integer', (col) =>
59+
col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
60+
)
61+
.addColumn('last_synced_at', 'integer')
62+
.addColumn('is_dirty', 'integer', (col) => col.notNull())
63+
.addColumn('is_deleted', 'integer', (col) => col.defaultTo(false).notNull())
64+
.execute();
65+
await db.schema
66+
.createIndex(`${table}_timestamp`)
67+
.ifNotExists()
68+
.on(table)
69+
.column('timestamp')
70+
.execute();
71+
await db.schema
72+
.createIndex(`${table}_parent_ulid`)
73+
.ifNotExists()
74+
.on(table)
75+
.column('parent_ulid')
76+
.execute();
77+
78+
try {
79+
await db.schema.alterTable(table).addColumn('parent_ulid', 'text').execute();
80+
} catch (error) {
81+
// Silent the error. The column already exists.
82+
}
83+
});
84+
85+
export interface UserTable {
86+
id: string;
87+
email: string;
88+
name: string;
89+
created_at: number;
90+
updated_at: number;
91+
}
92+
93+
export interface PostTable {
94+
id: string;
95+
user_id: string;
96+
title: string;
97+
content: string;
98+
created_at: number;
99+
updated_at: number;
100+
}
101+
102+
export interface CommentTable {
103+
id: string;
104+
post_id: string;
105+
user_id: string;
106+
content: string;
107+
created_at: number;
108+
updated_at: number;
109+
}
110+
111+
export interface SampleDatabase {
112+
users: UserTable;
113+
posts: PostTable;
114+
comments: CommentTable;
115+
}
116+
117+
export { db, sql };

database/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './types';
2+
export * from './provider';
3+
export * from './config';
4+
export * from './provider-v2';

database/provider-v2.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { BaseEndpoint, BaseRecord, BaseTable } from './types';
2+
import { SQLiteDataProvider } from './provider';
3+
import { Database } from './db';
4+
5+
// Add type intersection to ensure Database has string index signature
6+
type DatabaseWithIndex = Database & Record<string, BaseTable>;
7+
8+
export class SQLiteDataProviderV2<T extends BaseRecord> extends SQLiteDataProvider<T, DatabaseWithIndex> {
9+
constructor(
10+
entity: keyof Database,
11+
endpoint: BaseEndpoint<T>,
12+
queryKey: string
13+
) {
14+
const { db } = require('../db');
15+
super(db, entity, endpoint, queryKey);
16+
}
17+
}

0 commit comments

Comments
 (0)