-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathPowerSyncSQLiteDatabase.ts
More file actions
115 lines (105 loc) · 4.13 KB
/
PowerSyncSQLiteDatabase.ts
File metadata and controls
115 lines (105 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import {
AbstractPowerSyncDatabase,
compilableQueryWatch,
CompilableQueryWatchHandler,
QueryResult,
SQLWatchOptions
} from '@powersync/common';
import { Query } from 'drizzle-orm';
import { DefaultLogger } from 'drizzle-orm/logger';
import {
createTableRelationsHelpers,
extractTablesRelationalConfig,
ExtractTablesWithRelations,
TableRelationalConfig,
type RelationalSchemaConfig,
type TablesRelationalConfig
} from 'drizzle-orm/relations';
import { SQLiteSession, SQLiteTable, SQLiteTransaction } from 'drizzle-orm/sqlite-core';
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core/db';
import { SQLiteAsyncDialect } from 'drizzle-orm/sqlite-core/dialect';
import { RelationalQueryBuilder } from 'drizzle-orm/sqlite-core/query-builders/query';
import type { DrizzleConfig } from 'drizzle-orm/utils';
import { toCompilableQuery } from './../utils/compilableQuery.js';
import { PowerSyncSQLiteBaseSession, PowerSyncSQLiteTransactionConfig } from './PowerSyncSQLiteBaseSession.js';
import { PowerSyncSQLiteSession } from './PowerSyncSQLiteSession.js';
export type DrizzleQuery<T> = { toSQL(): Query; execute(): Promise<T | T[]> };
export class PowerSyncSQLiteDatabase<
TSchema extends Record<string, unknown> = Record<string, never>
> extends BaseSQLiteDatabase<'async', QueryResult, TSchema> {
private db: AbstractPowerSyncDatabase;
constructor(db: AbstractPowerSyncDatabase, config: DrizzleConfig<TSchema> = {}) {
const dialect = new SQLiteAsyncDialect({ casing: config.casing });
let logger;
if (config.logger === true) {
logger = new DefaultLogger();
} else if (config.logger !== false) {
logger = config.logger;
}
let schema: RelationalSchemaConfig<TablesRelationalConfig> | undefined;
if (config.schema) {
const tablesConfig = extractTablesRelationalConfig(config.schema, createTableRelationsHelpers);
schema = {
fullSchema: config.schema,
schema: tablesConfig.tables,
tableNamesMap: tablesConfig.tableNamesMap
};
}
const session = new PowerSyncSQLiteSession(db, dialect, schema, {
logger
});
super('async', dialect, session as any, schema as any);
this.db = db;
/**
* A hack in order to use read locks for `db.query.users.findMany()` etc queries.
* We don't currently get queryMetadata for these queries, so we can't use the regular session.
* This session always uses read locks.
*/
const querySession = new PowerSyncSQLiteBaseSession(
{
useReadContext: (callback) => db.readLock(callback),
useWriteContext: (callback) => db.readLock(callback)
},
dialect,
schema,
{
logger
}
);
if (this._.schema) {
// https://github.com/drizzle-team/drizzle-orm/blob/ad4ddd444d066b339ffd5765cb6ec3bf49380189/drizzle-orm/src/sqlite-core/db.ts#L72
const query = this.query as {
[K in keyof TSchema]: RelationalQueryBuilder<'async', any, any, any>;
};
for (const [tableName, columns] of Object.entries(this._.schema)) {
query[tableName as keyof TSchema] = new RelationalQueryBuilder(
'async',
schema!.fullSchema,
this._.schema,
this._.tableNamesMap,
schema!.fullSchema[tableName] as SQLiteTable,
columns as TableRelationalConfig,
dialect,
querySession as SQLiteSession<'async', any, any, any>
);
}
}
}
transaction<T>(
transaction: (
tx: SQLiteTransaction<'async', QueryResult, TSchema, ExtractTablesWithRelations<TSchema>>
) => Promise<T>,
config?: PowerSyncSQLiteTransactionConfig
): Promise<T> {
return super.transaction(transaction, config);
}
watch<T>(query: DrizzleQuery<T>, handler: CompilableQueryWatchHandler<T>, options?: SQLWatchOptions): void {
compilableQueryWatch(this.db, toCompilableQuery(query), handler, options);
}
}
export function wrapPowerSyncWithDrizzle<TSchema extends Record<string, unknown> = Record<string, never>>(
db: AbstractPowerSyncDatabase,
config: DrizzleConfig<TSchema> = {}
): PowerSyncSQLiteDatabase<TSchema> {
return new PowerSyncSQLiteDatabase<TSchema>(db, config);
}