@remix-run/data-table-postgres 0.3.1 → 0.5.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 +41 -17
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/database.d.ts +35 -0
- package/dist/lib/database.d.ts.map +1 -0
- package/dist/lib/database.js +31 -0
- package/dist/lib/{adapter.d.ts → driver.d.ts} +50 -44
- package/dist/lib/driver.d.ts.map +1 -0
- package/dist/lib/driver.js +577 -0
- package/dist/lib/sql-compiler.d.ts +2 -1
- package/dist/lib/sql-compiler.d.ts.map +1 -1
- package/dist/lib/sql-compiler.js +179 -13
- package/package.json +12 -12
- package/src/index.ts +3 -1
- package/src/lib/database.ts +45 -0
- package/src/lib/driver.ts +760 -0
- package/src/lib/sql-compiler.ts +235 -15
- package/dist/lib/adapter.d.ts.map +0 -1
- package/dist/lib/adapter.js +0 -735
- package/src/lib/adapter.ts +0 -925
package/src/lib/sql-compiler.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getTableName, getTablePrimaryKey } from '@remix-run/data-table'
|
|
2
|
-
import type {
|
|
2
|
+
import type { Predicate, SqlStatement } from '@remix-run/data-table'
|
|
3
|
+
import type { DataManipulationOperation } from '@remix-run/data-table'
|
|
3
4
|
import {
|
|
4
5
|
collectColumns as collectColumnsHelper,
|
|
5
6
|
normalizeJoinType as normalizeJoinTypeHelper,
|
|
@@ -39,8 +40,8 @@ export function compilePostgresOperation(operation: DataManipulationOperation):
|
|
|
39
40
|
compileGroupByClause(operation.groupBy) +
|
|
40
41
|
compileHavingClause(operation.having, context) +
|
|
41
42
|
compileOrderByClause(operation.orderBy) +
|
|
42
|
-
compileLimitClause(operation.limit) +
|
|
43
|
-
compileOffsetClause(operation.offset)
|
|
43
|
+
compileLimitClause(operation.limit, context) +
|
|
44
|
+
compileOffsetClause(operation.offset, context)
|
|
44
45
|
|
|
45
46
|
return {
|
|
46
47
|
text,
|
|
@@ -258,19 +259,238 @@ function compileRawOperation(statement: SqlStatement): SqlStatement {
|
|
|
258
259
|
}
|
|
259
260
|
}
|
|
260
261
|
|
|
261
|
-
let index = 1
|
|
262
|
-
let text = statement.text.replace(/\?/g, function replaceParameter() {
|
|
263
|
-
let placeholder = '$' + String(index)
|
|
264
|
-
index += 1
|
|
265
|
-
return placeholder
|
|
266
|
-
})
|
|
267
|
-
|
|
268
262
|
return {
|
|
269
|
-
text,
|
|
263
|
+
text: rewriteRawPlaceholders(statement.text),
|
|
270
264
|
values: [...statement.values],
|
|
271
265
|
}
|
|
272
266
|
}
|
|
273
267
|
|
|
268
|
+
function rewriteRawPlaceholders(text: string): string {
|
|
269
|
+
let output = ''
|
|
270
|
+
let index = 0
|
|
271
|
+
let placeholderIndex = 1
|
|
272
|
+
|
|
273
|
+
while (index < text.length) {
|
|
274
|
+
let char = text[index]
|
|
275
|
+
|
|
276
|
+
if (char === '?') {
|
|
277
|
+
output += '$' + String(placeholderIndex)
|
|
278
|
+
placeholderIndex += 1
|
|
279
|
+
index += 1
|
|
280
|
+
continue
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if ((char === 'E' || char === 'e') && text[index + 1] === "'") {
|
|
284
|
+
let end = scanEscapeSingleQuotedString(text, index + 1)
|
|
285
|
+
output += text.slice(index, end)
|
|
286
|
+
index = end
|
|
287
|
+
continue
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (char === "'") {
|
|
291
|
+
let end = scanSingleQuotedString(text, index)
|
|
292
|
+
output += text.slice(index, end)
|
|
293
|
+
index = end
|
|
294
|
+
continue
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (char === '"') {
|
|
298
|
+
let end = scanDoubleQuotedIdentifier(text, index)
|
|
299
|
+
output += text.slice(index, end)
|
|
300
|
+
index = end
|
|
301
|
+
continue
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (text.startsWith('--', index)) {
|
|
305
|
+
let end = scanLineComment(text, index)
|
|
306
|
+
output += text.slice(index, end)
|
|
307
|
+
index = end
|
|
308
|
+
continue
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (text.startsWith('/*', index)) {
|
|
312
|
+
let end = scanBlockComment(text, index)
|
|
313
|
+
output += text.slice(index, end)
|
|
314
|
+
index = end
|
|
315
|
+
continue
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
let dollarQuotedStringEnd = scanDollarQuotedString(text, index)
|
|
319
|
+
|
|
320
|
+
if (dollarQuotedStringEnd !== undefined) {
|
|
321
|
+
output += text.slice(index, dollarQuotedStringEnd)
|
|
322
|
+
index = dollarQuotedStringEnd
|
|
323
|
+
continue
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
output += char
|
|
327
|
+
index += 1
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return output
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function scanSingleQuotedString(text: string, start: number): number {
|
|
334
|
+
let index = start + 1
|
|
335
|
+
|
|
336
|
+
while (index < text.length) {
|
|
337
|
+
if (text[index] === "'") {
|
|
338
|
+
if (text[index + 1] === "'") {
|
|
339
|
+
index += 2
|
|
340
|
+
continue
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return index + 1
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
index += 1
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return text.length
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function scanEscapeSingleQuotedString(text: string, start: number): number {
|
|
353
|
+
let index = start + 1
|
|
354
|
+
|
|
355
|
+
while (index < text.length) {
|
|
356
|
+
if (text[index] === '\\') {
|
|
357
|
+
index += 2
|
|
358
|
+
continue
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (text[index] === "'") {
|
|
362
|
+
if (text[index + 1] === "'") {
|
|
363
|
+
index += 2
|
|
364
|
+
continue
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return index + 1
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
index += 1
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return text.length
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function scanDoubleQuotedIdentifier(text: string, start: number): number {
|
|
377
|
+
let index = start + 1
|
|
378
|
+
|
|
379
|
+
while (index < text.length) {
|
|
380
|
+
if (text[index] === '"') {
|
|
381
|
+
if (text[index + 1] === '"') {
|
|
382
|
+
index += 2
|
|
383
|
+
continue
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return index + 1
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
index += 1
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return text.length
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function scanLineComment(text: string, start: number): number {
|
|
396
|
+
let index = start + 2
|
|
397
|
+
|
|
398
|
+
while (index < text.length && text[index] !== '\n' && text[index] !== '\r') {
|
|
399
|
+
index += 1
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return index
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function scanBlockComment(text: string, start: number): number {
|
|
406
|
+
let index = start + 2
|
|
407
|
+
let depth = 1
|
|
408
|
+
|
|
409
|
+
while (index < text.length && depth > 0) {
|
|
410
|
+
if (text.startsWith('/*', index)) {
|
|
411
|
+
depth += 1
|
|
412
|
+
index += 2
|
|
413
|
+
continue
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (text.startsWith('*/', index)) {
|
|
417
|
+
depth -= 1
|
|
418
|
+
index += 2
|
|
419
|
+
continue
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
index += 1
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return index
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function scanDollarQuotedString(text: string, start: number): number | undefined {
|
|
429
|
+
let delimiter = getDollarQuoteDelimiter(text, start)
|
|
430
|
+
|
|
431
|
+
if (delimiter === undefined) {
|
|
432
|
+
return undefined
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
let end = text.indexOf(delimiter, start + delimiter.length)
|
|
436
|
+
|
|
437
|
+
return end === -1 ? text.length : end + delimiter.length
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function getDollarQuoteDelimiter(text: string, start: number): string | undefined {
|
|
441
|
+
if (text[start] !== '$') {
|
|
442
|
+
return undefined
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
let index = start + 1
|
|
446
|
+
|
|
447
|
+
if (text[index] === '$') {
|
|
448
|
+
return '$$'
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (!isDollarQuoteTagStart(text[index])) {
|
|
452
|
+
return undefined
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
index += 1
|
|
456
|
+
|
|
457
|
+
while (index < text.length && isDollarQuoteTagPart(text[index])) {
|
|
458
|
+
index += 1
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (text[index] !== '$') {
|
|
462
|
+
return undefined
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return text.slice(start, index + 1)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function isDollarQuoteTagStart(char: string | undefined): boolean {
|
|
469
|
+
if (char === undefined) {
|
|
470
|
+
return false
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return isAsciiLetter(char) || char === '_'
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function isDollarQuoteTagPart(char: string | undefined): boolean {
|
|
477
|
+
if (char === undefined) {
|
|
478
|
+
return false
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return isDollarQuoteTagStart(char) || isAsciiDigit(char)
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function isAsciiLetter(char: string): boolean {
|
|
485
|
+
let code = char.charCodeAt(0)
|
|
486
|
+
return (code >= 65 && code <= 90) || (code >= 97 && code <= 122)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function isAsciiDigit(char: string): boolean {
|
|
490
|
+
let code = char.charCodeAt(0)
|
|
491
|
+
return code >= 48 && code <= 57
|
|
492
|
+
}
|
|
493
|
+
|
|
274
494
|
function compileFromClause(
|
|
275
495
|
table: OperationTable,
|
|
276
496
|
joins: JoinClause[],
|
|
@@ -336,20 +556,20 @@ function compileOrderByClause(orderBy: { column: string; direction: 'asc' | 'des
|
|
|
336
556
|
)
|
|
337
557
|
}
|
|
338
558
|
|
|
339
|
-
function compileLimitClause(limit: number | undefined): string {
|
|
559
|
+
function compileLimitClause(limit: number | undefined, context: CompileContext): string {
|
|
340
560
|
if (limit === undefined) {
|
|
341
561
|
return ''
|
|
342
562
|
}
|
|
343
563
|
|
|
344
|
-
return ' limit ' +
|
|
564
|
+
return ' limit ' + pushValue(context, limit)
|
|
345
565
|
}
|
|
346
566
|
|
|
347
|
-
function compileOffsetClause(offset: number | undefined): string {
|
|
567
|
+
function compileOffsetClause(offset: number | undefined, context: CompileContext): string {
|
|
348
568
|
if (offset === undefined) {
|
|
349
569
|
return ''
|
|
350
570
|
}
|
|
351
571
|
|
|
352
|
-
return ' offset ' +
|
|
572
|
+
return ' offset ' + pushValue(context, offset)
|
|
353
573
|
}
|
|
354
574
|
|
|
355
575
|
function compileReturningClause(returning: '*' | string[] | undefined): string {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/lib/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EAEf,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAO9B,OAAO,KAAK,EACV,MAAM,IAAI,cAAc,EACxB,IAAI,IAAI,YAAY,EACpB,UAAU,IAAI,kBAAkB,EACjC,MAAM,IAAI,CAAA;AASX,KAAK,iBAAiB,GAAG,cAAc,GAAG,YAAY,GAAG,kBAAkB,CAAA;AAE3E;;GAEG;AACH,qBAAa,uBAAwB,YAAW,eAAe;;IAC7D;;OAEG;IACH,OAAO,SAAa;IAEpB;;OAEG;IACH,YAAY;;;;;;MAAA;IAMZ,YAAY,MAAM,EAAE,iBAAiB,EASpC;IAED;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,yBAAyB,GAAG,sBAAsB,GAAG,YAAY,EAAE,CAOxF;IAED;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuB/E;IAED;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAWzE;IAED;;;;;OAKG;IACG,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAMhF;IAED;;;;;;OAMG;IACG,SAAS,CACb,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,gBAAgB,GAC7B,OAAO,CAAC,OAAO,CAAC,CASlB;IAED;;;;OAIG;IACG,gBAAgB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0B9E;IAED;;;;OAIG;IACG,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9D;IAED;;;;OAIG;IACG,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhE;IAED;;;;;OAKG;IACG,eAAe,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E;IAED;;;;;OAKG;IACG,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9E;IAED;;;;;OAKG;IACG,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;IAED;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1C;IAED;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1C;CAmBF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,iBAAiB,GAAG,uBAAuB,CAEhG"}
|