@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.
@@ -1,46 +1,46 @@
1
1
  import { getTableName, getTablePrimaryKey } from '@remix-run/data-table'
2
- import type { AdapterStatement, Predicate, SqlStatement } from '@remix-run/data-table'
2
+ import type { DataManipulationOperation, Predicate, SqlStatement } from '@remix-run/data-table'
3
+ import {
4
+ collectColumns as collectColumnsHelper,
5
+ normalizeJoinType as normalizeJoinTypeHelper,
6
+ quotePath as quotePathHelper,
7
+ } from '@remix-run/data-table/sql-helpers'
3
8
 
4
- type JoinClause = Extract<AdapterStatement, { kind: 'select' }>['joins'][number]
5
- type UpsertStatement = Extract<AdapterStatement, { kind: 'upsert' }>
6
- type StatementTable = Extract<AdapterStatement, { kind: 'select' }>['table']
7
-
8
- type CompiledSql = {
9
- text: string
10
- values: unknown[]
11
- }
9
+ type JoinClause = Extract<DataManipulationOperation, { kind: 'select' }>['joins'][number]
10
+ type UpsertOperation = Extract<DataManipulationOperation, { kind: 'upsert' }>
11
+ type OperationTable = Extract<DataManipulationOperation, { kind: 'select' }>['table']
12
12
 
13
13
  type CompileContext = {
14
14
  values: unknown[]
15
15
  }
16
16
 
