@@ -13,6 +13,7 @@ import {
13
13
export default class SQLiteAdapter implements DBAdapter {
14
14
private _sqlite : typeof SQLiteWorker | undefined ;
15
15
private _dbId : string | undefined ;
16
+ private primaryKeys = new Map < string , string > ( ) ;
16
17
17
18
// TODO: one difference that I'm seeing is that it looks like "json_each" is
18
19
// actually similar to "json_each_text" in postgres. i think we might need to
@@ -56,11 +57,25 @@ export default class SQLiteAdapter implements DBAdapter {
56
57
) ;
57
58
throw e ;
58
59
}
60
+
61
+ let pks = ( await this . execute (
62
+ `
63
+ SELECT m.name AS table_name,
64
+ GROUP_CONCAT(p.name, ', ') AS primary_keys
65
+ FROM sqlite_master AS m
66
+ JOIN pragma_table_info(m.name) AS p ON m.type = 'table'
67
+ WHERE p.pk > 0
68
+ GROUP BY m.name;
69
+ ` ,
70
+ ) ) as { table_name : string ; primary_keys : string } [ ] ;
71
+ for ( let { table_name, primary_keys } of pks ) {
72
+ this . primaryKeys . set ( table_name , primary_keys ) ;
73
+ }
59
74
}
60
75
}
61
76
62
77
async execute ( sql : string , opts ?: ExecuteOptions ) {
63
- return await this . query ( sql , opts ) ;
78
+ return await this . query ( this . adjustSQL ( sql ) , opts ) ;
64
79
}
65
80
66
81
async close ( ) {
@@ -137,6 +152,24 @@ export default class SQLiteAdapter implements DBAdapter {
137
152
138
153
return results ;
139
154
}
155
+
156
+ private adjustSQL ( sql : string ) : string {
157
+ return sql
158
+ . replace ( / O N C O N F L I C T O N C O N S T R A I N T ( \w * ) \b / , ( _ , constraint ) => {
159
+ let tableName = constraint . replace ( / _ p k e y $ / , '' ) ;
160
+ let pkColumns = this . primaryKeys . get ( tableName ) ;
161
+ if ( ! pkColumns ) {
162
+ throw new Error (
163
+ `could not determine primary key columns for constraint '${ constraint } '` ,
164
+ ) ;
165
+ }
166
+ return `ON CONFLICT (${ pkColumns } )` ;
167
+ } )
168
+ . replace ( / C R O S S J O I N L A T E R A L / g, 'CROSS JOIN' )
169
+ . replace ( / j s o n b _ a r r a y _ e a c h \( / g, 'json_each(' )
170
+ . replace ( / \. t e x t _ v a l u e / g, '.value' )
171
+ . replace ( / C O L L A T E " P O S I X " / g, '' ) ;
172
+ }
140
173
}
141
174
142
175
function assertNever ( value : never ) {
0 commit comments