@remix-run/data-table-postgres 0.3.0 → 0.4.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.
@@ -258,19 +258,238 @@ function compileRawOperation(statement: SqlStatement): SqlStatement {
258
258
  }
259
259
  }
260
260
 
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
261
  return {
269
- text,
262
+ text: rewriteRawPlaceholders(statement.text),
270
263
  values: [...statement.values],
271
264
  }
272
265
  }
273
266
 
267
+ function rewriteRawPlaceholders(text: string): string {
268
+ let output = ''
269
+ let index = 0
270
+ let placeholderIndex = 1
271
+
272
+ while (index < text.length) {
273
+ let char = text[index]
274
+
275
+ if (char === '?') {
276
+ output += '$' + String(placeholderIndex)
277
+ placeholderIndex += 1
278
+ index += 1
279
+ continue
280
+ }
281
+
282
+ if ((char === 'E' || char === 'e') && text[index + 1] === "'") {
283
+ let end = scanEscapeSingleQuotedString(text, index + 1)
284
+ output += text.slice(index, end)
285
+ index = end
286
+ continue
287
+ }
288
+
289
+ if (char === "'") {
290
+ let end = scanSingleQuotedString(text, index)
291
+ output += text.slice(index, end)
292
+ index = end
293
+ continue
294
+ }
295
+
296
+ if (char === '"') {
297
+ let end = scanDoubleQuotedIdentifier(text, index)
298
+ output += text.slice(index, end)
299
+ index = end
300
+ continue
301
+ }
302
+
303
+ if (text.startsWith('--', index)) {
304
+ let end = scanLineComment(text, index)
305
+ output += text.slice(index, end)
306
+ index = end
307
+ continue
308
+ }
309
+
310
+ if (text.startsWith('/*', index)) {
311
+ let end = scanBlockComment(text, index)
312
+ output += text.slice(index, end)
313
+ index = end
314
+ continue
315
+ }
316
+
317
+ let dollarQuotedStringEnd = scanDollarQuotedString(text, index)
318
+
319
+ if (dollarQuotedStringEnd !== undefined) {
320
+ output += text.slice(index, dollarQuotedStringEnd)
321
+ index = dollarQuotedStringEnd
322
+ continue
323
+ }
324
+
325
+ output += char
326
+ index += 1
327
+ }
328
+
329
+ return output
330
+ }
331
+
332
+ function scanSingleQuotedString(text: string, start: number): number {
333
+ let index = start + 1
334
+
335
+ while (index < text.length) {
336
+ if (text[index] === "'") {
337
+ if (text[index + 1] === "'") {
338
+ index += 2
339
+ continue
340
+ }
341
+
342
+ return index + 1
343
+ }
344
+
345
+ index += 1
346
+ }
347
+
348
+ return text.length
349
+ }
350
+
351
+ function scanEscapeSingleQuotedString(text: string, start: number): number {
352
+ let index = start + 1
353
+
354
+ while (index < text.length) {
355
+ if (text[index] === '\\') {
356
+ index += 2
357
+ continue
358
+ }
359
+
360
+ if (text[index] === "'") {
361
+ if (text[index + 1] === "'") {
362
+ index += 2
363
+ continue
364
+ }
365
+
366
+ return index + 1
367
+ }
368
+
369
+ index += 1
370
+ }
371
+
372
+ return text.length
373
+ }
374
+
375
+ function scanDoubleQuotedIdentifier(text: string, start: number): number {
376
+ let index = start + 1
377
+
378
+ while (index < text.length) {
379
+ if (text[index] === '"') {
380
+ if (text[index + 1] === '"') {
381
+ index += 2
382
+ continue
383
+ }
384
+
385
+ return index + 1
386
+ }
387
+
388
+ index += 1
389
+ }
390
+
391
+ return text.length
392
+ }
393
+
394
+ function scanLineComment(text: string, start: number): number {
395
+ let index = start + 2
396
+
397
+ while (index < text.length && text[index] !== '\n' && text[index] !== '\r') {
398
+ index += 1
399
+ }
400
+
401
+ return index
402
+ }
403
+
404
+ function scanBlockComment(text: string, start: number): number {
405
+ let index = start + 2
406
+ let depth = 1
407
+
408
+ while (index < text.length && depth > 0) {
409
+ if (text.startsWith('/*', index)) {
410
+ depth += 1
411
+ index += 2
412
+ continue
413
+ }
414
+
415
+ if (text.startsWith('*/', index)) {
416
+ depth -= 1
417
+ index += 2
418
+ continue
419
+ }
420
+
421
+ index += 1
422
+ }
423
+
424
+ return index
425
+ }
426
+
427
+ function scanDollarQuotedString(text: string, start: number): number | undefined {
428
+ let delimiter = getDollarQuoteDelimiter(text, start)
429
+
430
+ if (delimiter === undefined) {
431
+ return undefined
432
+ }
433
+
434
+ let end = text.indexOf(delimiter, start + delimiter.length)
435
+
436
+ return end === -1 ? text.length : end + delimiter.length
437
+ }
438
+
439
+ function getDollarQuoteDelimiter(text: string, start: number): string | undefined {
440
+ if (text[start] !== '$') {
441
+ return undefined
442
+ }
443
+
444
+ let index = start + 1
445
+
446
+ if (text[index] === '$') {
447
+ return '$$'
448
+ }
449
+
450
+ if (!isDollarQuoteTagStart(text[index])) {
451
+ return undefined
452
+ }
453
+
454
+ index += 1
455
+
456
+ while (index < text.length && isDollarQuoteTagPart(text[index])) {
457
+ index += 1
458
+ }
459
+
460
+ if (text[index] !== '$') {
461
+ return undefined
462
+ }
463
+
464
+ return text.slice(start, index + 1)
465
+ }
466
+
467
+ function isDollarQuoteTagStart(char: string | undefined): boolean {
468
+ if (char === undefined) {
469
+ return false
470
+ }
471
+
472
+ return isAsciiLetter(char) || char === '_'
473
+ }
474
+
475
+ function isDollarQuoteTagPart(char: string | undefined): boolean {
476
+ if (char === undefined) {
477
+ return false
478
+ }
479
+
480
+ return isDollarQuoteTagStart(char) || isAsciiDigit(char)
481
+ }
482
+
483
+ function isAsciiLetter(char: string): boolean {
484
+ let code = char.charCodeAt(0)
485
+ return (code >= 65 && code <= 90) || (code >= 97 && code <= 122)
486
+ }
487
+
488
+ function isAsciiDigit(char: string): boolean {
489
+ let code = char.charCodeAt(0)
490
+ return code >= 48 && code <= 57
491
+ }
492
+
274
493
  function compileFromClause(
275
494
  table: OperationTable,
276
495
  joins: JoinClause[],