17
- export function compilePostgresStatement(statement: AdapterStatement): CompiledSql {
18
- if (statement.kind === 'raw') {
19
- return compileRawStatement(statement.sql)
17
+ export function compilePostgresOperation(operation: DataManipulationOperation): SqlStatement {
18
+ if (operation.kind === 'raw') {
19
+ return compileRawOperation(operation.sql)
20
20
  }
21
21
 
22
22
  let context: CompileContext = { values: [] }
23
23
 
24
- if (statement.kind === 'select') {
24
+ if (operation.kind === 'select') {
25
25
  let selection = '*'
26
26
 
27
- if (statement.select !== '*') {
28
- selection = statement.select
27
+ if (operation.select !== '*') {
28
+ selection = operation.select
29
29
  .map((field) => quotePath(field.column) + ' as ' + quoteIdentifier(field.alias))
30
30
  .join(', ')
31
31
  }
32
32
 
33
33
  let text =
34
34
  'select ' +
35
- (statement.distinct ? 'distinct ' : '') +
35
+ (operation.distinct ? 'distinct ' : '') +
36
36
  selection +
37
- compileFromClause(statement.table, statement.joins, context) +
38
- compileWhereClause(statement.where, context) +
39
- compileGroupByClause(statement.groupBy) +
40
- compileHavingClause(statement.having, context) +
41
- compileOrderByClause(statement.orderBy) +
42
- compileLimitClause(statement.limit) +
43
- compileOffsetClause(statement.offset)
37
+ compileFromClause(operation.table, operation.joins, context) +
38
+ compileWhereClause(operation.where, context) +
39
+ compileGroupByClause(operation.groupBy) +
40
+ compileHavingClause(operation.having, context) +
41
+ compileOrderByClause(operation.orderBy) +
42
+ compileLimitClause(operation.limit) +
43
+ compileOffsetClause(operation.offset)
44
44
 
45
45
  return {
46
46
  text,
@@ -48,13 +48,13 @@ export function compilePostgresStatement(statement: AdapterStatement): CompiledS
48
48
  }
49
49
  }
50
50
 
51
- if (statement.kind === 'count' || statement.kind === 'exists') {
51
+ if (operation.kind === 'count' || operation.kind === 'exists') {
52
52
  let inner =
53
53
  'select 1' +
54
- compileFromClause(statement.table, statement.joins, context) +
55
- compileWhereClause(statement.where, context) +
56
- compileGroupByClause(statement.groupBy) +
57
- compileHavingClause(statement.having, context)
54
+ compileFromClause(operation.table, operation.joins, context) +
55
+ compileWhereClause(operation.where, context) +
56
+ compileGroupByClause(operation.groupBy) +
57
+ compileHavingClause(operation.having, context)
58
58
 
59
59
  return {
60
60
  text:
@@ -68,61 +68,61 @@ export function compilePostgresStatement(statement: AdapterStatement): CompiledS
68
68
  }
69
69
  }
70
70
 
71
- if (statement.kind === 'insert') {
72
- return compileInsertStatement(statement.table, statement.values, statement.returning, context)
71
+ if (operation.kind === 'insert') {
72
+ return compileInsertOperation(operation.table, operation.values, operation.returning, context)
73
73
  }
74
74
 
75
- if (statement.kind === 'insertMany') {
76
- return compileInsertManyStatement(
77
- statement.table,
78
- statement.values,
79
- statement.returning,
75
+ if (operation.kind === 'insertMany') {
76
+ return compileInsertManyOperation(
77
+ operation.table,
78
+ operation.values,
79
+ operation.returning,
80
80
  context,
81
81
  )
82
82
  }
83
83
 
84
- if (statement.kind === 'update') {
85
- let changes = Object.keys(statement.changes)
84
+ if (operation.kind === 'update') {
85
+ let changes = Object.keys(operation.changes)
86
86
  let assignments = changes
87
- .map((column) => quotePath(column) + ' = ' + pushValue(context, statement.changes[column]))
87
+ .map((column) => quotePath(column) + ' = ' + pushValue(context, operation.changes[column]))
88
88
  .join(', ')
89
89
 
90
90
  return {
91
91
  text:
92
92
  'update ' +
93
- quotePath(getTableName(statement.table)) +
93
+ quotePath(getTableName(operation.table)) +
94
94
  ' set ' +
95
95
  assignments +
96
- compileWhereClause(statement.where, context) +
97
- compileReturningClause(statement.returning),
96
+ compileWhereClause(operation.where, context) +
97
+ compileReturningClause(operation.returning),
98
98
  values: context.values,
99
99
  }
100
100
  }
101
101
 
102
- if (statement.kind === 'delete') {
102
+ if (operation.kind === 'delete') {
103
103
  return {
104
104
  text:
105
105
  'delete from ' +
106
- quotePath(getTableName(statement.table)) +
107
- compileWhereClause(statement.where, context) +
108
- compileReturningClause(statement.returning),
106
+ quotePath(getTableName(operation.table)) +
107
+ compileWhereClause(operation.where, context) +
108
+ compileReturningClause(operation.returning),
109
109
  values: context.values,
110
110
  }
111
111
  }
112
112
 
113
- if (statement.kind === 'upsert') {
114
- return compileUpsertStatement(statement, context)
113
+ if (operation.kind === 'upsert') {
114
+ return compileUpsertOperation(operation, context)
115
115
  }
116
116
 
117
- throw new Error('Unsupported statement kind')
117
+ throw new Error('Unsupported operation kind')
118
118
  }
119
119
 
120
- function compileInsertStatement(
121
- table: StatementTable,
120
+ function compileInsertOperation(
121
+ table: OperationTable,
122
122
  values: Record<string, unknown>,
123
123
  returning: '*' | string[] | undefined,
124
124
  context: CompileContext,
125
- ): CompiledSql {
125
+ ): SqlStatement {
126
126
  let columns = Object.keys(values)
127
127
 
128
128
  if (columns.length === 0) {
@@ -153,12 +153,12 @@ function compileInsertStatement(
153
153
  }
154
154
  }
155
155
 
156
- function compileInsertManyStatement(
157
- table: StatementTable,
156
+ function compileInsertManyOperation(
157
+ table: OperationTable,
158
158
  rows: Record<string, unknown>[],
159
159
  returning: '*' | string[] | undefined,
160
160
  context: CompileContext,
161
- ): CompiledSql {
161
+ ): SqlStatement {
162
162
  if (rows.length === 0) {
163
163
  return {
164
164
  text: 'select 0 where 1 = 0',
@@ -203,9 +203,9 @@ function compileInsertManyStatement(
203
203
  }
204
204
  }
205
205
 
206
- function compileUpsertStatement(statement: UpsertStatement, context: CompileContext): CompiledSql {
207
- let insertColumns = Object.keys(statement.values)
208
- let conflictTarget = statement.conflictTarget ?? [...getTablePrimaryKey(statement.table)]
206
+ function compileUpsertOperation(operation: UpsertOperation, context: CompileContext): SqlStatement {
207
+ let insertColumns = Object.keys(operation.values)
208
+ let conflictTarget = operation.conflictTarget ?? [...getTablePrimaryKey(operation.table)]
209
209
 
210
210
  if (insertColumns.length === 0) {
211
211
  throw new Error('upsert requires at least one value')
@@ -213,10 +213,10 @@ function compileUpsertStatement(statement: UpsertStatement, context: CompileCont
213
213
 
214
214
  let quotedInsertColumns = insertColumns.map((column) => quotePath(column))
215
215
  let insertPlaceholders = insertColumns.map((column) =>
216
- pushValue(context, statement.values[column]),
216
+ pushValue(context, operation.values[column]),
217
217
  )
218
218
 
219
- let updateValues = statement.update ?? statement.values
219
+ let updateValues = operation.update ?? operation.values
220
220
  let updateColumns = Object.keys(updateValues)
221
221
  let onConflictClause = ''
222
222
 
@@ -238,19 +238,19 @@ function compileUpsertStatement(statement: UpsertStatement, context: CompileCont
238
238
  return {
239
239
  text:
240
240
  'insert into ' +
241
- quotePath(getTableName(statement.table)) +
241
+ quotePath(getTableName(operation.table)) +
242
242
  ' (' +
243
243
  quotedInsertColumns.join(', ') +
244
244
  ') values (' +
245
245
  insertPlaceholders.join(', ') +
246
246
  ')' +
247
247
  onConflictClause +
248
- compileReturningClause(statement.returning),
248
+ compileReturningClause(operation.returning),
249
249
  values: context.values,
250
250
  }
251
251
  }
252
252
 
253
- function compileRawStatement(statement: SqlStatement): CompiledSql {
253
+ function compileRawOperation(statement: SqlStatement): SqlStatement {
254
254
  if (!statement.text.includes('?')) {
255
255
  return {
256
256
  text: statement.text,
@@ -272,7 +272,7 @@ function compileRawStatement(statement: SqlStatement): CompiledSql {
272
272
  }
273
273
 
274
274
  function compileFromClause(
275
- table: StatementTable,
275
+ table: OperationTable,
276
276
  joins: JoinClause[],
277
277
  context: CompileContext,
278
278
  ): string {
@@ -480,15 +480,7 @@ function compileComparisonValue(
480
480
  }
481
481
 
482
482
  function normalizeJoinType(type: string): string {
483
- if (type === 'left') {
484
- return 'left'
485
- }
486
-
487
- if (type === 'right') {
488
- return 'right'
489
- }
490
-
491
- return 'inner'
483
+ return normalizeJoinTypeHelper(type)
492
484
  }
493
485
 
494
486
  function quoteIdentifier(value: string): string {
@@ -496,21 +488,7 @@ function quoteIdentifier(value: string): string {
496
488
  }
497
489
 
498
490
  function quotePath(path: string): string {
499
- if (path === '*') {
500
- return '*'
501
- }
502
-
503
- let segments = path.split('.')
504
-
505
- return segments
506
- .map((segment) => {
507
- if (segment === '*') {
508
- return '*'
509
- }
510
-
511
- return quoteIdentifier(segment)
512
- })
513
- .join('.')
491
+ return quotePathHelper(path, quoteIdentifier)
514
492
  }
515
493
 
516
494
  function pushValue(context: CompileContext, value: unknown): string {
@@ -519,23 +497,5 @@ function pushValue(context: CompileContext, value: unknown): string {
519
497
  }
520
498
 
521
499
  function collectColumns(rows: Record<string, unknown>[]): string[] {
522
- let columns: string[] = []
523
- let seen = new Set<string>()
524
-
525
- for (let row of rows) {
526
- for (let key in row) {
527
- if (!Object.prototype.hasOwnProperty.call(row, key)) {
528
- continue
529
- }
530
-
531
- if (seen.has(key)) {
532
- continue
533
- }
534
-
535
- seen.add(key)
536
- columns.push(key)
537
- }
538
- }
539
-
540
- return columns
500
+ return collectColumnsHelper(rows)
541
501
  }