@remix-run/data-table-postgres 0.3.1 → 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.
package/README.md CHANGED
@@ -8,7 +8,7 @@ Use this package when you want `data-table` APIs backed by `pg`.
8
8
  - **Native `pg` Integration**: Works with `pg` `Pool` and `PoolClient` instances
9
9
  - **Full `data-table` API Support**: Queries, relations, writes, and transactions
10
10
  - **Adapter-Owned Compiler**: SQL compilation lives in this adapter, with optional shared pure helpers from `data-table`
11
- - **Migration DDL Support**: Compiles and executes `DataMigrationOperation` operations for `remix/data-table/migrations`
11
+ - **Multi-Statement Migrations**: `executeScript()` runs `up.sql` / `down.sql` files natively via `pg`
12
12
  - **Postgres Capabilities Enabled By Default**:
13
13
  - `returning: true`
14
14
  - `savepoints: true`
@@ -27,7 +27,7 @@ npm i remix pg
27
27
  ```ts
28
28
  import { Pool } from 'pg'
29
29
  import { createDatabase } from 'remix/data-table'
30
- import { createPostgresDatabaseAdapter } from 'remix/data-table-postgres'
30
+ import { createPostgresDatabaseAdapter } from 'remix/data-table/postgres'
31
31
 
32
32
  let pool = new Pool({
33
33
  connectionString: process.env.DATABASE_URL,
@@ -1,4 +1,4 @@
1
- import type { DataMigrationRequest, DataManipulationRequest, DataMigrationResult, DataMigrationOperation, DataManipulationResult, DataManipulationOperation, DatabaseAdapter, SqlStatement, TableRef, TransactionOptions, TransactionToken } from '@remix-run/data-table';
1
+ import type { DataManipulationRequest, DataManipulationResult, DataManipulationOperation, DatabaseAdapter, SqlStatement, TableRef, TransactionOptions, TransactionToken } from '@remix-run/data-table';
2
2
  import type { Client as PostgresClient, Pool as PostgresPool, PoolClient as PostgresPoolClient } from 'pg';
3
3
  type PostgresQueryable = PostgresClient | PostgresPool | PostgresPoolClient;
4
4
  /**
@@ -22,11 +22,11 @@ export declare class PostgresDatabaseAdapter implements DatabaseAdapter {
22
22
  };
23
23
  constructor(client: PostgresQueryable);
24
24
  /**
25
- * Compiles a data or migration operation to postgres SQL statements.
25
+ * Compiles a data-manipulation operation to postgres SQL statements.
26
26
  * @param operation Operation to compile.
27
27
  * @returns Compiled SQL statements.
28
28
  */
29
- compileSql(operation: DataManipulationOperation | DataMigrationOperation): SqlStatement[];
29
+ compileSql(operation: DataManipulationOperation): SqlStatement[];
30
30
  /**
31
31
  * Executes a postgres data-manipulation request.
32
32
  * @param request Request to execute.
@@ -34,11 +34,15 @@ export declare class PostgresDatabaseAdapter implements DatabaseAdapter {
34
34
  */
35
35
  execute(request: DataManipulationRequest): Promise<DataManipulationResult>;
36
36
  /**
37
- * Executes postgres migration operations.
38
- * @param request Migration request to execute.
39
- * @returns Migration result.
37
+ * Executes a multi-statement postgres SQL script.
38
+ *
39
+ * Postgres natively supports multi-statement scripts when `query` is called
40
+ * without a parameter array.
41
+ * @param sql SQL script to execute.
42
+ * @param transaction Optional transaction token.
43
+ * @returns A promise that resolves once execution completes.
40
44
  */
41
- migrate(request: DataMigrationRequest): Promise<DataMigrationResult>;
45
+ executeScript(sql: string, transaction?: TransactionToken): Promise<void>;
42
46
  /**
43
47
  * Checks whether a table exists in postgres.
44
48
  * @param table Table reference to inspect.
@@ -113,7 +117,7 @@ export declare class PostgresDatabaseAdapter implements DatabaseAdapter {
113
117
  * ```ts
114
118
  * import { Pool } from 'pg'
115
119
  * import { createDatabase } from 'remix/data-table'
116
- * import { createPostgresDatabaseAdapter } from 'remix/data-table-postgres'
120
+ * import { createPostgresDatabaseAdapter } from 'remix/data-table/postgres'
117
121
  *
