@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/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 compileSqliteOperation(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,41 +45,41 @@ export function compileSqliteStatement(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, operation.returning, context);
|
|
49
50
|
}
|
|
50
|
-
if (
|
|
51
|
-
return
|
|
51
|
+
if (operation.kind === 'insertMany') {
|
|
52
|
+
return compileInsertManyOperation(operation.table, operation.values, operation.returning, 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
|
-
compileReturningClause(
|
|
63
|
+
compileWhereClause(operation.where, context) +
|
|
64
|
+
compileReturningClause(operation.returning),
|
|
64
65
|
values: context.values,
|
|
65
66
|
};
|
|
66
67
|
}
|
|
67
|
-
if (
|
|
68
|
+
if (operation.kind === 'delete') {
|
|
68
69
|
return {
|
|
69
70
|
text: 'delete from ' +
|
|
70
|
-
quotePath(getTableName(
|
|
71
|
-
compileWhereClause(
|
|
72
|
-
compileReturningClause(
|
|
71
|
+
quotePath(getTableName(operation.table)) +
|
|
72
|
+
compileWhereClause(operation.where, context) +
|
|
73
|
+
compileReturningClause(operation.returning),
|
|
73
74
|
values: context.values,
|
|
74
75
|
};
|
|
75
76
|
}
|
|
76
|
-
if (
|
|
77
|
-
return
|
|
77
|
+
if (operation.kind === 'upsert') {
|
|
78
|
+
return compileUpsertOperation(operation, context);
|
|
78
79
|
}
|
|
79
|
-
throw new Error('Unsupported
|
|
80
|
+
throw new Error('Unsupported operation kind');
|
|
80
81
|
}
|
|
81
|
-
function
|
|
82
|
+
function compileInsertOperation(table, values, returning, context) {
|
|
82
83
|
let columns = Object.keys(values);
|
|
83
84
|
if (columns.length === 0) {
|
|
84
85
|
return {
|
|
@@ -101,7 +102,7 @@ function compileInsertStatement(table, values, returning, context) {
|
|
|
101
102
|
values: context.values,
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
|
-
function
|
|
105
|
+
function compileInsertManyOperation(table, rows, returning, context) {
|
|
105
106
|
if (rows.length === 0) {
|
|
106
107
|
return {
|
|
107
108
|
text: 'select 0 where 1 = 0',
|
|
@@ -138,13 +139,13 @@ function compileInsertManyStatement(table, rows, returning, context) {
|
|
|
138
139
|
values: context.values,
|
|
139
140
|
};
|
|
140
141
|
}
|
|
141
|
-
function
|
|
142
|
-
let insertColumns = Object.keys(
|
|
143
|
-
let conflictTarget =
|
|
142
|
+
function compileUpsertOperation(operation, context) {
|
|
143
|
+
let insertColumns = Object.keys(operation.values);
|
|
144
|
+
let conflictTarget = operation.conflictTarget ?? [...getTablePrimaryKey(operation.table)];
|
|
144
145
|
if (insertColumns.length === 0) {
|
|
145
146
|
throw new Error('upsert requires at least one value');
|
|
146
147
|
}
|
|
147
|
-
let updateValues =
|
|
148
|
+
let updateValues = operation.update ?? operation.values;
|
|
148
149
|
let updateColumns = Object.keys(updateValues);
|
|
149
150
|
let conflictClause = '';
|
|
150
151
|
if (updateColumns.length === 0) {
|
|
@@ -164,14 +165,14 @@ function compileUpsertStatement(statement, context) {
|
|
|
164
165
|
}
|
|
165
166
|
return {
|
|
166
167
|
text: 'insert into ' +
|
|
167
|
-
quotePath(getTableName(
|
|
168
|
+
quotePath(getTableName(operation.table)) +
|
|
168
169
|
' (' +
|
|
169
170
|
insertColumns.map((column) => quotePath(column)).join(', ') +
|
|
170
171
|
') values (' +
|
|
171
|
-
insertColumns.map((column) => pushValue(context,
|
|
172
|
+
insertColumns.map((column) => pushValue(context, operation.values[column])).join(', ') +
|
|
172
173
|
')' +
|
|
173
174
|
conflictClause +
|
|
174
|
-
compileReturningClause(
|
|
175
|
+
compileReturningClause(operation.returning),
|
|
175
176
|
values: context.values,
|
|
176
177
|
};
|
|
177
178
|
}
|
|
@@ -323,30 +324,13 @@ function compileComparisonValue(predicate, context) {
|
|
|
323
324
|
return pushValue(context, predicate.value);
|
|
324
325
|
}
|
|
325
326
|
function normalizeJoinType(type) {
|
|
326
|
-
|
|
327
|
-
return 'left';
|
|
328
|
-
}
|
|
329
|
-
if (type === 'right') {
|
|
330
|
-
return 'right';
|
|
331
|
-
}
|
|
332
|
-
return 'inner';
|
|
327
|
+
return normalizeJoinTypeHelper(type);
|
|
333
328
|
}
|
|
334
329
|
function quoteIdentifier(value) {
|
|
335
330
|
return '"' + value.replace(/"/g, '""') + '"';
|
|
336
331
|
}
|
|
337
332
|
function quotePath(path) {
|
|
338
|
-
|
|
339
|
-
return '*';
|
|
340
|
-
}
|
|
341
|
-
return path
|
|
342
|
-
.split('.')
|
|
343
|
-
.map((segment) => {
|
|
344
|
-
if (segment === '*') {
|
|
345
|
-
return '*';
|
|
346
|
-
}
|
|
347
|
-
return quoteIdentifier(segment);
|
|
348
|
-
})
|
|
349
|
-
.join('.');
|
|
333
|
+
return quotePathHelper(path, quoteIdentifier);
|
|
350
334
|
}
|
|
351
335
|
function pushValue(context, value) {
|
|
352
336
|
context.values.push(normalizeBoundValue(value));
|
|
@@ -359,19 +343,5 @@ function normalizeBoundValue(value) {
|
|
|
359
343
|
return value;
|
|
360
344
|
}
|
|
361
345
|
function collectColumns(rows) {
|
|
362
|
-
|
|
363
|
-
let seen = new Set();
|
|
364
|
-
for (let row of rows) {
|
|
365
|
-
for (let key in row) {
|
|
366
|
-
if (!Object.prototype.hasOwnProperty.call(row, key)) {
|
|
367
|
-
continue;
|
|
368
|
-
}
|
|
369
|
-
if (seen.has(key)) {
|
|
370
|
-
continue;
|
|
371
|
-
}
|
|
372
|
-
seen.add(key);
|
|
373
|
-
columns.push(key);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return columns;
|
|
346
|
+
return collectColumnsHelper(rows);
|
|
377
347
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remix-run/data-table-sqlite",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "SQLite adapter for
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "SQLite adapter for remix/data-table",
|
|
5
5
|
"author": "Michael Jackson <mjijackson@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -31,11 +31,10 @@
|
|
|
31
31
|
"@types/node": "^24.6.0",
|
|
32
32
|
"@typescript/native-preview": "7.0.0-dev.20251125.1",
|
|
33
33
|
"better-sqlite3": "^12.4.1",
|
|
34
|
-
"@remix-run/data-
|
|
35
|
-
"@remix-run/data-table": "0.1.0"
|
|
34
|
+
"@remix-run/data-table": "0.2.0"
|
|
36
35
|
},
|
|
37
36
|
"dependencies": {
|
|
38
|
-
"@remix-run/data-table": "^0.
|
|
37
|
+
"@remix-run/data-table": "^0.2.0"
|
|
39
38
|
},
|
|
40
39
|
"peerDependencies": {
|
|
41
40
|
"better-sqlite3": "^12.4.1"
|
|
@@ -55,8 +54,8 @@
|
|
|
55
54
|
"scripts": {
|
|
56
55
|
"build": "tsgo -p tsconfig.build.json",
|
|
57
56
|
"clean": "git clean -fdX",
|
|
58
|
-
"test": "node --
|
|
59
|
-
"test:coverage": "node --
|
|
57
|
+
"test": "node --test",
|
|
58
|
+
"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",
|
|
60
59
|
"typecheck": "tsgo --noEmit"
|
|
61
60
|
}
|
|
62
61
|
}
|
package/src/index.ts
CHANGED