@remix-run/data-table-postgres 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 +9 -16
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/adapter.d.ts +100 -39
- package/dist/lib/adapter.d.ts.map +1 -1
- package/dist/lib/adapter.js +559 -23
- 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 -7
- package/src/lib/adapter.ts +683 -84
- package/src/lib/sql-compiler.ts +66 -106
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-compiler.d.ts","sourceRoot":"","sources":["../../src/lib/sql-compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"sql-compiler.d.ts","sourceRoot":"","sources":["../../src/lib/sql-compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAa,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAe/F,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,yBAAyB,GAAG,YAAY,CAqG3F"}
|
package/dist/lib/sql-compiler.js
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
import { getTableName, getTablePrimaryKey } from '@remix-run/data-table';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { collectColumns as collectColumnsHelper, normalizeJoinType as normalizeJoinTypeHelper, quotePath as quotePathHelper, } from '@remix-run/data-table/sql-helpers';
|
|
3
|
+
export function compilePostgresOperation(operation) {
|
|
4
|
+
if (operation.kind === 'raw') {
|
|
5
|
+
return compileRawOperation(operation.sql);
|
|
5
6
|
}
|
|
6
7
|
let context = { values: [] };
|
|
7
|
-
if (
|
|
8
|
+
if (operation.kind === 'select') {
|
|
8
9
|
let selection = '*';
|
|
9
|
-
if (
|
|
10
|
-
selection =
|
|
10
|
+
if (operation.select !== '*') {
|
|
11
|
+
selection = operation.select
|
|
11
12
|
.map((field) => quotePath(field.column) + ' as ' + quoteIdentifier(field.alias))
|
|
12
13
|
.join(', ');
|
|
13
14
|
}
|
|
14
15
|
let text = 'select ' +
|
|
15
|
-
(
|
|
16
|
+
(operation.distinct ? 'distinct ' : '') +
|
|
16
17
|
selection +
|
|
17
|
-
compileFromClause(
|
|
18
|
-
compileWhereClause(
|
|
19
|
-
compileGroupByClause(
|
|
20
|
-
compileHavingClause(
|
|
21
|
-
compileOrderByClause(
|
|
22
|
-
compileLimitClause(
|
|
23
|
-
compileOffsetClause(
|
|
18
|
+
compileFromClause(operation.table, operation.joins, context) +
|
|
19
|
+
compileWhereClause(operation.where, context) +
|
|
20
|
+
compileGroupByClause(operation.groupBy) +
|
|
21
|
+
compileHavingClause(operation.having, context) +
|
|
22
|
+
compileOrderByClause(operation.orderBy) +
|
|
23
|
+
compileLimitClause(operation.limit) +
|
|
24
|
+
compileOffsetClause(operation.offset);
|
|
24
25
|
return {
|
|
25
26
|
text,
|
|
26
27
|
values: context.values,
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
|
-
if (
|
|
30
|
+
if (operation.kind === 'count' || operation.kind === 'exists') {
|
|
30
31
|
let inner = 'select 1' +
|
|
31
|
-
compileFromClause(
|
|
32
|
-
compileWhereClause(
|
|
33
|
-
compileGroupByClause(
|
|
34
|
-
compileHavingClause(
|
|
32
|
+
compileFromClause(operation.table, operation.joins, context) +
|
|
33
|
+
compileWhereClause(operation.where, context) +
|
|
34
|
+
compileGroupByClause(operation.groupBy) +
|
|
35
|
+
compileHavingClause(operation.having, context);
|
|
35
36
|
return {
|
|
36
37
|
text: 'select count(*) as ' +
|
|
37
38
|
quoteIdentifier('count') +
|
|
@@ -42,42 +43,42 @@ export function compilePostgresStatement(statement) {
|
|
|
42
43
|
values: context.values,
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
|
-
if (
|
|
46
|
-
return
|
|
46
|
+
if (operation.kind === 'insert') {
|
|
47
|
+
return compileInsertOperation(operation.table, operation.values, operation.returning, context);
|
|
47
48
|
}
|
|
48
|
-
if (
|
|
49
|
-
return
|
|
49
|
+
if (operation.kind === 'insertMany') {
|
|
50
|
+
return compileInsertManyOperation(operation.table, operation.values, operation.returning, context);
|
|
50
51
|
}
|
|
51
|
-
if (
|
|
52
|
-
let changes = Object.keys(
|
|
52
|
+
if (operation.kind === 'update') {
|
|
53
|
+
let changes = Object.keys(operation.changes);
|
|
53
54
|
let assignments = changes
|
|
54
|
-
.map((column) => quotePath(column) + ' = ' + pushValue(context,
|
|
55
|
+
.map((column) => quotePath(column) + ' = ' + pushValue(context, operation.changes[column]))
|
|
55
56
|
.join(', ');
|
|
56
57
|
return {
|
|
57
58
|
text: 'update ' +
|
|
58
|
-
quotePath(getTableName(
|
|
59
|
+
quotePath(getTableName(operation.table)) +
|
|
59
60
|
' set ' +
|
|
60
61
|
assignments +
|
|
61
|
-
compileWhereClause(
|
|
62
|
-
compileReturningClause(
|
|
62
|
+
compileWhereClause(operation.where, context) +
|
|
63
|
+
compileReturningClause(operation.returning),
|
|
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(
|
|
71
|
-
compileReturningClause(
|
|
70
|
+
quotePath(getTableName(operation.table)) +
|
|
71
|
+
compileWhereClause(operation.where, context) +
|
|
72
|
+
compileReturningClause(operation.returning),
|
|
72
73
|
values: context.values,
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
|
-
if (
|
|
76
|
-
return
|
|
76
|
+
if (operation.kind === 'upsert') {
|
|
77
|
+
return compileUpsertOperation(operation, context);
|
|
77
78
|
}
|
|
78
|
-
throw new Error('Unsupported
|
|
79
|
+
throw new Error('Unsupported operation kind');
|
|
79
80
|
}
|
|
80
|
-
function
|
|
81
|
+
function compileInsertOperation(table, values, returning, context) {
|
|
81
82
|
let columns = Object.keys(values);
|
|
82
83
|
if (columns.length === 0) {
|
|
83
84
|
return {
|
|
@@ -102,7 +103,7 @@ function compileInsertStatement(table, values, returning, context) {
|
|
|
102
103
|
values: context.values,
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
|
-
function
|
|
106
|
+
function compileInsertManyOperation(table, rows, returning, context) {
|
|
106
107
|
if (rows.length === 0) {
|
|
107
108
|
return {
|
|
108
109
|
text: 'select 0 where 1 = 0',
|
|
@@ -138,15 +139,15 @@ 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
148
|
let quotedInsertColumns = insertColumns.map((column) => quotePath(column));
|
|
148
|
-
let insertPlaceholders = insertColumns.map((column) => pushValue(context,
|
|
149
|
-
let updateValues =
|
|
149
|
+
let insertPlaceholders = insertColumns.map((column) => pushValue(context, operation.values[column]));
|
|
150
|
+
let updateValues = operation.update ?? operation.values;
|
|
150
151
|
let updateColumns = Object.keys(updateValues);
|
|
151
152
|
let onConflictClause = '';
|
|
152
153
|
if (updateColumns.length === 0) {
|
|
@@ -166,18 +167,18 @@ function compileUpsertStatement(statement, context) {
|
|
|
166
167
|
}
|
|
167
168
|
return {
|
|
168
169
|
text: 'insert into ' +
|
|
169
|
-
quotePath(getTableName(
|
|
170
|
+
quotePath(getTableName(operation.table)) +
|
|
170
171
|
' (' +
|
|
171
172
|
quotedInsertColumns.join(', ') +
|
|
172
173
|
') values (' +
|
|
173
174
|
insertPlaceholders.join(', ') +
|
|
174
175
|
')' +
|
|
175
176
|
onConflictClause +
|
|
176
|
-
compileReturningClause(
|
|
177
|
+
compileReturningClause(operation.returning),
|
|
177
178
|
values: context.values,
|
|
178
179
|
};
|
|
179
180
|
}
|
|
180
|
-
function
|
|
181
|
+
function compileRawOperation(statement) {
|
|
181
182
|
if (!statement.text.includes('?')) {
|
|
182
183
|
return {
|
|
183
184
|
text: statement.text,
|
|
@@ -344,49 +345,18 @@ function compileComparisonValue(predicate, context) {
|
|
|
344
345
|
return pushValue(context, predicate.value);
|
|
345
346
|
}
|
|
346
347
|
function normalizeJoinType(type) {
|
|
347
|
-
|
|
348
|
-
return 'left';
|
|
349
|
-
}
|
|
350
|
-
if (type === 'right') {
|
|
351
|
-
return 'right';
|
|
352
|
-
}
|
|
353
|
-
return 'inner';
|
|
348
|
+
return normalizeJoinTypeHelper(type);
|
|
354
349
|
}
|
|
355
350
|
function quoteIdentifier(value) {
|
|
356
351
|
return '"' + value.replace(/"/g, '""') + '"';
|
|
357
352
|
}
|
|
358
353
|
function quotePath(path) {
|
|
359
|
-
|
|
360
|
-
return '*';
|
|
361
|
-
}
|
|
362
|
-
let segments = path.split('.');
|
|
363
|
-
return segments
|
|
364
|
-
.map((segment) => {
|
|
365
|
-
if (segment === '*') {
|
|
366
|
-
return '*';
|
|
367
|
-
}
|
|
368
|
-
return quoteIdentifier(segment);
|
|
369
|
-
})
|
|
370
|
-
.join('.');
|
|
354
|
+
return quotePathHelper(path, quoteIdentifier);
|
|
371
355
|
}
|
|
372
356
|
function pushValue(context, value) {
|
|
373
357
|
context.values.push(value);
|
|
374
358
|
return '$' + String(context.values.length);
|
|
375
359
|
}
|
|
376
360
|
function collectColumns(rows) {
|
|
377
|
-
|
|
378
|
-
let seen = new Set();
|
|
379
|
-
for (let row of rows) {
|
|
380
|
-
for (let key in row) {
|
|
381
|
-
if (!Object.prototype.hasOwnProperty.call(row, key)) {
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
if (seen.has(key)) {
|
|
385
|
-
continue;
|
|
386
|
-
}
|
|
387
|
-
seen.add(key);
|
|
388
|
-
columns.push(key);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
return columns;
|
|
361
|
+
return collectColumnsHelper(rows);
|
|
392
362
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remix-run/data-table-postgres",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "PostgreSQL adapter for
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "PostgreSQL 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/pg": "^8.15.6",
|
|
32
32
|
"@typescript/native-preview": "7.0.0-dev.20251125.1",
|
|
33
33
|
"pg": "^8.16.3",
|
|
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
|
"pg": "^8.16.3"
|
|
@@ -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
|
@@ -1,8 +1 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
PostgresDatabaseAdapterOptions,
|
|
3
|
-
PostgresDatabaseClient,
|
|
4
|
-
PostgresDatabasePool,
|
|
5
|
-
PostgresQueryResult,
|
|
6
|
-
PostgresTransactionClient,
|
|
7
|
-
} from './lib/adapter.ts'
|
|
8
1
|
export { createPostgresDatabaseAdapter, PostgresDatabaseAdapter } from './lib/adapter.ts'
|