118
122
  * let pool = new Pool({ connectionString: process.env.DATABASE_URL })
119
123
  * let adapter = createPostgresDatabaseAdapter(pool)
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/lib/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAE9B,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,YAAY,EAAE,CAG/D;IAED;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuB/E;IAED;;;;;;;;OAQG;IACG,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9E;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"}
@@ -1,5 +1,4 @@
1
1
  import { getTablePrimaryKey } from '@remix-run/data-table';
2
- import { isDataManipulationOperation as isDataManipulationOperationHelper, quoteLiteral as quoteLiteralHelper, quoteTableRef as quoteTableRefHelper, } from '@remix-run/data-table/sql-helpers';
3
2
  import { compilePostgresOperation } from "./sql-compiler.js";
4
3
  /**
5
4
  * `DatabaseAdapter` implementation for postgres-compatible clients.
@@ -27,16 +26,13 @@ export class PostgresDatabaseAdapter {
27
26
  };
28
27
  }
29
28
  /**
30
- * Compiles a data or migration operation to postgres SQL statements.
29
+ * Compiles a data-manipulation operation to postgres SQL statements.
31
30
  * @param operation Operation to compile.
32
31
  * @returns Compiled SQL statements.
33
32
  */
34
33
  compileSql(operation) {
35
- if (isDataManipulationOperation(operation)) {
36
- let compiled = compilePostgresOperation(operation);
37
- return [{ text: compiled.text, values: compiled.values }];
38
- }
39
- return compilePostgresMigrationOperations(operation);
34
+ let compiled = compilePostgresOperation(operation);
35
+ return [{ text: compiled.text, values: compiled.values }];
40
36
  }
41
37
  /**
42
38
  * Executes a postgres data-manipulation request.
@@ -65,19 +61,17 @@ export class PostgresDatabaseAdapter {
65
61
  };
66
62
  }
67
63
  /**
68
- * Executes postgres migration operations.
69
- * @param request Migration request to execute.
70
- * @returns Migration result.
64
+ * Executes a multi-statement postgres SQL script.
65
+ *
66
+ * Postgres natively supports multi-statement scripts when `query` is called
67
+ * without a parameter array.
68
+ * @param sql SQL script to execute.
69
+ * @param transaction Optional transaction token.
70
+ * @returns A promise that resolves once execution completes.
71
71
  */
