@remix-run/data-table-mysql 0.1.0 → 0.2.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 +9 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/adapter.d.ts +98 -35
- package/dist/lib/adapter.d.ts.map +1 -1
- package/dist/lib/adapter.js +547 -17
- 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 +47 -77
- package/package.json +6 -7
- package/src/index.ts +1 -8
- package/src/lib/adapter.ts +680 -68
- package/src/lib/sql-compiler.ts +60 -99
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 compileMysqlOperation(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 compileMysqlStatement(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,54 +69,54 @@ export function compileMysqlStatement(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, context)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
if (
|
|
77
|
-
return
|
|
76
|
+
if (operation.kind === 'insertMany') {
|
|
77
|
+
return compileInsertManyOperation(operation.table, operation.values, context)
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
if (
|
|
81
|
-
let columns = Object.keys(
|
|
80
|
+
if (operation.kind === 'update') {
|
|
81
|
+
let columns = Object.keys(operation.changes)
|
|
82
82
|
|
|
83
83
|
return {
|
|
84
84
|
text:
|
|
85
85
|
'update ' +
|
|
86
|
-
quotePath(getTableName(
|
|
86
|
+
quotePath(getTableName(operation.table)) +
|
|
87
87
|
' set ' +
|
|
88
88
|
columns
|
|
89
89
|
.map(
|
|
90
|
-
(column) => quotePath(column) + ' = ' + pushValue(context,
|
|
90
|
+
(column) => quotePath(column) + ' = ' + pushValue(context, operation.changes[column]),
|
|
91
91
|
)
|
|
92
92
|
.join(', ') +
|
|
93
|
-
compileWhereClause(
|
|
93
|
+
compileWhereClause(operation.where, context),
|
|
94
94
|
values: context.values,
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
if (
|
|
98
|
+
if (operation.kind === 'delete') {
|
|
99
99
|
return {
|
|
100
100
|
text:
|
|
101
101
|
'delete from ' +
|
|
102
|
-
quotePath(getTableName(
|
|
103
|
-
compileWhereClause(
|
|
102
|
+
quotePath(getTableName(operation.table)) +
|
|
103
|
+
compileWhereClause(operation.where, context),
|
|
104
104
|
values: context.values,
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
if (
|
|
109
|
-
return
|
|
108
|
+
if (operation.kind === 'upsert') {
|
|
109
|
+
return compileUpsertOperation(operation, context)
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
throw new Error('Unsupported
|
|
112
|
+
throw new Error('Unsupported operation kind')
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function
|
|
116
|
-
table:
|
|
115
|
+
function compileInsertOperation(
|
|
116
|
+
table: OperationTable,
|
|
117
117
|
values: Record<string, unknown>,
|
|
118
118
|
context: CompileContext,
|
|
119
|
-
):
|
|
119
|
+
): SqlStatement {
|
|
120
120
|
let columns = Object.keys(values)
|
|
121
121
|
|
|
122
122
|
if (columns.length === 0) {
|
|
@@ -139,11 +139,11 @@ function compileInsertStatement(
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
function
|
|
143
|
-
table:
|
|
142
|
+
function compileInsertManyOperation(
|
|
143
|
+
table: OperationTable,
|
|
144
144
|
rows: Record<string, unknown>[],
|
|
145
145
|
context: CompileContext,
|
|
146
|
-
):
|
|
146
|
+
): SqlStatement {
|
|
147
147
|
if (rows.length === 0) {
|
|
148
148
|
return {
|
|
149
149
|
text: 'select 0 where 1 = 0',
|
|
@@ -184,16 +184,16 @@ function compileInsertManyStatement(
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
function
|
|
188
|
-
let insertColumns = Object.keys(
|
|
187
|
+
function compileUpsertOperation(operation: UpsertOperation, context: CompileContext): SqlStatement {
|
|
188
|
+
let insertColumns = Object.keys(operation.values)
|
|
189
189
|
|
|
190
190
|
if (insertColumns.length === 0) {
|
|
191
191
|
throw new Error('upsert requires at least one value')
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
let updateValues =
|
|
194
|
+
let updateValues = operation.update ?? operation.values
|
|
195
195
|
let updateColumns = Object.keys(updateValues)
|
|
196
|
-
let fallbackNoopColumn = getTablePrimaryKey(
|
|
196
|
+
let fallbackNoopColumn = getTablePrimaryKey(operation.table)[0]
|
|
197
197
|
|
|
198
198
|
let onDuplicate =
|
|
199
199
|
updateColumns.length > 0
|
|
@@ -205,11 +205,11 @@ function compileUpsertStatement(statement: UpsertStatement, context: CompileCont
|
|
|
205
205
|
return {
|
|
206
206
|
text:
|
|
207
207
|
'insert into ' +
|
|
208
|
-
quotePath(getTableName(
|
|
208
|
+
quotePath(getTableName(operation.table)) +
|
|
209
209
|
' (' +
|
|
210
210
|
insertColumns.map((column) => quotePath(column)).join(', ') +
|
|
211
211
|
') values (' +
|
|
212
|
-
insertColumns.map((column) => pushValue(context,
|
|
212
|
+
insertColumns.map((column) => pushValue(context, operation.values[column])).join(', ') +
|
|
213
213
|
') on duplicate key update ' +
|
|
214
214
|
onDuplicate,
|
|
215
215
|
values: context.values,
|
|
@@ -217,7 +217,7 @@ function compileUpsertStatement(statement: UpsertStatement, context: CompileCont
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
function compileFromClause(
|
|
220
|
-
table:
|
|
220
|
+
table: OperationTable,
|
|
221
221
|
joins: JoinClause[],
|
|
222
222
|
context: CompileContext,
|
|
223
223
|
): string {
|
|
@@ -416,15 +416,7 @@ function compileComparisonValue(
|
|
|
416
416
|
}
|
|
417
417
|
|
|
418
418
|
function normalizeJoinType(type: string): string {
|
|
419
|
-
|
|
420
|
-
return 'left'
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
if (type === 'right') {
|
|
424
|
-
return 'right'
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return 'inner'
|
|
419
|
+
return normalizeJoinTypeHelper(type)
|
|
428
420
|
}
|
|
429
421
|
|
|
430
422
|
function quoteIdentifier(value: string): string {
|
|
@@ -432,20 +424,7 @@ function quoteIdentifier(value: string): string {
|
|
|
432
424
|
}
|
|
433
425
|
|
|
434
426
|
function quotePath(path: string): string {
|
|
435
|
-
|
|
436
|
-
return '*'
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
return path
|
|
440
|
-
.split('.')
|
|
441
|
-
.map((segment) => {
|
|
442
|
-
if (segment === '*') {
|
|
443
|
-
return '*'
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
return quoteIdentifier(segment)
|
|
447
|
-
})
|
|
448
|
-
.join('.')
|
|
427
|
+
return quotePathHelper(path, quoteIdentifier)
|
|
449
428
|
}
|
|
450
429
|
|
|
451
430
|
function pushValue(context: CompileContext, value: unknown): string {
|
|
@@ -454,23 +433,5 @@ function pushValue(context: CompileContext, value: unknown): string {
|
|
|
454
433
|
}
|
|
455
434
|
|
|
456
435
|
function collectColumns(rows: Record<string, unknown>[]): string[] {
|
|
457
|
-
|
|
458
|
-
let seen = new Set<string>()
|
|
459
|
-
|
|
460
|
-
for (let row of rows) {
|
|
461
|
-
for (let key in row) {
|
|
462
|
-
if (!Object.prototype.hasOwnProperty.call(row, key)) {
|
|
463
|
-
continue
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
if (seen.has(key)) {
|
|
467
|
-
continue
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
seen.add(key)
|
|
471
|
-
columns.push(key)
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
return columns
|
|
436
|
+
return collectColumnsHelper(rows)
|
|
476
437
|
}
|