@atscript/db-postgres 0.1.138 → 0.1.139

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/dist/index.cjs CHANGED
@@ -858,25 +858,21 @@ var PostgresAdapter = class PostgresAdapter extends _atscript_db.BaseDbAdapter {
858
858
  /** Live columns of `tableName`, read through `exec` (the recreate's own connection, or the pool). */
859
859
  async _readColumns(exec, tableName) {
860
860
  const schema = this._schema;
861
- const rows = await exec.all(`SELECT c.column_name, c.data_type, c.udt_name, c.character_maximum_length, c.numeric_precision, c.numeric_scale, c.is_nullable, c.column_default, c.is_identity,
862
- format_type(a.atttypid, a.atttypmod) AS formatted_type
861
+ return (await exec.all(`SELECT c.column_name, c.data_type, c.udt_name, c.character_maximum_length, c.numeric_precision, c.numeric_scale, c.is_nullable, c.column_default, c.is_identity,
862
+ format_type(a.atttypid, a.atttypmod) AS formatted_type,
863
+ EXISTS (
864
+ SELECT 1 FROM pg_index i
865
+ WHERE i.indrelid = a.attrelid AND i.indisprimary AND a.attnum = ANY (i.indkey)
866
+ ) AS is_pk
863
867
  FROM information_schema.columns c
864
868
  JOIN pg_attribute a ON a.attname = c.column_name
865
869
  AND a.attrelid = (SELECT oid FROM pg_class WHERE relname = $1 AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = COALESCE($2, 'public')))
866
870
  WHERE c.table_name = $1 AND c.table_schema = COALESCE($2, 'public')
867
- ORDER BY c.ordinal_position`, [tableName, schema]);
868
- const pkRows = await exec.all(`SELECT kcu.column_name
869
- FROM information_schema.table_constraints tc
870
- JOIN information_schema.key_column_usage kcu
871
- ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
872
- WHERE tc.table_name = $1 AND tc.table_schema = COALESCE($2, 'public')
873
- AND tc.constraint_type = 'PRIMARY KEY'`, [tableName, schema]);
874
- const pkSet = new Set(pkRows.map((r) => r.column_name));
875
- return rows.map((r) => ({
871
+ ORDER BY c.ordinal_position`, [tableName, schema])).map((r) => ({
876
872
  name: r.column_name,
877
873
  type: normalizePgType(r.data_type, r.character_maximum_length, r.numeric_precision, r.numeric_scale, r.udt_name, r.formatted_type),
878
874
  notnull: r.is_nullable === "NO",
879
- pk: pkSet.has(r.column_name),
875
+ pk: r.is_pk,
880
876
  dflt_value: normalizePgDefault(r.column_default, r.is_identity)
881
877
  }));
882
878
  }