72
- async migrate(request) {
73
- let statements = this.compileSql(request.operation);
74
- let client = this.#resolveClient(request.transaction);
75
- for (let statement of statements) {
76
- await client.query(statement.text, statement.values);
77
- }
78
- return {
79
- affectedOperations: statements.length,
80
- };
72
+ async executeScript(sql, transaction) {
73
+ let client = this.#resolveClient(transaction);
74
+ await client.query(sql);
81
75
  }
82
76
  /**
83
77
  * Checks whether a table exists in postgres.
@@ -240,7 +234,7 @@ export class PostgresDatabaseAdapter {
240
234
  * ```ts
241
235
  * import { Pool } from 'pg'
242
236
  * import { createDatabase } from 'remix/data-table'
243
- * import { createPostgresDatabaseAdapter } from 'remix/data-table-postgres'
237
+ * import { createPostgresDatabaseAdapter } from 'remix/data-table/postgres'
244
238
  *
245
239
  * let pool = new Pool({ connectionString: process.env.DATABASE_URL })
246
240
  * let adapter = createPostgresDatabaseAdapter(pool)
@@ -347,389 +341,3 @@ function isInsertOperationKind(kind) {
347
341
  function isInsertOperation(operation) {
348
342
  return (operation.kind === 'insert' || operation.kind === 'insertMany' || operation.kind === 'upsert');
349
343
  }
350
- function isDataManipulationOperation(operation) {
351
- return isDataManipulationOperationHelper(operation);
352
- }
353
- function compilePostgresMigrationOperations(operation) {
354
- if (operation.kind === 'raw') {
355
- return [{ text: operation.sql.text, values: [...operation.sql.values] }];
356
- }
357
- if (operation.kind === 'createTable') {
358
- let columns = Object.keys(operation.columns).map((columnName) => quoteIdentifier(columnName) + ' ' + compilePostgresColumn(operation.columns[columnName]));
359
- let tableConstraints = [];
360
- if (operation.primaryKey) {
361
- tableConstraints.push('constraint ' +
362
- quoteIdentifier(operation.primaryKey.name) +
363
- ' primary key (' +
364
- operation.primaryKey.columns.map((column) => quoteIdentifier(column)).join(', ') +
365
- ')');
366
- }
367
- for (let unique of operation.uniques ?? []) {
368
- tableConstraints.push('constraint ' +
369
- quoteIdentifier(unique.name) +
370
- ' ' +
371
- 'unique (' +
372
- unique.columns.map((column) => quoteIdentifier(column)).join(', ') +
373
- ')');
374
- }
375
- for (let check of operation.checks ?? []) {
376
- tableConstraints.push('constraint ' + quoteIdentifier(check.name) + ' ' + 'check (' + check.expression + ')');
377
- }
378
- for (let foreignKey of operation.foreignKeys ?? []) {
379
- let clause = 'constraint ' +
380
- quoteIdentifier(foreignKey.name) +
381
- ' ' +
382
- 'foreign key (' +
383
- foreignKey.columns.map((column) => quoteIdentifier(column)).join(', ') +
384
- ') references ' +
385
- quoteTableRef(foreignKey.references.table) +
386
- ' (' +
387
- foreignKey.references.columns.map((column) => quoteIdentifier(column)).join(', ') +
388
- ')';
389
- if (foreignKey.onDelete) {
390
- clause += ' on delete ' + foreignKey.onDelete;
391
- }
392
- if (foreignKey.onUpdate) {
393
- clause += ' on update ' + foreignKey.onUpdate;
394
- }
395
- tableConstraints.push(clause);
396
- }
397
- let sql = 'create table ' +
398
- (operation.ifNotExists ? 'if not exists ' : '') +
399
- quoteTableRef(operation.table) +
400
- ' (' +
401
- [...columns, ...tableConstraints].join(', ') +
402
- ')';
403
- let statements = [{ text: sql, values: [] }];
404
- if (operation.comment) {
405
- statements.push({
406
- text: 'comment on table ' +
407
- quoteTableRef(operation.table) +
408
- ' is ' +
409
- quoteLiteral(operation.comment),
410
- values: [],
411
- });
412
- }
413
- return statements;
414
- }
415
- if (operation.kind === 'alterTable') {
416
- let sqlStatements = [];
417
- for (let change of operation.changes) {
418
- let sql = 'alter table ' + quoteTableRef(operation.table) + ' ';
419
- if (change.kind === 'addColumn') {
420
- sql +=
421
- 'add column ' +
422
- quoteIdentifier(change.column) +
423
- ' ' +
424
- compilePostgresColumn(change.definition);
425
- }
426
- else if (change.kind === 'changeColumn') {
427
- let typeSql = compilePostgresColumnType(change.definition);
428
- sql += 'alter column ' + quoteIdentifier(change.column) + ' type ' + typeSql;
429
- }
430
- else if (change.kind === 'renameColumn') {
431
- sql += 'rename column ' + quoteIdentifier(change.from) + ' to ' + quoteIdentifier(change.to);
432
- }
433
- else if (change.kind === 'dropColumn') {
434
- sql +=
435
- 'drop column ' + (change.ifExists ? 'if exists ' : '') + quoteIdentifier(change.column);
436
- }
437
- else if (change.kind === 'addPrimaryKey') {
438
- sql +=
439
- 'add ' +
440
- 'constraint ' +
441
- quoteIdentifier(change.constraint.name) +
442
- ' ' +
443
- 'primary key (' +
444
- change.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
445
- ')';
446
- }
447
- else if (change.kind === 'dropPrimaryKey') {
448
- sql += 'drop constraint ' + quoteIdentifier(change.name);
449
- }
450
- else if (change.kind === 'addUnique') {
451
- sql +=
452
- 'add ' +
453
- 'constraint ' +
454
- quoteIdentifier(change.constraint.name) +
455
- ' ' +
456
- 'unique (' +
457
- change.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
458
- ')';
459
- }
460
- else if (change.kind === 'dropUnique') {
461
- sql += 'drop constraint ' + quoteIdentifier(change.name);
462
- }
463
- else if (change.kind === 'addForeignKey') {
464
- sql +=
465
- 'add ' +
466
- 'constraint ' +
467
- quoteIdentifier(change.constraint.name) +
468
- ' ' +
469
- 'foreign key (' +
470
- change.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
471
- ') references ' +
472
- quoteTableRef(change.constraint.references.table) +
473
- ' (' +
474
- change.constraint.references.columns.map((column) => quoteIdentifier(column)).join(', ') +
475
- ')';
476
- }
477
- else if (change.kind === 'dropForeignKey') {
478
- sql += 'drop constraint ' + quoteIdentifier(change.name);
479
- }
480
- else if (change.kind === 'addCheck') {
481
- sql +=
482
- 'add ' +
483
- 'constraint ' +
484
- quoteIdentifier(change.constraint.name) +
485
- ' ' +
486
- 'check (' +
487
- change.constraint.expression +
488
- ')';
489
- }
490
- else if (change.kind === 'dropCheck') {
491
- sql += 'drop constraint ' + quoteIdentifier(change.name);
492
- }
493
- else if (change.kind === 'setTableComment') {
494
- sqlStatements.push({
495
- text: 'comment on table ' +
496
- quoteTableRef(operation.table) +
497
- ' is ' +
498
- quoteLiteral(change.comment),
499
- values: [],
500
- });
501
- continue;
502
- }
503
- else {
504
- continue;
505
- }
506
- sqlStatements.push({ text: sql, values: [] });
507
- }
508
- return sqlStatements;
509
- }
510
- if (operation.kind === 'renameTable') {
511
- return [
512
- {
513
- text: 'alter table ' +
514
- quoteTableRef(operation.from) +
515
- ' rename to ' +
516
- quoteIdentifier(operation.to.name),
517
- values: [],
518
- },
519
- ];
520
- }
521
- if (operation.kind === 'dropTable') {
522
- return [
523
- {
524
- text: 'drop table ' +
525
- (operation.ifExists ? 'if exists ' : '') +
526
- quoteTableRef(operation.table) +
527
- (operation.cascade ? ' cascade' : ''),
528
- values: [],
529
- },
530
- ];
531
- }
532
- if (operation.kind === 'createIndex') {
533
- return [
534
- {
535
- text: 'create ' +
536
- (operation.index.unique ? 'unique ' : '') +
537
- 'index ' +
538
- (operation.ifNotExists ? 'if not exists ' : '') +
539
- quoteIdentifier(operation.index.name) +
540
- ' on ' +
541
- quoteTableRef(operation.index.table) +
542
- (operation.index.using ? ' using ' + operation.index.using : '') +
543
- ' (' +
544
- operation.index.columns.map((column) => quoteIdentifier(column)).join(', ') +
545
- ')' +
546
- (operation.index.where ? ' where ' + operation.index.where : ''),
547
- values: [],
548
- },
549
- ];
550
- }
551
- if (operation.kind === 'dropIndex') {
552
- return [
553
- {
554
- text: 'drop index ' +
555
- (operation.ifExists ? 'if exists ' : '') +
556
- quoteIdentifier(operation.name),
557
- values: [],
558
- },
559
- ];
560
- }
561
- if (operation.kind === 'renameIndex') {
562
- return [
563
- {
564
- text: 'alter index ' +
565
- quoteIdentifier(operation.from) +
566
- ' rename to ' +
567
- quoteIdentifier(operation.to),
568
- values: [],
569
- },
570
- ];
571
- }
572
- if (operation.kind === 'addForeignKey') {
573
- return [
574
- {
575
- text: 'alter table ' +
576
- quoteTableRef(operation.table) +
577
- ' add ' +
578
- 'constraint ' +
579
- quoteIdentifier(operation.constraint.name) +
580
- ' ' +
581
- 'foreign key (' +
582
- operation.constraint.columns.map((column) => quoteIdentifier(column)).join(', ') +
583
- ') references ' +
584
- quoteTableRef(operation.constraint.references.table) +
585
- ' (' +
586
- operation.constraint.references.columns
587
- .map((column) => quoteIdentifier(column))
588
- .join(', ') +
589
- ')' +
590
- (operation.constraint.onDelete ? ' on delete ' + operation.constraint.onDelete : '') +
591
- (operation.constraint.onUpdate ? ' on update ' + operation.constraint.onUpdate : ''),
592
- values: [],
593
- },
594
- ];
595
- }
596
- if (operation.kind === 'dropForeignKey') {
597
- return [
598
- {
599
- text: 'alter table ' +
600
- quoteTableRef(operation.table) +
601
- ' drop constraint ' +
602
- quoteIdentifier(operation.name),
603
- values: [],
604
- },
605
- ];
606
- }
607
- if (operation.kind === 'addCheck') {
608
- return [
609
- {
610
- text: 'alter table ' +
611
- quoteTableRef(operation.table) +
612
- ' add ' +
613
- 'constraint ' +
614
- quoteIdentifier(operation.constraint.name) +
615
- ' ' +
616
- 'check (' +
617
- operation.constraint.expression +
618
- ')',
619
- values: [],
620
- },
621
- ];
622
- }
623
- if (operation.kind === 'dropCheck') {
624
- return [
625
- {
626
- text: 'alter table ' +
627
- quoteTableRef(operation.table) +
628
- ' drop constraint ' +
629
- quoteIdentifier(operation.name),
630
- values: [],
631
- },
632
- ];
633
- }
634
- throw new Error('Unsupported data migration operation kind');
635
- }
636
- function compilePostgresColumn(definition) {
637
- let parts = [compilePostgresColumnType(definition)];
638
- if (definition.nullable === false) {
639
- parts.push('not null');
640
- }
641
- if (definition.default) {
642
- if (definition.default.kind === 'now') {
643
- parts.push('default now()');
644
- }
645
- else if (definition.default.kind === 'sql') {
646
- parts.push('default ' + definition.default.expression);
647
- }
648
- else {
649
- parts.push('default ' + quoteLiteral(definition.default.value));
650
- }
651
- }
652
- if (definition.primaryKey) {
653
- parts.push('primary key');
654
- }
655
- if (definition.unique) {
656
- parts.push('unique');
657
- }
658
- if (definition.computed) {
659
- if (!definition.computed.stored) {
660
- throw new Error('Postgres only supports stored computed/generated columns');
661
- }
662
- parts.push('generated always as (' + definition.computed.expression + ') stored');
663
- }
664
- if (definition.references) {
665
- let clause = 'references ' +
666
- quoteTableRef(definition.references.table) +
667
- ' (' +
668
- definition.references.columns.map((column) => quoteIdentifier(column)).join(', ') +
669
- ')';
670
- if (definition.references.onDelete) {
671
- clause += ' on delete ' + definition.references.onDelete;
672
- }
673
- if (definition.references.onUpdate) {
674
- clause += ' on update ' + definition.references.onUpdate;
675
- }
676
- parts.push(clause);
677
- }
678
- if (definition.checks && definition.checks.length > 0) {
679
- for (let check of definition.checks) {
680
- parts.push('check (' + check.expression + ')');
681
- }
682
- }
683
- return parts.join(' ');
684
- }
685
- function compilePostgresColumnType(definition) {
686
- if (definition.type === 'varchar') {
687
- return 'varchar(' + String(definition.length ?? 255) + ')';
688
- }
689
- if (definition.type === 'text') {
690
- return 'text';
691
- }
692
- if (definition.type === 'integer') {
693
- return 'integer';
694
- }
695
- if (definition.type === 'bigint') {
696
- return 'bigint';
697
- }
698
- if (definition.type === 'decimal') {
699
- if (definition.precision !== undefined && definition.scale !== undefined) {
700
- return 'decimal(' + String(definition.precision) + ', ' + String(definition.scale) + ')';
701
- }
702
- return 'decimal';
703
- }
704
- if (definition.type === 'boolean') {
705
- return 'boolean';
706
- }
707
- if (definition.type === 'uuid') {
708
- return 'uuid';
709
- }
710
- if (definition.type === 'date') {
711
- return 'date';
712
- }
713
- if (definition.type === 'time') {
714
- return definition.withTimezone ? 'time with time zone' : 'time without time zone';
715
- }
716
- if (definition.type === 'timestamp') {
717
- return definition.withTimezone ? 'timestamp with time zone' : 'timestamp without time zone';
718
- }
719
- if (definition.type === 'json') {
720
- return 'jsonb';
721
- }
722
- if (definition.type === 'binary') {
723
- return 'bytea';
724
- }
725
- if (definition.type === 'enum') {
726
- return 'text';
727
- }
728
- return 'text';
729
- }
730
- function quoteTableRef(table) {
731
- return quoteTableRefHelper(table, quoteIdentifier);
732
- }
733
- function quoteLiteral(value) {
734
- return quoteLiteralHelper(value);
735
- }