@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/dist/lib/sql-compiler.js
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
import { getTableName, getTablePrimaryKey } from '@remix-run/data-table';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { collectColumns as collectColumnsHelper, normalizeJoinType as normalizeJoinTypeHelper, quotePath as quotePathHelper, } from '@remix-run/data-table/sql-helpers';
|
|
3
|
+
export function compileMysqlOperation(operation) {
|
|
4
|
+
if (operation.kind === 'raw') {
|
|
4
5
|
return {
|
|
5
|
-
text:
|
|
6
|
-
values: [...
|
|
6
|
+
text: operation.sql.text,
|
|
7
|
+
values: [...operation.sql.values],
|
|
7
8
|
};
|
|
8
9
|
}
|
|
9
10
|
let context = { values: [] };
|
|
10
|
-
if (
|
|
11
|
+
if (operation.kind === 'select') {
|
|
11
12
|
let selection = '*';
|
|
12
|
-
if (
|
|
13
|
-
selection =
|
|
13
|
+
if (operation.select !== '*') {
|
|
14
|
+
selection = operation.select
|
|
14
15
|
.map((field) => quotePath(field.column) + ' as ' + quoteIdentifier(field.alias))
|
|
15
16
|
.join(', ');
|
|
16
17
|
}
|
|
17
18
|
return {
|
|
18
19
|
text: 'select ' +
|
|
19
|
-
(
|
|
20
|
+
(operation.distinct ? 'distinct ' : '') +
|
|
20
21
|
selection +
|
|
21
|
-
compileFromClause(
|
|
22
|
-
compileWhereClause(
|
|
23
|
-
compileGroupByClause(
|
|
24
|
-
compileHavingClause(
|
|
25
|
-
compileOrderByClause(
|
|
26
|
-
compileLimitClause(
|
|
27
|
-
compileOffsetClause(
|
|
22
|
+
compileFromClause(operation.table, operation.joins, context) +
|
|
23
|
+
compileWhereClause(operation.where, context) +
|
|
24
|
+
compileGroupByClause(operation.groupBy) +
|
|
25
|
+
compileHavingClause(operation.having, context) +
|
|
26
|
+
compileOrderByClause(operation.orderBy) +
|
|
27
|
+
compileLimitClause(operation.limit) +
|
|
28
|
+
compileOffsetClause(operation.offset),
|
|
28
29
|
values: context.values,
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
|
-
if (
|
|
32
|
+
if (operation.kind === 'count' || operation.kind === 'exists') {
|
|
32
33
|
let inner = 'select 1' +
|
|
33
|
-
compileFromClause(
|
|
34
|
-
compileWhereClause(
|
|
35
|
-
compileGroupByClause(
|
|
36
|
-
compileHavingClause(
|
|
34
|
+
compileFromClause(operation.table, operation.joins, context) +
|
|
35
|
+
compileWhereClause(operation.where, context) +
|
|
36
|
+
compileGroupByClause(operation.groupBy) +
|
|
37
|
+
compileHavingClause(operation.having, context);
|
|
37
38
|
return {
|
|
38
39
|
text: 'select count(*) as ' +
|
|
39
40
|
quoteIdentifier('count') +
|
|
@@ -44,39 +45,39 @@ export function compileMysqlStatement(statement) {
|
|
|
44
45
|
values: context.values,
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
|
-
if (
|
|
48
|
-
return
|
|
48
|
+
if (operation.kind === 'insert') {
|
|
49
|
+
return compileInsertOperation(operation.table, operation.values, context);
|
|
49
50
|
}
|
|
50
|
-
if (
|
|
51
|
-
return
|
|
51
|
+
if (operation.kind === 'insertMany') {
|
|
52
|
+
return compileInsertManyOperation(operation.table, operation.values, context);
|
|
52
53
|
}
|
|
53
|
-
if (
|
|
54
|
-
let columns = Object.keys(
|
|
54
|
+
if (operation.kind === 'update') {
|
|
55
|
+
let columns = Object.keys(operation.changes);
|
|
55
56
|
return {
|
|
56
57
|
text: 'update ' +
|
|
57
|
-
quotePath(getTableName(
|
|
58
|
+
quotePath(getTableName(operation.table)) +
|
|
58
59
|
' set ' +
|
|
59
60
|
columns
|
|
60
|
-
.map((column) => quotePath(column) + ' = ' + pushValue(context,
|
|
61
|
+
.map((column) => quotePath(column) + ' = ' + pushValue(context, operation.changes[column]))
|
|
61
62
|
.join(', ') +
|
|
62
|
-
compileWhereClause(
|
|
63
|
+
compileWhereClause(operation.where, context),
|
|
63
64
|
values: context.values,
|
|
64
65
|
};
|
|
65
66
|
}
|
|
66
|
-
if (
|
|
67
|
+
if (operation.kind === 'delete') {
|
|
67
68
|
return {
|
|
68
69
|
text: 'delete from ' +
|
|
69
|
-
quotePath(getTableName(
|
|
70
|
-
compileWhereClause(
|
|
70
|
+
quotePath(getTableName(operation.table)) +
|
|
71
|
+
compileWhereClause(operation.where, context),
|
|
71
72
|
values: context.values,
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
|
-
if (
|
|
75
|
-
return
|
|
75
|
+
if (operation.kind === 'upsert') {
|
|
76
|
+
return compileUpsertOperation(operation, context);
|
|
76
77
|
}
|
|
77
|
-
throw new Error('Unsupported
|
|
78
|
+
throw new Error('Unsupported operation kind');
|
|
78
79
|
}
|
|
79
|
-
function
|
|
80
|
+
function compileInsertOperation(table, values, context) {
|
|
80
81
|
let columns = Object.keys(values);
|
|
81
82
|
if (columns.length === 0) {
|
|
82
83
|
return {
|
|
@@ -95,7 +96,7 @@ function compileInsertStatement(table, values, context) {
|
|
|
95
96
|
values: context.values,
|
|
96
97
|
};
|
|
97
98
|
}
|
|
98
|
-
function
|
|
99
|
+
function compileInsertManyOperation(table, rows, context) {
|
|
99
100
|
if (rows.length === 0) {
|
|
100
101
|
return {
|
|
101
102
|
text: 'select 0 where 1 = 0',
|
|
@@ -127,14 +128,14 @@ function compileInsertManyStatement(table, rows, context) {
|
|
|
127
128
|
values: context.values,
|
|
128
129
|
};
|
|
129
130
|
}
|
|
130
|
-
function
|
|
131
|
-
let insertColumns = Object.keys(
|
|
131
|
+
function compileUpsertOperation(operation, context) {
|
|
132
|
+
let insertColumns = Object.keys(operation.values);
|
|
132
133
|
if (insertColumns.length === 0) {
|
|
133
134
|
throw new Error('upsert requires at least one value');
|
|
134
135
|
}
|
|
135
|
-
let updateValues =
|
|
136
|
+
let updateValues = operation.update ?? operation.values;
|
|
136
137
|
let updateColumns = Object.keys(updateValues);
|
|
137
|
-
let fallbackNoopColumn = getTablePrimaryKey(
|
|
138
|
+
let fallbackNoopColumn = getTablePrimaryKey(operation.table)[0];
|
|
138
139
|
let onDuplicate = updateColumns.length > 0
|
|
139
140
|
? updateColumns
|
|
140
141
|
.map((column) => quotePath(column) + ' = ' + pushValue(context, updateValues[column]))
|
|
@@ -142,11 +143,11 @@ function compileUpsertStatement(statement, context) {
|
|
|
142
143
|
: quotePath(fallbackNoopColumn) + ' = ' + quotePath(fallbackNoopColumn);
|
|
143
144
|
return {
|
|
144
145
|
text: 'insert into ' +
|
|
145
|
-
quotePath(getTableName(
|
|
146
|
+
quotePath(getTableName(operation.table)) +
|
|
146
147
|
' (' +
|
|
147
148
|
insertColumns.map((column) => quotePath(column)).join(', ') +
|
|
148
149
|
') values (' +
|
|
149
|
-
insertColumns.map((column) => pushValue(context,
|
|
150
|
+
insertColumns.map((column) => pushValue(context, operation.values[column])).join(', ') +
|
|
150
151
|
') on duplicate key update ' +
|
|
151
152
|
onDuplicate,
|
|
152
153
|
values: context.values,
|
|
@@ -291,49 +292,18 @@ function compileComparisonValue(predicate, context) {
|
|
|
291
292
|
return pushValue(context, predicate.value);
|
|
292
293
|
}
|
|
293
294
|
function normalizeJoinType(type) {
|
|
294
|
-
|
|
295
|
-
return 'left';
|
|
296
|
-
}
|
|
297
|
-
if (type === 'right') {
|
|
298
|
-
return 'right';
|
|
299
|
-
}
|
|
300
|
-
return 'inner';
|
|
295
|
+
return normalizeJoinTypeHelper(type);
|
|
301
296
|
}
|
|
302
297
|
function quoteIdentifier(value) {
|
|
303
298
|
return '`' + value.replace(/`/g, '``') + '`';
|
|
304
299
|
}
|
|
305
300
|
function quotePath(path) {
|
|
306
|
-
|
|
307
|
-
return '*';
|
|
308
|
-
}
|
|
309
|
-
return path
|
|
310
|
-
.split('.')
|
|
311
|
-
.map((segment) => {
|
|
312
|
-
if (segment === '*') {
|
|
313
|
-
return '*';
|
|
314
|
-
}
|
|
315
|
-
return quoteIdentifier(segment);
|
|
316
|
-
})
|
|
317
|
-
.join('.');
|
|
301
|
+
return quotePathHelper(path, quoteIdentifier);
|
|
318
302
|
}
|
|
319
303
|
function pushValue(context, value) {
|
|
320
304
|
context.values.push(value);
|
|
321
305
|
return '?';
|
|
322
306
|
}
|
|
323
307
|
function collectColumns(rows) {
|
|
324
|
-
|
|
325
|
-
let seen = new Set();
|
|
326
|
-
for (let row of rows) {
|
|
327
|
-
for (let key in row) {
|
|
328
|
-
if (!Object.prototype.hasOwnProperty.call(row, key)) {
|
|
329
|
-
continue;
|
|
330
|
-
}
|
|
331
|
-
if (seen.has(key)) {
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
seen.add(key);
|
|
335
|
-
columns.push(key);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
return columns;
|
|
308
|
+
return collectColumnsHelper(rows);
|
|
339
309
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remix-run/data-table-mysql",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MySQL adapter for
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "MySQL adapter for remix/data-table",
|
|
5
5
|
"author": "Michael Jackson <mjijackson@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -30,11 +30,10 @@
|
|
|
30
30
|
"@types/node": "^24.6.0",
|
|
31
31
|
"@typescript/native-preview": "7.0.0-dev.20251125.1",
|
|
32
32
|
"mysql2": "^3.15.3",
|
|
33
|
-
"@remix-run/data-table": "0.
|
|
34
|
-
"@remix-run/data-schema": "0.1.0"
|
|
33
|
+
"@remix-run/data-table": "0.2.0"
|
|
35
34
|
},
|
|
36
35
|
"dependencies": {
|
|
37
|
-
"@remix-run/data-table": "^0.
|
|
36
|
+
"@remix-run/data-table": "^0.2.0"
|
|
38
37
|
},
|
|
39
38
|
"peerDependencies": {
|
|
40
39
|
"mysql2": "^3.15.3"
|
|
@@ -54,8 +53,8 @@
|
|
|
54
53
|
"scripts": {
|
|
55
54
|
"build": "tsgo -p tsconfig.build.json",
|
|
56
55
|
"clean": "git clean -fdX",
|
|
57
|
-
"test": "node --
|
|
58
|
-
"test:coverage": "node --
|
|
56
|
+
"test": "node --test",
|
|
57
|
+
"test:coverage": "node --experimental-test-coverage --test-coverage-include='src/**/*.ts' --test-coverage-lines=90 --test-coverage-branches=90 --test-coverage-functions=90 --test ./src/lib/adapter.test.ts ./src/lib/sql-compiler.test.ts",
|
|
59
58
|
"typecheck": "tsgo --noEmit"
|
|
60
59
|
}
|
|
61
60
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
MysqlDatabaseAdapterOptions,
|
|
3
|
-
MysqlDatabaseConnection,
|
|
4
|
-
MysqlDatabasePool,
|
|
5
|
-
MysqlQueryResponse,
|
|
6
|
-
MysqlQueryResultHeader,
|
|
7
|
-
MysqlQueryRows,
|
|
8
|
-
} from './lib/adapter.ts'
|
|
1
|
+
export type { MysqlDatabaseAdapterOptions } from './lib/adapter.ts'
|
|
9
2
|
export { createMysqlDatabaseAdapter, MysqlDatabaseAdapter } from './lib/adapter.ts'
|