@@ -969,31 +965,31 @@ var PostgresAdapter = class PostgresAdapter extends _atscript_db.BaseDbAdapter {
969
965
  const conn = await this.driver.getConnection();
970
966
  try {
971
967
  await conn.exec("BEGIN");
972
- const fkRefs = await conn.all(`SELECT tc.constraint_name, tc.table_name, tc.table_schema,
973
- kcu.column_name, kcur.column_name AS ref_column_name,
974
- rc.delete_rule, rc.update_rule
975
- FROM information_schema.referential_constraints rc
976
- JOIN information_schema.table_constraints tc
977
- ON rc.constraint_name = tc.constraint_name AND rc.constraint_schema = tc.constraint_schema
978
- JOIN information_schema.key_column_usage kcu
979
- ON kcu.constraint_name = tc.constraint_name AND kcu.table_schema = tc.table_schema
980
- JOIN information_schema.key_column_usage kcur
981
- ON kcur.constraint_name = rc.unique_constraint_name AND kcur.table_schema = rc.unique_constraint_schema
982
- AND kcur.ordinal_position = kcu.position_in_unique_constraint
983
- WHERE rc.unique_constraint_schema = COALESCE($1, 'public')
984
- AND rc.unique_constraint_name IN (
985
- SELECT constraint_name FROM information_schema.table_constraints
986
- WHERE table_name = $2 AND table_schema = COALESCE($1, 'public')
987
- AND constraint_type IN ('PRIMARY KEY', 'UNIQUE')
988
- )
989
- ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position`, [schema, this._table.tableName]);
990
- const fkByName = /* @__PURE__ */ new Map();
968
+ const fkRefs = await conn.all(`SELECT c.conname AS constraint_name, cl.relname AS table_name, n.nspname AS table_schema,
969
+ a.attname AS column_name, ra.attname AS ref_column_name,
970
+ CASE c.confdeltype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT'
971
+ WHEN 'r' THEN 'RESTRICT' ELSE 'NO ACTION' END AS delete_rule,
972
+ CASE c.confupdtype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT'
973
+ WHEN 'r' THEN 'RESTRICT' ELSE 'NO ACTION' END AS update_rule
974
+ FROM pg_constraint c
975
+ JOIN pg_class cl ON cl.oid = c.conrelid
976
+ JOIN pg_namespace n ON n.oid = cl.relnamespace
977
+ JOIN pg_class rcl ON rcl.oid = c.confrelid
978
+ JOIN pg_namespace rn ON rn.oid = rcl.relnamespace
979
+ CROSS JOIN LATERAL unnest(c.conkey, c.confkey) WITH ORDINALITY AS k(attnum, refattnum, ord)
980
+ JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum
981
+ JOIN pg_attribute ra ON ra.attrelid = c.confrelid AND ra.attnum = k.refattnum
982
+ WHERE c.contype = 'f' AND rcl.relname = $2 AND rn.nspname = COALESCE($1, 'public')
983
+ ORDER BY n.nspname, cl.relname, c.conname, k.ord`, [schema, this._table.tableName]);
984
+ const inboundFks = /* @__PURE__ */ new Map();
991
985
  const ownSchema = schema ?? "public";
992
986
  for (const fk of fkRefs) {
993
987
  if (fk.table_schema === ownSchema && fk.table_name === this._table.tableName) continue;
994
- let entry = fkByName.get(fk.constraint_name);
988
+ const key = `${fk.table_schema}.${fk.table_name}.${fk.constraint_name}`;
989
+ let entry = inboundFks.get(key);
995
990
  if (!entry) {
996
991
  entry = {
992
+ name: fk.constraint_name,
997
993
  schema: fk.table_schema,
998
994
  table: fk.table_name,
999
995
  cols: [],
@@ -1001,13 +997,13 @@ var PostgresAdapter = class PostgresAdapter extends _atscript_db.BaseDbAdapter {
1001
997
  onDelete: fk.delete_rule,
1002
998
  onUpdate: fk.update_rule
1003
999
  };
1004
- fkByName.set(fk.constraint_name, entry);
1000
+ inboundFks.set(key, entry);
1005
1001
  }
1006
1002
  entry.cols.push(fk.column_name);
1007
1003
  entry.refCols.push(fk.ref_column_name);
1008
1004
  }
1009
- for (const [name, fk] of fkByName) {
1010
- const ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} DROP CONSTRAINT IF EXISTS ${qi(name)}`;
1005
+ for (const fk of inboundFks.values()) {
1006
+ const ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} DROP CONSTRAINT IF EXISTS ${qi(fk.name)}`;
1011
1007
  this._log(ddl);
1012
1008
  await conn.exec(ddl);
1013
1009
  }
@@ -1041,10 +1037,10 @@ var PostgresAdapter = class PostgresAdapter extends _atscript_db.BaseDbAdapter {
1041
1037
  await conn.exec(`ALTER TABLE ${quoteTableName(tempName)} RENAME TO ${qi(this._table.tableName)}`);
1042
1038
  await this._renameTempConstraints(conn, baseTempName);
1043
1039
  const resolvedTable = this.resolveTableName();
1044
- for (const [name, fk] of fkByName) {
1040
+ for (const fk of inboundFks.values()) {
1045
1041
  const localCols = fk.cols.map((c) => qi(c)).join(", ");
1046
1042
  const refCols = fk.refCols.map((c) => qi(c)).join(", ");
1047
- let ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} ADD CONSTRAINT ${qi(name)} FOREIGN KEY (${localCols}) REFERENCES ${quoteTableName(resolvedTable)} (${refCols})`;
1043
+ let ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} ADD CONSTRAINT ${qi(fk.name)} FOREIGN KEY (${localCols}) REFERENCES ${quoteTableName(resolvedTable)} (${refCols})`;
1048
1044
  if (fk.onDelete !== "NO ACTION") ddl += ` ON DELETE ${fk.onDelete}`;
1049
1045
  if (fk.onUpdate !== "NO ACTION") ddl += ` ON UPDATE ${fk.onUpdate}`;
1050
1046
  this._log(ddl);
@@ -1293,12 +1289,14 @@ var PostgresAdapter = class PostgresAdapter extends _atscript_db.BaseDbAdapter {
1293
1289
  }
1294
1290
  /** Queries information_schema for existing FK constraints. */
1295
1291
  async _getExistingFkConstraints() {
1296
- const rows = await this._exec().all(`SELECT kcu.constraint_name, kcu.column_name
1297
- FROM information_schema.table_constraints tc
1298
- JOIN information_schema.key_column_usage kcu
1299
- ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
1300
- WHERE tc.table_name = $1 AND tc.table_schema = COALESCE($2, 'public')
1301
- AND tc.constraint_type = 'FOREIGN KEY'`, [this._table.tableName, this._schema]);
1292
+ const rows = await this._exec().all(`SELECT c.conname AS constraint_name, a.attname AS column_name
1293
+ FROM pg_constraint c
1294
+ JOIN pg_class cl ON cl.oid = c.conrelid
1295
+ JOIN pg_namespace n ON n.oid = cl.relnamespace
1296
+ CROSS JOIN LATERAL unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)
1297
+ JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum
1298
+ WHERE c.contype = 'f' AND cl.relname = $1 AND n.nspname = COALESCE($2, 'public')
1299
+ ORDER BY c.conname, k.ord`, [this._table.tableName, this._schema]);
1302
1300
  const byName = /* @__PURE__ */ new Map();
1303
1301
  for (const row of rows) {
1304
1302
  let cols = byName.get(row.constraint_name);
package/dist/index.mjs CHANGED
@@ -857,25 +857,21 @@ var PostgresAdapter = class PostgresAdapter extends BaseDbAdapter {
857
857
  /** Live columns of `tableName`, read through `exec` (the recreate's own connection, or the pool). */
858
858
  async _readColumns(exec, tableName) {
859
859
  const schema = this._schema;
860
- const rows = await exec.all(`SELECT c.column_name, c.data_type, c.udt_name, c.character_maximum_length, c.numeric_precision, c.numeric_scale, c.is_nullable, c.column_default, c.is_identity,
861
- format_type(a.atttypid, a.atttypmod) AS formatted_type
860
+ return (await exec.all(`SELECT c.column_name, c.data_type, c.udt_name, c.character_maximum_length, c.numeric_precision, c.numeric_scale, c.is_nullable, c.column_default, c.is_identity,
861
+ format_type(a.atttypid, a.atttypmod) AS formatted_type,
862
+ EXISTS (
863
+ SELECT 1 FROM pg_index i
864
+ WHERE i.indrelid = a.attrelid AND i.indisprimary AND a.attnum = ANY (i.indkey)
865
+ ) AS is_pk
862
866
  FROM information_schema.columns c
863
867
  JOIN pg_attribute a ON a.attname = c.column_name
864
868
  AND a.attrelid = (SELECT oid FROM pg_class WHERE relname = $1 AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = COALESCE($2, 'public')))
865
869
  WHERE c.table_name = $1 AND c.table_schema = COALESCE($2, 'public')
866
- ORDER BY c.ordinal_position`, [tableName, schema]);
867
- const pkRows = await exec.all(`SELECT kcu.column_name
868
- FROM information_schema.table_constraints tc
869
- JOIN information_schema.key_column_usage kcu
870
- ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
871
- WHERE tc.table_name = $1 AND tc.table_schema = COALESCE($2, 'public')
872
- AND tc.constraint_type = 'PRIMARY KEY'`, [tableName, schema]);
873
- const pkSet = new Set(pkRows.map((r) => r.column_name));
874
- return rows.map((r) => ({
870
+ ORDER BY c.ordinal_position`, [tableName, schema])).map((r) => ({
875
871
  name: r.column_name,
876
872
  type: normalizePgType(r.data_type, r.character_maximum_length, r.numeric_precision, r.numeric_scale, r.udt_name, r.formatted_type),
877
873
  notnull: r.is_nullable === "NO",
878
- pk: pkSet.has(r.column_name),
874
+ pk: r.is_pk,
879
875
  dflt_value: normalizePgDefault(r.column_default, r.is_identity)
880
876
  }));
881
877
  }
@@ -968,31 +964,31 @@ var PostgresAdapter = class PostgresAdapter extends BaseDbAdapter {
968
964
  const conn = await this.driver.getConnection();
969
965
  try {
970
966
  await conn.exec("BEGIN");
971
- const fkRefs = await conn.all(`SELECT tc.constraint_name, tc.table_name, tc.table_schema,
972
- kcu.column_name, kcur.column_name AS ref_column_name,
973
- rc.delete_rule, rc.update_rule
974
- FROM information_schema.referential_constraints rc
975
- JOIN information_schema.table_constraints tc
976
- ON rc.constraint_name = tc.constraint_name AND rc.constraint_schema = tc.constraint_schema
977
- JOIN information_schema.key_column_usage kcu
978
- ON kcu.constraint_name = tc.constraint_name AND kcu.table_schema = tc.table_schema
979
- JOIN information_schema.key_column_usage kcur
980
- ON kcur.constraint_name = rc.unique_constraint_name AND kcur.table_schema = rc.unique_constraint_schema
981
- AND kcur.ordinal_position = kcu.position_in_unique_constraint
982
- WHERE rc.unique_constraint_schema = COALESCE($1, 'public')
983
- AND rc.unique_constraint_name IN (
984
- SELECT constraint_name FROM information_schema.table_constraints
985
- WHERE table_name = $2 AND table_schema = COALESCE($1, 'public')
986
- AND constraint_type IN ('PRIMARY KEY', 'UNIQUE')
987
- )
988
- ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position`, [schema, this._table.tableName]);
989
- const fkByName = /* @__PURE__ */ new Map();
967
+ const fkRefs = await conn.all(`SELECT c.conname AS constraint_name, cl.relname AS table_name, n.nspname AS table_schema,
968
+ a.attname AS column_name, ra.attname AS ref_column_name,
969
+ CASE c.confdeltype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT'
970
+ WHEN 'r' THEN 'RESTRICT' ELSE 'NO ACTION' END AS delete_rule,
971
+ CASE c.confupdtype WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT'
972
+ WHEN 'r' THEN 'RESTRICT' ELSE 'NO ACTION' END AS update_rule
973
+ FROM pg_constraint c
974
+ JOIN pg_class cl ON cl.oid = c.conrelid
975
+ JOIN pg_namespace n ON n.oid = cl.relnamespace
976
+ JOIN pg_class rcl ON rcl.oid = c.confrelid
977
+ JOIN pg_namespace rn ON rn.oid = rcl.relnamespace
978
+ CROSS JOIN LATERAL unnest(c.conkey, c.confkey) WITH ORDINALITY AS k(attnum, refattnum, ord)
979
+ JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum
980
+ JOIN pg_attribute ra ON ra.attrelid = c.confrelid AND ra.attnum = k.refattnum
981
+ WHERE c.contype = 'f' AND rcl.relname = $2 AND rn.nspname = COALESCE($1, 'public')
982
+ ORDER BY n.nspname, cl.relname, c.conname, k.ord`, [schema, this._table.tableName]);
983
+ const inboundFks = /* @__PURE__ */ new Map();
990
984
  const ownSchema = schema ?? "public";
991
985
  for (const fk of fkRefs) {
992
986
  if (fk.table_schema === ownSchema && fk.table_name === this._table.tableName) continue;
993
- let entry = fkByName.get(fk.constraint_name);
987
+ const key = `${fk.table_schema}.${fk.table_name}.${fk.constraint_name}`;
988
+ let entry = inboundFks.get(key);
994
989
  if (!entry) {
995
990
  entry = {
991
+ name: fk.constraint_name,
996
992
  schema: fk.table_schema,
997
993
  table: fk.table_name,
998
994
  cols: [],
@@ -1000,13 +996,13 @@ var PostgresAdapter = class PostgresAdapter extends BaseDbAdapter {
1000
996
  onDelete: fk.delete_rule,
1001
997
  onUpdate: fk.update_rule
1002
998
  };
1003
- fkByName.set(fk.constraint_name, entry);
999
+ inboundFks.set(key, entry);
1004
1000
  }
1005
1001
  entry.cols.push(fk.column_name);
1006
1002
  entry.refCols.push(fk.ref_column_name);
1007
1003
  }
1008
- for (const [name, fk] of fkByName) {
1009
- const ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} DROP CONSTRAINT IF EXISTS ${qi(name)}`;
1004
+ for (const fk of inboundFks.values()) {
1005
+ const ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} DROP CONSTRAINT IF EXISTS ${qi(fk.name)}`;
1010
1006
  this._log(ddl);
1011
1007
  await conn.exec(ddl);
1012
1008
  }
@@ -1040,10 +1036,10 @@ var PostgresAdapter = class PostgresAdapter extends BaseDbAdapter {
1040
1036
  await conn.exec(`ALTER TABLE ${quoteTableName(tempName)} RENAME TO ${qi(this._table.tableName)}`);
1041
1037
  await this._renameTempConstraints(conn, baseTempName);
1042
1038
  const resolvedTable = this.resolveTableName();
1043
- for (const [name, fk] of fkByName) {
1039
+ for (const fk of inboundFks.values()) {
1044
1040
  const localCols = fk.cols.map((c) => qi(c)).join(", ");
1045
1041
  const refCols = fk.refCols.map((c) => qi(c)).join(", ");
1046
- let ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} ADD CONSTRAINT ${qi(name)} FOREIGN KEY (${localCols}) REFERENCES ${quoteTableName(resolvedTable)} (${refCols})`;
1042
+ let ddl = `ALTER TABLE ${qi(fk.schema)}.${qi(fk.table)} ADD CONSTRAINT ${qi(fk.name)} FOREIGN KEY (${localCols}) REFERENCES ${quoteTableName(resolvedTable)} (${refCols})`;
1047
1043
  if (fk.onDelete !== "NO ACTION") ddl += ` ON DELETE ${fk.onDelete}`;
1048
1044
  if (fk.onUpdate !== "NO ACTION") ddl += ` ON UPDATE ${fk.onUpdate}`;
1049
1045
  this._log(ddl);
@@ -1292,12 +1288,14 @@ var PostgresAdapter = class PostgresAdapter extends BaseDbAdapter {
1292
1288
  }
1293
1289
  /** Queries information_schema for existing FK constraints. */
1294
1290
  async _getExistingFkConstraints() {
1295
- const rows = await this._exec().all(`SELECT kcu.constraint_name, kcu.column_name
1296
- FROM information_schema.table_constraints tc
1297
- JOIN information_schema.key_column_usage kcu
1298
- ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
1299
- WHERE tc.table_name = $1 AND tc.table_schema = COALESCE($2, 'public')
1300
- AND tc.constraint_type = 'FOREIGN KEY'`, [this._table.tableName, this._schema]);
1291
+ const rows = await this._exec().all(`SELECT c.conname AS constraint_name, a.attname AS column_name
1292
+ FROM pg_constraint c
1293
+ JOIN pg_class cl ON cl.oid = c.conrelid
1294
+ JOIN pg_namespace n ON n.oid = cl.relnamespace
1295
+ CROSS JOIN LATERAL unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)
1296
+ JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.attnum
1297
+ WHERE c.contype = 'f' AND cl.relname = $1 AND n.nspname = COALESCE($2, 'public')
1298
+ ORDER BY c.conname, k.ord`, [this._table.tableName, this._schema]);
1301
1299
  const byName = /* @__PURE__ */ new Map();
1302
1300
  for (const row of rows) {
1303
1301
  let cols = byName.get(row.constraint_name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db-postgres",
3
- "version": "0.1.138",
3
+ "version": "0.1.139",
4
4
  "description": "PostgreSQL adapter for @atscript/db with pg (node-postgres) driver support.",
5
5
  "keywords": [
6
6
  "atscript",
@@ -55,8 +55,8 @@
55
55
  "@atscript/typescript": "^0.1.92",
56
56
  "@uniqu/core": "^0.1.11",
57
57
  "pg": ">=8.0.0",
58
- "@atscript/db": "^0.1.138",
59
- "@atscript/db-sql-tools": "^0.1.138"
58
+ "@atscript/db": "^0.1.139",
59
+ "@atscript/db-sql-tools": "^0.1.139"
60
60
  },
61
61
  "peerDependenciesMeta": {
62
62
  "pg": {