bun-query-builder 0.2.19 → 0.2.20

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/bin/cli.js CHANGED
@@ -17890,7 +17890,10 @@ async function buildPgTable(qb, table, enumLabels) {
17890
17890
  WHERE t.relname = $1 AND t.relkind = 'r'
17891
17891
  ORDER BY i.relname, ord`, [table]);
17892
17892
  const fkRows = await qb.unsafe(`SELECT kcu.column_name, ccu.table_name AS ref_table, ccu.column_name AS ref_column,
17893
- rc.delete_rule, rc.update_rule
17893
+ tc.constraint_name, rc.delete_rule, rc.update_rule,
17894
+ (SELECT COUNT(*) FROM information_schema.key_column_usage count_kcu
17895
+ WHERE count_kcu.constraint_name = tc.constraint_name
17896
+ AND count_kcu.constraint_schema = tc.constraint_schema) AS constraint_column_count
17894
17897
  FROM information_schema.table_constraints tc
17895
17898
  JOIN information_schema.key_column_usage kcu ON kcu.constraint_name = tc.constraint_name
17896
17899
  JOIN information_schema.constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name
@@ -17898,11 +17901,15 @@ async function buildPgTable(qb, table, enumLabels) {
17898
17901
  WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name = $1 AND tc.table_schema = 'public'`, [table]);
17899
17902
  const fkByColumn = new Map;
17900
17903
  for (const fk of fkRows) {
17901
- fkByColumn.set(String(fk.column_name), {
17904
+ const name = String(fk.column_name);
17905
+ const existing = fkByColumn.get(name);
17906
+ const constraintNames = Number(fk.constraint_column_count) === 1 ? [...new Set([...existing?.constraintNames ?? [], String(fk.constraint_name)])] : existing?.constraintNames;
17907
+ fkByColumn.set(name, existing ? { ...existing, constraintNames } : {
17902
17908
  table: String(fk.ref_table),
17903
17909
  column: String(fk.ref_column ?? "id"),
17904
17910
  onDelete: asAction(fk.delete_rule),
17905
- onUpdate: asAction(fk.update_rule)
17911
+ onUpdate: asAction(fk.update_rule),
17912
+ constraintNames
17906
17913
  });
17907
17914
  }
17908
17915
  const { indexes, uniqueColumns } = groupPhysicalIndexes(table, idxRows.map((r) => ({
@@ -17941,18 +17948,27 @@ async function buildMysqlTable(qb, table) {
17941
17948
  WHERE table_name = ? AND table_schema = DATABASE()
17942
17949
  ORDER BY index_name, seq_in_index`, [table]);
17943
17950
  const fkRows = await qb.unsafe(`SELECT kcu.column_name, kcu.referenced_table_name AS ref_table, kcu.referenced_column_name AS ref_column,
17944
- rc.delete_rule, rc.update_rule
17951
+ kcu.constraint_name, rc.delete_rule, rc.update_rule,
17952
+ (SELECT COUNT(*) FROM information_schema.key_column_usage count_kcu
17953
+ WHERE count_kcu.constraint_name = kcu.constraint_name
17954
+ AND count_kcu.constraint_schema = kcu.constraint_schema) AS constraint_column_count
17945
17955
  FROM information_schema.key_column_usage kcu
17946
17956
  JOIN information_schema.referential_constraints rc
17947
17957
  ON rc.constraint_name = kcu.constraint_name AND rc.constraint_schema = kcu.table_schema
17948
17958
  WHERE kcu.table_name = ? AND kcu.table_schema = DATABASE() AND kcu.referenced_table_name IS NOT NULL`, [table]);
17949
17959
  const fkByColumn = new Map;
17950
17960
  for (const fk of fkRows) {
17951
- fkByColumn.set(String(fk.column_name ?? fk.COLUMN_NAME), {
17961
+ const name = String(fk.column_name ?? fk.COLUMN_NAME);
17962
+ const existing = fkByColumn.get(name);
17963
+ const columnCount = Number(fk.constraint_column_count ?? fk.CONSTRAINT_COLUMN_COUNT);
17964
+ const constraintName = String(fk.constraint_name ?? fk.CONSTRAINT_NAME);
17965
+ const constraintNames = columnCount === 1 ? [...new Set([...existing?.constraintNames ?? [], constraintName])] : existing?.constraintNames;
17966
+ fkByColumn.set(name, existing ? { ...existing, constraintNames } : {
17952
17967
  table: String(fk.ref_table ?? fk.REF_TABLE),
17953
17968
  column: String(fk.ref_column ?? fk.REF_COLUMN ?? "id"),
17954
17969
  onDelete: asAction(fk.delete_rule ?? fk.DELETE_RULE),
17955
- onUpdate: asAction(fk.update_rule ?? fk.UPDATE_RULE)
17970
+ onUpdate: asAction(fk.update_rule ?? fk.UPDATE_RULE),
17971
+ constraintNames
17956
17972
  });
17957
17973
  }
17958
17974
  const { indexes, uniqueColumns } = groupPhysicalIndexes(table, idxRows.map((r) => ({
@@ -18213,49 +18229,17 @@ class MySQLDriver {
18213
18229
  const columns = index.columns.map((c) => this.quoteIdentifier(c)).join(", ");
18214
18230
  return `CREATE ${kind}INDEX ${this.quoteIdentifier(idxName)} ON ${this.quoteIdentifier(tableName)} (${columns});`;
18215
18231
  }
18216
- addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate) {
18232
+ addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate, existingConstraintNames = []) {
18217
18233
  const fkName = `${tableName}_${columnName}_fk`;
18218
18234
  let sql = `ALTER TABLE ${this.quoteIdentifier(tableName)} ADD CONSTRAINT ${this.quoteIdentifier(fkName)} FOREIGN KEY (${this.quoteIdentifier(columnName)}) REFERENCES ${this.quoteIdentifier(refTable)}(${this.quoteIdentifier(refColumn)})`;
18219
18235
  if (onDelete)
18220
18236
  sql += ` ON DELETE ${onDelete.toUpperCase()}`;
18221
18237
  if (onUpdate)
18222
18238
  sql += ` ON UPDATE ${onUpdate.toUpperCase()}`;
18223
- return `${this.dropForeignKeysOn(tableName, columnName)}
18224
- ${sql};`;
18225
- }
18226
- dropForeignKeysOn(tableName, columnName) {
18227
- const table = this.quoteLiteral(tableName);
18228
- const column = this.quoteLiteral(columnName);
18229
- return `SET @drop_fks := (
18230
- SELECT CONCAT(
18231
- 'ALTER TABLE \`', ${table}, '\` DROP FOREIGN KEY \`',
18232
- GROUP_CONCAT(kcu.CONSTRAINT_NAME SEPARATOR '\`, DROP FOREIGN KEY \`'),
18233
- '\`'
18234
- )
18235
- FROM information_schema.KEY_COLUMN_USAGE kcu
18236
- WHERE kcu.TABLE_SCHEMA = DATABASE()
18237
- AND kcu.TABLE_NAME = ${table}
18238
- AND kcu.COLUMN_NAME = ${column}
18239
- AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
18240
- AND kcu.CONSTRAINT_NAME IN (
18241
- SELECT single.CONSTRAINT_NAME FROM (
18242
- SELECT inner_kcu.CONSTRAINT_NAME
18243
- FROM information_schema.KEY_COLUMN_USAGE inner_kcu
18244
- WHERE inner_kcu.TABLE_SCHEMA = DATABASE()
18245
- AND inner_kcu.TABLE_NAME = ${table}
18246
- AND inner_kcu.REFERENCED_TABLE_NAME IS NOT NULL
18247
- GROUP BY inner_kcu.CONSTRAINT_NAME
18248
- HAVING COUNT(*) = 1
18249
- ) AS single
18250
- )
18251
- );
18252
- SET @drop_fks := IFNULL(@drop_fks, 'SELECT 1');
18253
- PREPARE drop_fks_stmt FROM @drop_fks;
18254
- EXECUTE drop_fks_stmt;
18255
- DEALLOCATE PREPARE drop_fks_stmt;`;
18256
- }
18257
- quoteLiteral(value) {
18258
- return `'${value.replace(/'/g, "''")}'`;
18239
+ const drops = [...new Set(existingConstraintNames)].map((name) => `ALTER TABLE ${this.quoteIdentifier(tableName)} DROP FOREIGN KEY ${this.quoteIdentifier(name)};`).join(`
18240
+ `);
18241
+ return drops ? `${drops}
18242
+ ${sql};` : `${sql};`;
18259
18243
  }
18260
18244
  addColumn(tableName, column) {
18261
18245
  const typeSql = this.getColumnType(column);
@@ -18438,41 +18422,17 @@ class PostgresDriver {
18438
18422
  const where = index.where ? ` WHERE ${index.where}` : "";
18439
18423
  return `CREATE ${kind}INDEX IF NOT EXISTS ${this.quoteIdentifier(idxName)} ON ${this.quoteIdentifier(tableName)} (${columns})${where};`;
18440
18424
  }
18441
- addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate) {
18425
+ addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate, existingConstraintNames = []) {
18442
18426
  const fkName = `${tableName}_${columnName}_fk`;
18443
18427
  let sql = `ALTER TABLE ${this.quoteIdentifier(tableName)} ADD CONSTRAINT ${this.quoteIdentifier(fkName)} FOREIGN KEY (${this.quoteIdentifier(columnName)}) REFERENCES ${this.quoteIdentifier(refTable)}(${this.quoteIdentifier(refColumn)})`;
18444
18428
  if (onDelete)
18445
18429
  sql += ` ON DELETE ${onDelete.toUpperCase()}`;
18446
18430
  if (onUpdate)
18447
18431
  sql += ` ON UPDATE ${onUpdate.toUpperCase()}`;
18448
- return `${this.dropForeignKeysOn(tableName, columnName)}
18449
- ${sql};`;
18450
- }
18451
- dropForeignKeysOn(tableName, columnName) {
18452
- const table = this.quoteLiteral(tableName);
18453
- const column = this.quoteLiteral(columnName);
18454
- return `DO $$
18455
- DECLARE existing_name text;
18456
- BEGIN
18457
- FOR existing_name IN
18458
- SELECT con.conname
18459
- FROM pg_constraint con
18460
- JOIN pg_class rel ON rel.oid = con.conrelid
18461
- JOIN pg_namespace nsp ON nsp.oid = rel.relnamespace
18462
- WHERE con.contype = 'f'
18463
- AND rel.relname = ${table}
18464
- AND nsp.nspname = current_schema()
18465
- AND con.conkey = ARRAY[(
18466
- SELECT att.attnum FROM pg_attribute att
18467
- WHERE att.attrelid = rel.oid AND att.attname = ${column} AND att.attnum > 0
18468
- )]::smallint[]
18469
- LOOP
18470
- EXECUTE format('ALTER TABLE %I DROP CONSTRAINT %I', ${table}, existing_name);
18471
- END LOOP;
18472
- END $$;`;
18473
- }
18474
- quoteLiteral(value) {
18475
- return `'${value.replace(/'/g, "''")}'`;
18432
+ const drops = [...new Set(existingConstraintNames)].map((name) => `ALTER TABLE ${this.quoteIdentifier(tableName)} DROP CONSTRAINT ${this.quoteIdentifier(name)};`).join(`
18433
+ `);
18434
+ return drops ? `${drops}
18435
+ ${sql};` : `${sql};`;
18476
18436
  }
18477
18437
  addColumn(tableName, column) {
18478
18438
  const typeSql = this.getColumnType(column);
@@ -29271,6 +29231,8 @@ function referencesAreDifferent(r1, r2) {
29271
29231
  return true;
29272
29232
  if (!r1 || !r2)
29273
29233
  return false;
29234
+ if ((r1.constraintNames?.length ?? 0) > 1)
29235
+ return true;
29274
29236
  const act = (a2) => (a2 ?? "no action").toLowerCase();
29275
29237
  return r1.table !== r2.table || r1.column !== r2.column || act(r1.onDelete) !== act(r2.onDelete) || act(r1.onUpdate) !== act(r2.onUpdate);
29276
29238
  }
@@ -29518,7 +29480,7 @@ function generateDiffOperations(previous, next, opts = {}) {
29518
29480
  const currCol = currCols[colName];
29519
29481
  if (!currCol.references)
29520
29482
  continue;
29521
- const addFkStatement = driver.addForeignKey(curr.table, currCol.name, currCol.references.table, currCol.references.column, currCol.references.onDelete, currCol.references.onUpdate);
29483
+ const addFkStatement = driver.addForeignKey(curr.table, currCol.name, currCol.references.table, currCol.references.column, currCol.references.onDelete, currCol.references.onUpdate, prevCols[colName].references?.constraintNames);
29522
29484
  if (!addFkStatement)
29523
29485
  continue;
29524
29486
  tableChanges.push(addFkStatement);
@@ -31668,7 +31630,7 @@ function getPrefix() {
31668
31630
  }
31669
31631
  var prefix = getPrefix();
31670
31632
  // package.json
31671
- var version2 = "0.2.19";
31633
+ var version2 = "0.2.20";
31672
31634
 
31673
31635
  // bin/cli.ts
31674
31636
  init_actions();
@@ -3,7 +3,7 @@ export declare interface DialectDriver {
3
3
  createEnumType: (enumTypeName: string, values: string[]) => string
4
4
  createTable: (table: TablePlan) => string
5
5
  createIndex: (tableName: string, index: IndexPlan) => string
6
- addForeignKey: (tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string) => string
6
+ addForeignKey: (tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string, existingConstraintNames?: string[]) => string
7
7
  addColumn: (tableName: string, column: ColumnPlan) => string
8
8
  modifyColumn: (tableName: string, column: ColumnPlan) => string
9
9
  renameColumn: (tableName: string, from: string, to: string) => string
@@ -26,7 +26,7 @@ export declare class MySQLDriver implements DialectDriver {
26
26
  createEnumType(_enumTypeName: string, _values: string[]): string;
27
27
  createTable(table: TablePlan): string;
28
28
  createIndex(tableName: string, index: IndexPlan): string;
29
- addForeignKey(tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string): string;
29
+ addForeignKey(tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string, existingConstraintNames?: string[]): string;
30
30
  addColumn(tableName: string, column: ColumnPlan): string;
31
31
  modifyColumn(tableName: string, column: ColumnPlan): string;
32
32
  renameColumn(tableName: string, from: string, to: string): string;
@@ -3,7 +3,7 @@ export declare interface DialectDriver {
3
3
  createEnumType: (enumTypeName: string, values: string[]) => string
4
4
  createTable: (table: TablePlan) => string
5
5
  createIndex: (tableName: string, index: IndexPlan) => string
6
- addForeignKey: (tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string) => string
6
+ addForeignKey: (tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string, existingConstraintNames?: string[]) => string
7
7
  addColumn: (tableName: string, column: ColumnPlan) => string
8
8
  modifyColumn: (tableName: string, column: ColumnPlan) => string
9
9
  renameColumn: (tableName: string, from: string, to: string) => string
@@ -21,7 +21,7 @@ export declare class PostgresDriver implements DialectDriver {
21
21
  createEnumType(enumTypeName: string, values: string[]): string;
22
22
  createTable(table: TablePlan): string;
23
23
  createIndex(tableName: string, index: IndexPlan): string;
24
- addForeignKey(tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string): string;
24
+ addForeignKey(tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string, existingConstraintNames?: string[]): string;
25
25
  addColumn(tableName: string, column: ColumnPlan): string;
26
26
  modifyColumn(tableName: string, column: ColumnPlan): string;
27
27
  renameColumn(tableName: string, from: string, to: string): string;
@@ -91,7 +91,13 @@ export declare interface ColumnPlan {
91
91
  isNullable: boolean
92
92
  hasDefault: boolean
93
93
  defaultValue?: PrimitiveDefault
94
- references?: { table: string, column: string, onDelete?: OnForeignKeyAction, onUpdate?: OnForeignKeyAction }
94
+ references?: {
95
+ table: string
96
+ column: string
97
+ onDelete?: OnForeignKeyAction
98
+ onUpdate?: OnForeignKeyAction
99
+ constraintNames?: string[]
100
+ }
95
101
  enumValues?: string[]
96
102
  maxLength?: number
97
103
  enumTypeName?: string
package/dist/src/index.js CHANGED
@@ -17889,7 +17889,10 @@ async function buildPgTable(qb, table, enumLabels) {
17889
17889
  WHERE t.relname = $1 AND t.relkind = 'r'
17890
17890
  ORDER BY i.relname, ord`, [table]);
17891
17891
  const fkRows = await qb.unsafe(`SELECT kcu.column_name, ccu.table_name AS ref_table, ccu.column_name AS ref_column,
17892
- rc.delete_rule, rc.update_rule
17892
+ tc.constraint_name, rc.delete_rule, rc.update_rule,
17893
+ (SELECT COUNT(*) FROM information_schema.key_column_usage count_kcu
17894
+ WHERE count_kcu.constraint_name = tc.constraint_name
17895
+ AND count_kcu.constraint_schema = tc.constraint_schema) AS constraint_column_count
17893
17896
  FROM information_schema.table_constraints tc
17894
17897
  JOIN information_schema.key_column_usage kcu ON kcu.constraint_name = tc.constraint_name
17895
17898
  JOIN information_schema.constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name
@@ -17897,11 +17900,15 @@ async function buildPgTable(qb, table, enumLabels) {
17897
17900
  WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name = $1 AND tc.table_schema = 'public'`, [table]);
17898
17901
  const fkByColumn = new Map;
17899
17902
  for (const fk of fkRows) {
17900
- fkByColumn.set(String(fk.column_name), {
17903
+ const name = String(fk.column_name);
17904
+ const existing = fkByColumn.get(name);
17905
+ const constraintNames = Number(fk.constraint_column_count) === 1 ? [...new Set([...existing?.constraintNames ?? [], String(fk.constraint_name)])] : existing?.constraintNames;
17906
+ fkByColumn.set(name, existing ? { ...existing, constraintNames } : {
17901
17907
  table: String(fk.ref_table),
17902
17908
  column: String(fk.ref_column ?? "id"),
17903
17909
  onDelete: asAction(fk.delete_rule),
17904
- onUpdate: asAction(fk.update_rule)
17910
+ onUpdate: asAction(fk.update_rule),
17911
+ constraintNames
17905
17912
  });
17906
17913
  }
17907
17914
  const { indexes, uniqueColumns } = groupPhysicalIndexes(table, idxRows.map((r) => ({
@@ -17940,18 +17947,27 @@ async function buildMysqlTable(qb, table) {
17940
17947
  WHERE table_name = ? AND table_schema = DATABASE()
17941
17948
  ORDER BY index_name, seq_in_index`, [table]);
17942
17949
  const fkRows = await qb.unsafe(`SELECT kcu.column_name, kcu.referenced_table_name AS ref_table, kcu.referenced_column_name AS ref_column,
17943
- rc.delete_rule, rc.update_rule
17950
+ kcu.constraint_name, rc.delete_rule, rc.update_rule,
17951
+ (SELECT COUNT(*) FROM information_schema.key_column_usage count_kcu
17952
+ WHERE count_kcu.constraint_name = kcu.constraint_name
17953
+ AND count_kcu.constraint_schema = kcu.constraint_schema) AS constraint_column_count
17944
17954
  FROM information_schema.key_column_usage kcu
17945
17955
  JOIN information_schema.referential_constraints rc
17946
17956
  ON rc.constraint_name = kcu.constraint_name AND rc.constraint_schema = kcu.table_schema
17947
17957
  WHERE kcu.table_name = ? AND kcu.table_schema = DATABASE() AND kcu.referenced_table_name IS NOT NULL`, [table]);
17948
17958
  const fkByColumn = new Map;
17949
17959
  for (const fk of fkRows) {
17950
- fkByColumn.set(String(fk.column_name ?? fk.COLUMN_NAME), {
17960
+ const name = String(fk.column_name ?? fk.COLUMN_NAME);
17961
+ const existing = fkByColumn.get(name);
17962
+ const columnCount = Number(fk.constraint_column_count ?? fk.CONSTRAINT_COLUMN_COUNT);
17963
+ const constraintName = String(fk.constraint_name ?? fk.CONSTRAINT_NAME);
17964
+ const constraintNames = columnCount === 1 ? [...new Set([...existing?.constraintNames ?? [], constraintName])] : existing?.constraintNames;
17965
+ fkByColumn.set(name, existing ? { ...existing, constraintNames } : {
17951
17966
  table: String(fk.ref_table ?? fk.REF_TABLE),
17952
17967
  column: String(fk.ref_column ?? fk.REF_COLUMN ?? "id"),
17953
17968
  onDelete: asAction(fk.delete_rule ?? fk.DELETE_RULE),
17954
- onUpdate: asAction(fk.update_rule ?? fk.UPDATE_RULE)
17969
+ onUpdate: asAction(fk.update_rule ?? fk.UPDATE_RULE),
17970
+ constraintNames
17955
17971
  });
17956
17972
  }
17957
17973
  const { indexes, uniqueColumns } = groupPhysicalIndexes(table, idxRows.map((r) => ({
@@ -18212,49 +18228,17 @@ class MySQLDriver {
18212
18228
  const columns = index.columns.map((c) => this.quoteIdentifier(c)).join(", ");
18213
18229
  return `CREATE ${kind}INDEX ${this.quoteIdentifier(idxName)} ON ${this.quoteIdentifier(tableName)} (${columns});`;
18214
18230
  }
18215
- addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate) {
18231
+ addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate, existingConstraintNames = []) {
18216
18232
  const fkName = `${tableName}_${columnName}_fk`;
18217
18233
  let sql = `ALTER TABLE ${this.quoteIdentifier(tableName)} ADD CONSTRAINT ${this.quoteIdentifier(fkName)} FOREIGN KEY (${this.quoteIdentifier(columnName)}) REFERENCES ${this.quoteIdentifier(refTable)}(${this.quoteIdentifier(refColumn)})`;
18218
18234
  if (onDelete)
18219
18235
  sql += ` ON DELETE ${onDelete.toUpperCase()}`;
18220
18236
  if (onUpdate)
18221
18237
  sql += ` ON UPDATE ${onUpdate.toUpperCase()}`;
18222
- return `${this.dropForeignKeysOn(tableName, columnName)}
18223
- ${sql};`;
18224
- }
18225
- dropForeignKeysOn(tableName, columnName) {
18226
- const table = this.quoteLiteral(tableName);
18227
- const column = this.quoteLiteral(columnName);
18228
- return `SET @drop_fks := (
18229
- SELECT CONCAT(
18230
- 'ALTER TABLE \`', ${table}, '\` DROP FOREIGN KEY \`',
18231
- GROUP_CONCAT(kcu.CONSTRAINT_NAME SEPARATOR '\`, DROP FOREIGN KEY \`'),
18232
- '\`'
18233
- )
18234
- FROM information_schema.KEY_COLUMN_USAGE kcu
18235
- WHERE kcu.TABLE_SCHEMA = DATABASE()
18236
- AND kcu.TABLE_NAME = ${table}
18237
- AND kcu.COLUMN_NAME = ${column}
18238
- AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
18239
- AND kcu.CONSTRAINT_NAME IN (
18240
- SELECT single.CONSTRAINT_NAME FROM (
18241
- SELECT inner_kcu.CONSTRAINT_NAME
18242
- FROM information_schema.KEY_COLUMN_USAGE inner_kcu
18243
- WHERE inner_kcu.TABLE_SCHEMA = DATABASE()
18244
- AND inner_kcu.TABLE_NAME = ${table}
18245
- AND inner_kcu.REFERENCED_TABLE_NAME IS NOT NULL
18246
- GROUP BY inner_kcu.CONSTRAINT_NAME
18247
- HAVING COUNT(*) = 1
18248
- ) AS single
18249
- )
18250
- );
18251
- SET @drop_fks := IFNULL(@drop_fks, 'SELECT 1');
18252
- PREPARE drop_fks_stmt FROM @drop_fks;
18253
- EXECUTE drop_fks_stmt;
18254
- DEALLOCATE PREPARE drop_fks_stmt;`;
18255
- }
18256
- quoteLiteral(value) {
18257
- return `'${value.replace(/'/g, "''")}'`;
18238
+ const drops = [...new Set(existingConstraintNames)].map((name) => `ALTER TABLE ${this.quoteIdentifier(tableName)} DROP FOREIGN KEY ${this.quoteIdentifier(name)};`).join(`
18239
+ `);
18240
+ return drops ? `${drops}
18241
+ ${sql};` : `${sql};`;
18258
18242
  }
18259
18243
  addColumn(tableName, column) {
18260
18244
  const typeSql = this.getColumnType(column);
@@ -18437,41 +18421,17 @@ class PostgresDriver {
18437
18421
  const where = index.where ? ` WHERE ${index.where}` : "";
18438
18422
  return `CREATE ${kind}INDEX IF NOT EXISTS ${this.quoteIdentifier(idxName)} ON ${this.quoteIdentifier(tableName)} (${columns})${where};`;
18439
18423
  }
18440
- addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate) {
18424
+ addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate, existingConstraintNames = []) {
18441
18425
  const fkName = `${tableName}_${columnName}_fk`;
18442
18426
  let sql = `ALTER TABLE ${this.quoteIdentifier(tableName)} ADD CONSTRAINT ${this.quoteIdentifier(fkName)} FOREIGN KEY (${this.quoteIdentifier(columnName)}) REFERENCES ${this.quoteIdentifier(refTable)}(${this.quoteIdentifier(refColumn)})`;
18443
18427
  if (onDelete)
18444
18428
  sql += ` ON DELETE ${onDelete.toUpperCase()}`;
18445
18429
  if (onUpdate)
18446
18430
  sql += ` ON UPDATE ${onUpdate.toUpperCase()}`;
18447
- return `${this.dropForeignKeysOn(tableName, columnName)}
18448
- ${sql};`;
18449
- }
18450
- dropForeignKeysOn(tableName, columnName) {
18451
- const table = this.quoteLiteral(tableName);
18452
- const column = this.quoteLiteral(columnName);
18453
- return `DO $$
18454
- DECLARE existing_name text;
18455
- BEGIN
18456
- FOR existing_name IN
18457
- SELECT con.conname
18458
- FROM pg_constraint con
18459
- JOIN pg_class rel ON rel.oid = con.conrelid
18460
- JOIN pg_namespace nsp ON nsp.oid = rel.relnamespace
18461
- WHERE con.contype = 'f'
18462
- AND rel.relname = ${table}
18463
- AND nsp.nspname = current_schema()
18464
- AND con.conkey = ARRAY[(
18465
- SELECT att.attnum FROM pg_attribute att
18466
- WHERE att.attrelid = rel.oid AND att.attname = ${column} AND att.attnum > 0
18467
- )]::smallint[]
18468
- LOOP
18469
- EXECUTE format('ALTER TABLE %I DROP CONSTRAINT %I', ${table}, existing_name);
18470
- END LOOP;
18471
- END $$;`;
18472
- }
18473
- quoteLiteral(value) {
18474
- return `'${value.replace(/'/g, "''")}'`;
18431
+ const drops = [...new Set(existingConstraintNames)].map((name) => `ALTER TABLE ${this.quoteIdentifier(tableName)} DROP CONSTRAINT ${this.quoteIdentifier(name)};`).join(`
18432
+ `);
18433
+ return drops ? `${drops}
18434
+ ${sql};` : `${sql};`;
18475
18435
  }
18476
18436
  addColumn(tableName, column) {
18477
18437
  const typeSql = this.getColumnType(column);
@@ -29270,6 +29230,8 @@ function referencesAreDifferent(r1, r2) {
29270
29230
  return true;
29271
29231
  if (!r1 || !r2)
29272
29232
  return false;
29233
+ if ((r1.constraintNames?.length ?? 0) > 1)
29234
+ return true;
29273
29235
  const act = (a2) => (a2 ?? "no action").toLowerCase();
29274
29236
  return r1.table !== r2.table || r1.column !== r2.column || act(r1.onDelete) !== act(r2.onDelete) || act(r1.onUpdate) !== act(r2.onUpdate);
29275
29237
  }
@@ -29517,7 +29479,7 @@ function generateDiffOperations(previous, next, opts = {}) {
29517
29479
  const currCol = currCols[colName];
29518
29480
  if (!currCol.references)
29519
29481
  continue;
29520
- const addFkStatement = driver.addForeignKey(curr.table, currCol.name, currCol.references.table, currCol.references.column, currCol.references.onDelete, currCol.references.onUpdate);
29482
+ const addFkStatement = driver.addForeignKey(curr.table, currCol.name, currCol.references.table, currCol.references.column, currCol.references.onDelete, currCol.references.onUpdate, prevCols[colName].references?.constraintNames);
29521
29483
  if (!addFkStatement)
29522
29484
  continue;
29523
29485
  tableChanges.push(addFkStatement);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bun-query-builder",
3
3
  "type": "module",
4
- "version": "0.2.19",
4
+ "version": "0.2.20",
5
5
  "description": "A simple yet performant query builder for TypeScript. Built with Bun.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",