@remix-run/data-table-sqlite 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -13
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/adapter.d.ts +87 -14
- package/dist/lib/adapter.d.ts.map +1 -1
- package/dist/lib/adapter.js +507 -26
- package/dist/lib/sql-compiler.d.ts +2 -7
- package/dist/lib/sql-compiler.d.ts.map +1 -1
- package/dist/lib/sql-compiler.js +50 -80
- package/package.json +6 -7
- package/src/index.ts +0 -1
- package/src/lib/adapter.ts +610 -53
- package/src/lib/sql-compiler.ts +66 -105
package/src/lib/sql-compiler.ts
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import { getTableName, getTablePrimaryKey } from '@remix-run/data-table'
|
|
2
|
-
import type {
|
|
2
|
+
import type { DataManipulationOperation, Predicate, SqlStatement } from '@remix-run/data-table'
|
|
3
|
+
import {
|
|
4
|
+
collectColumns as collectColumnsHelper,
|
|
5
|
+
normalizeJoinType as normalizeJoinTypeHelper,
|
|
6
|
+
quotePath as quotePathHelper,
|
|
7
|
+
} from '@remix-run/data-table/sql-helpers'
|
|
3
8
|
|
|
4
|
-
type JoinClause = Extract<
|
|
5
|
-
type
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
type CompiledSql = {
|
|
9
|
-
text: string
|
|
10
|
-
values: unknown[]
|
|
11
|
-
}
|
|
9
|
+
type JoinClause = Extract<DataManipulationOperation, { kind: 'select' }>['joins'][number]
|
|
10
|
+
type UpsertOperation = Extract<DataManipulationOperation, { kind: 'upsert' }>
|
|
11
|
+
type OperationTable = Extract<DataManipulationOperation, { kind: 'select' }>['table']
|
|
12
12
|
|
|
13
13
|
type CompileContext = {
|
|
14
14
|
values: unknown[]
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export function
|
|
18
|
-
if (
|
|
17
|
+
export function compileSqliteOperation(operation: DataManipulationOperation): SqlStatement {
|
|
18
|
+
if (operation.kind === 'raw') {
|
|
19
19
|
return {
|
|
20
|
-
text:
|
|
21
|
-
values: [...
|
|
20
|
+
text: operation.sql.text,
|
|
21
|
+
values: [...operation.sql.values],
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
let context: CompileContext = { values: [] }
|
|
26
26
|
|
|
27
|
-
if (
|
|
27
|
+
if (operation.kind === 'select') {
|
|
28
28
|
let selection = '*'
|
|
29
29
|
|
|
30
|
-
if (
|
|
31
|
-
selection =
|
|
30
|
+
if (operation.select !== '*') {
|
|
31
|
+
selection = operation.select
|
|
32
32
|
.map((field) => quotePath(field.column) + ' as ' + quoteIdentifier(field.alias))
|
|
33
33
|
.join(', ')
|
|
34
34
|
}
|
|
@@ -36,26 +36,26 @@ export function compileSqliteStatement(statement: AdapterStatement): CompiledSql
|
|
|
36
36
|
return {
|
|
37
37
|
text:
|
|
38
38
|
'select ' +
|
|
39
|
-
(
|
|
39
|
+
(operation.distinct ? 'distinct ' : '') +
|
|
40
40
|
selection +
|
|
41
|
-
compileFromClause(
|
|
42
|
-
compileWhereClause(
|
|
43
|
-
compileGroupByClause(
|
|
44
|
-
compileHavingClause(
|
|
45
|
-
compileOrderByClause(
|
|
46
|
-
compileLimitClause(
|
|
47
|
-
compileOffsetClause(
|
|
41
|
+
compileFromClause(operation.table, operation.joins, context) +
|
|
42
|
+
compileWhereClause(operation.where, context) +
|
|
43
|
+
compileGroupByClause(operation.groupBy) +
|
|
44
|
+
compileHavingClause(operation.having, context) +
|
|
45
|
+
compileOrderByClause(operation.orderBy) +
|
|
46
|
+
compileLimitClause(operation.limit) +
|
|
47
|
+
compileOffsetClause(operation.offset),
|
|
48
48
|
values: context.values,
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (
|
|
52
|
+
if (operation.kind === 'count' || operation.kind === 'exists') {
|
|
53
53
|
let inner =
|
|
54
54
|
'select 1' +
|
|
55
|
-
compileFromClause(
|
|
56
|
-
compileWhereClause(
|
|
57
|
-
compileGroupByClause(
|
|
58
|
-
compileHavingClause(
|
|
55
|
+
compileFromClause(operation.table, operation.joins, context) +
|
|
56
|
+
compileWhereClause(operation.where, context) +
|
|
57
|
+
compileGroupByClause(operation.groupBy) +
|
|
58
|
+
compileHavingClause(operation.having, context)
|
|
59
59
|
|
|
60
60
|
return {
|
|
61
61
|
text:
|
|
@@ -69,62 +69,62 @@ export function compileSqliteStatement(statement: AdapterStatement): CompiledSql
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
if (
|
|
73
|
-
return
|
|
72
|
+
if (operation.kind === 'insert') {
|
|
73
|
+
return compileInsertOperation(operation.table, operation.values, operation.returning, context)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
if (
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
if (operation.kind === 'insertMany') {
|
|
77
|
+
return compileInsertManyOperation(
|
|
78
|
+
operation.table,
|
|
79
|
+
operation.values,
|
|
80
|
+
operation.returning,
|
|
81
81
|
context,
|
|
82
82
|
)
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
if (
|
|
86
|
-
let columns = Object.keys(
|
|
85
|
+
if (operation.kind === 'update') {
|
|
86
|
+
let columns = Object.keys(operation.changes)
|
|
87
87
|
|
|
88
88
|
return {
|
|
89
89
|
text:
|
|
90
90
|
'update ' +
|
|
91
|
-
quotePath(getTableName(
|
|
91
|
+
quotePath(getTableName(operation.table)) +
|
|
92
92
|
' set ' +
|
|
93
93
|
columns
|
|
94
94
|
.map(
|
|
95
|
-
(column) => quotePath(column) + ' = ' + pushValue(context,
|
|
95
|
+
(column) => quotePath(column) + ' = ' + pushValue(context, operation.changes[column]),
|
|
96
96
|
)
|
|
97
97
|
.join(', ') +
|
|
98
|
-
compileWhereClause(
|
|
99
|
-
compileReturningClause(
|
|
98
|
+
compileWhereClause(operation.where, context) +
|
|
99
|
+
compileReturningClause(operation.returning),
|
|
100
100
|
values: context.values,
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
if (
|
|
104
|
+
if (operation.kind === 'delete') {
|
|
105
105
|
return {
|
|
106
106
|
text:
|
|
107
107
|
'delete from ' +
|
|
108
|
-
quotePath(getTableName(
|
|
109
|
-
compileWhereClause(
|
|
110
|
-
compileReturningClause(
|
|
108
|
+
quotePath(getTableName(operation.table)) +
|
|
109
|
+
compileWhereClause(operation.where, context) +
|
|
110
|
+
compileReturningClause(operation.returning),
|
|
111
111
|
values: context.values,
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
if (
|
|
116
|
-
return
|
|
115
|
+
if (operation.kind === 'upsert') {
|
|
116
|
+
return compileUpsertOperation(operation, context)
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
throw new Error('Unsupported
|
|
119
|
+
throw new Error('Unsupported operation kind')
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
function
|
|
123
|
-
table:
|
|
122
|
+
function compileInsertOperation(
|
|
123
|
+
table: OperationTable,
|
|
124
124
|
values: Record<string, unknown>,
|
|
125
125
|
returning: '*' | string[] | undefined,
|
|
126
126
|
context: CompileContext,
|
|
127
|
-
):
|
|
127
|
+
): SqlStatement {
|
|
128
128
|
let columns = Object.keys(values)
|
|
129
129
|
|
|
130
130
|
if (columns.length === 0) {
|
|
@@ -152,12 +152,12 @@ function compileInsertStatement(
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
function
|
|
156
|
-
table:
|
|
155
|
+
function compileInsertManyOperation(
|
|
156
|
+
table: OperationTable,
|
|
157
157
|
rows: Record<string, unknown>[],
|
|
158
158
|
returning: '*' | string[] | undefined,
|
|
159
159
|
context: CompileContext,
|
|
160
|
-
):
|
|
160
|
+
): SqlStatement {
|
|
161
161
|
if (rows.length === 0) {
|
|
162
162
|
return {
|
|
163
163
|
text: 'select 0 where 1 = 0',
|
|
@@ -203,15 +203,15 @@ function compileInsertManyStatement(
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
function
|
|
207
|
-
let insertColumns = Object.keys(
|
|
208
|
-
let conflictTarget =
|
|
206
|
+
function compileUpsertOperation(operation: UpsertOperation, context: CompileContext): SqlStatement {
|
|
207
|
+
let insertColumns = Object.keys(operation.values)
|
|
208
|
+
let conflictTarget = operation.conflictTarget ?? [...getTablePrimaryKey(operation.table)]
|
|
209
209
|
|
|
210
210
|
if (insertColumns.length === 0) {
|
|
211
211
|
throw new Error('upsert requires at least one value')
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
let updateValues =
|
|
214
|
+
let updateValues = operation.update ?? operation.values
|
|
215
215
|
let updateColumns = Object.keys(updateValues)
|
|
216
216
|
|
|
217
217
|
let conflictClause = ''
|
|
@@ -234,20 +234,20 @@ function compileUpsertStatement(statement: UpsertStatement, context: CompileCont
|
|
|
234
234
|
return {
|
|
235
235
|
text:
|
|
236
236
|
'insert into ' +
|
|
237
|
-
quotePath(getTableName(
|
|
237
|
+
quotePath(getTableName(operation.table)) +
|
|
238
238
|
' (' +
|
|
239
239
|
insertColumns.map((column) => quotePath(column)).join(', ') +
|
|
240
240
|
') values (' +
|
|
241
|
-
insertColumns.map((column) => pushValue(context,
|
|
241
|
+
insertColumns.map((column) => pushValue(context, operation.values[column])).join(', ') +
|
|
242
242
|
')' +
|
|
243
243
|
conflictClause +
|
|
244
|
-
compileReturningClause(
|
|
244
|
+
compileReturningClause(operation.returning),
|
|
245
245
|
values: context.values,
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
function compileFromClause(
|
|
250
|
-
table:
|
|
250
|
+
table: OperationTable,
|
|
251
251
|
joins: JoinClause[],
|
|
252
252
|
context: CompileContext,
|
|
253
253
|
): string {
|
|
@@ -458,15 +458,7 @@ function compileComparisonValue(
|
|
|
458
458
|
}
|
|
459
459
|
|
|
460
460
|
function normalizeJoinType(type: string): string {
|
|
461
|
-
|
|
462
|
-
return 'left'
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
if (type === 'right') {
|
|
466
|
-
return 'right'
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
return 'inner'
|
|
461
|
+
return normalizeJoinTypeHelper(type)
|
|
470
462
|
}
|
|
471
463
|
|
|
472
464
|
function quoteIdentifier(value: string): string {
|
|
@@ -474,20 +466,7 @@ function quoteIdentifier(value: string): string {
|
|
|
474
466
|
}
|
|
475
467
|
|
|
476
468
|
function quotePath(path: string): string {
|
|
477
|
-
|
|
478
|
-
return '*'
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
return path
|
|
482
|
-
.split('.')
|
|
483
|
-
.map((segment) => {
|
|
484
|
-
if (segment === '*') {
|
|
485
|
-
return '*'
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
return quoteIdentifier(segment)
|
|
489
|
-
})
|
|
490
|
-
.join('.')
|
|
469
|
+
return quotePathHelper(path, quoteIdentifier)
|
|
491
470
|
}
|
|
492
471
|
|
|
493
472
|
function pushValue(context: CompileContext, value: unknown): string {
|
|
@@ -504,23 +483,5 @@ function normalizeBoundValue(value: unknown): unknown {
|
|
|
504
483
|
}
|
|
505
484
|
|
|
506
485
|
function collectColumns(rows: Record<string, unknown>[]): string[] {
|
|
507
|
-
|
|
508
|
-
let seen = new Set<string>()
|
|
509
|
-
|
|
510
|
-
for (let row of rows) {
|
|
511
|
-
for (let key in row) {
|
|
512
|
-
if (!Object.prototype.hasOwnProperty.call(row, key)) {
|
|
513
|
-
continue
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
if (seen.has(key)) {
|
|
517
|
-
continue
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
seen.add(key)
|
|
521
|
-
columns.push(key)
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
return columns
|
|
486
|
+
return collectColumnsHelper(rows)
|
|
526
487
|
}
|