bun-query-builder 0.2.47 → 0.2.49

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
@@ -18635,20 +18635,62 @@ class MySQLDriver {
18635
18635
  createEnumType(_enumTypeName, _values) {
18636
18636
  return "";
18637
18637
  }
18638
+ foreignKeyClauses(table) {
18639
+ return table.columns.filter((column) => column.references).map((column) => {
18640
+ const reference = column.references;
18641
+ const name = `${table.table}_${column.name}_fk`;
18642
+ let clause = `CONSTRAINT ${this.quoteIdentifier(name)} FOREIGN KEY (${this.quoteIdentifier(column.name)}) REFERENCES ${this.quoteIdentifier(reference.table)}(${this.quoteIdentifier(reference.column)})`;
18643
+ if (reference.onDelete)
18644
+ clause += ` ON DELETE ${reference.onDelete.toUpperCase()}`;
18645
+ if (reference.onUpdate)
18646
+ clause += ` ON UPDATE ${reference.onUpdate.toUpperCase()}`;
18647
+ return clause;
18648
+ });
18649
+ }
18638
18650
  createTable(table) {
18639
- const columns = table.columns.map((c) => this.renderColumn(c)).join(`,
18640
- `);
18651
+ const parts = [
18652
+ ...table.columns.map((c) => this.renderColumn(c)),
18653
+ ...this.foreignKeyClauses(table)
18654
+ ];
18641
18655
  return `CREATE TABLE IF NOT EXISTS ${this.quoteIdentifier(table.table)} (
18642
- ${columns}
18643
- );`;
18656
+ ${parts.join(`,
18657
+ `)}
18658
+ ) DEFAULT CHARSET=utf8mb4;`;
18644
18659
  }
18645
18660
  static KEY_PREFIX_CHARACTERS = 255;
18646
- needsKeyPrefix(column) {
18661
+ static MAX_KEY_BYTES = 3072;
18662
+ static BYTES_PER_CHARACTER = 4;
18663
+ keyPartWidth(column) {
18647
18664
  const rendered = this.getColumnType(column).toLowerCase();
18648
18665
  if (rendered.includes("text") || rendered.includes("blob") || rendered === "json")
18649
- return true;
18650
- const width = rendered.match(/^(?:var)?char\((\d+)\)$/)?.[1];
18651
- return width !== undefined && Number(width) >= 768;
18666
+ return { bytes: Number.POSITIVE_INFINITY, indexableWhole: false };
18667
+ const characters = rendered.match(/^(?:var)?char\((\d+)\)$/)?.[1];
18668
+ if (characters !== undefined)
18669
+ return { bytes: Number(characters) * MySQLDriver.BYTES_PER_CHARACTER, indexableWhole: true };
18670
+ return { bytes: 8, indexableWhole: true };
18671
+ }
18672
+ keyParts(tableName, index, columns) {
18673
+ const parts = index.columns.map((name) => {
18674
+ const column = columns?.find((one) => one.name === name);
18675
+ const width = column ? this.keyPartWidth(column) : { bytes: 0, indexableWhole: true };
18676
+ const prefixed = !width.indexableWhole;
18677
+ return {
18678
+ name,
18679
+ prefixed,
18680
+ bytes: prefixed ? MySQLDriver.KEY_PREFIX_CHARACTERS * MySQLDriver.BYTES_PER_CHARACTER : width.bytes,
18681
+ narrowable: !width.indexableWhole || width.bytes > MySQLDriver.KEY_PREFIX_CHARACTERS * MySQLDriver.BYTES_PER_CHARACTER
18682
+ };
18683
+ });
18684
+ const total = () => parts.reduce((sum, part) => sum + part.bytes, 0);
18685
+ while (total() > MySQLDriver.MAX_KEY_BYTES) {
18686
+ const widest = parts.filter((part) => part.narrowable && !part.prefixed).sort((a, b) => b.bytes - a.bytes)[0];
18687
+ if (!widest) {
18688
+ throw new Error(`[migrations] Index '${index.name}' on table '${tableName}' needs ${total()} bytes of key, over MySQL's ${MySQLDriver.MAX_KEY_BYTES}. ` + `Every column in it is already at its ${MySQLDriver.KEY_PREFIX_CHARACTERS}-character prefix, so shorten a column or drop one from the index.`);
18689
+ }
18690
+ widest.prefixed = true;
18691
+ widest.bytes = MySQLDriver.KEY_PREFIX_CHARACTERS * MySQLDriver.BYTES_PER_CHARACTER;
18692
+ }
18693
+ return parts.map((part) => part.prefixed ? `${this.quoteIdentifier(part.name)}(${MySQLDriver.KEY_PREFIX_CHARACTERS})` : this.quoteIdentifier(part.name));
18652
18694
  }
18653
18695
  createIndex(tableName, index, columns) {
18654
18696
  if (index.where) {
@@ -18656,11 +18698,7 @@ class MySQLDriver {
18656
18698
  }
18657
18699
  const kind = index.type === "unique" ? "UNIQUE " : "";
18658
18700
  const idxName = qualifiedIndexName(tableName, index.name);
18659
- const keyParts = index.columns.map((name) => {
18660
- const column = columns?.find((one) => one.name === name);
18661
- const quoted = this.quoteIdentifier(name);
18662
- return column && this.needsKeyPrefix(column) ? `${quoted}(${MySQLDriver.KEY_PREFIX_CHARACTERS})` : quoted;
18663
- }).join(", ");
18701
+ const keyParts = this.keyParts(tableName, index, columns).join(", ");
18664
18702
  return `CREATE ${kind}INDEX ${this.quoteIdentifier(idxName)} ON ${this.quoteIdentifier(tableName)} (${keyParts});`;
18665
18703
  }
18666
18704
  addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate, existingConstraintNames = []) {
@@ -18773,14 +18811,6 @@ ${sql};` : `${sql};`;
18773
18811
  if (defaultValue) {
18774
18812
  parts.push(defaultValue);
18775
18813
  }
18776
- if (column.references) {
18777
- let reference = `REFERENCES ${this.quoteIdentifier(column.references.table)}(${this.quoteIdentifier(column.references.column)})`;
18778
- if (column.references.onDelete)
18779
- reference += ` ON DELETE ${column.references.onDelete.toUpperCase()}`;
18780
- if (column.references.onUpdate)
18781
- reference += ` ON UPDATE ${column.references.onUpdate.toUpperCase()}`;
18782
- parts.push(reference);
18783
- }
18784
18814
  return parts.join(" ");
18785
18815
  }
18786
18816
  }
@@ -19068,6 +19098,9 @@ var init_vitess = __esm(() => {
19068
19098
  const { references: _references, ...withoutReference } = column;
19069
19099
  return super.renderColumn(withoutReference);
19070
19100
  }
19101
+ foreignKeyClauses(table) {
19102
+ return this.sharded ? [] : super.foreignKeyClauses(table);
19103
+ }
19071
19104
  createTable(table) {
19072
19105
  return super.createTable(table);
19073
19106
  }
@@ -32560,7 +32593,7 @@ function getPrefix() {
32560
32593
  }
32561
32594
  var prefix = getPrefix();
32562
32595
  // package.json
32563
- var version2 = "0.2.47";
32596
+ var version2 = "0.2.49";
32564
32597
 
32565
32598
  // bin/cli.ts
32566
32599
  init_actions();
@@ -25,9 +25,13 @@ export declare class MySQLDriver implements DialectDriver {
25
25
  protected getAutoIncrementClause(column: ColumnPlan): string;
26
26
  protected getDefaultValue(column: ColumnPlan): string;
27
27
  createEnumType(_enumTypeName: string, _values: string[]): string;
28
+ protected foreignKeyClauses(table: TablePlan): string[];
28
29
  createTable(table: TablePlan): string;
29
30
  protected static readonly KEY_PREFIX_CHARACTERS: 255;
30
- protected needsKeyPrefix(column: ColumnPlan): boolean;
31
+ protected static readonly MAX_KEY_BYTES: 3072;
32
+ protected static readonly BYTES_PER_CHARACTER: 4;
33
+ protected keyPartWidth(column: ColumnPlan): { bytes: number, indexableWhole: boolean };
34
+ protected keyParts(tableName: string, index: IndexPlan, columns?: readonly ColumnPlan[]): string[];
31
35
  createIndex(tableName: string, index: IndexPlan, columns?: readonly ColumnPlan[]): string;
32
36
  addForeignKey(tableName: string, columnName: string, refTable: string, refColumn: string, onDelete?: string, onUpdate?: string, existingConstraintNames?: string[]): string;
33
37
  addColumn(tableName: string, column: ColumnPlan): string;
@@ -35,6 +35,7 @@ export declare class VitessDriver extends MySQLDriver {
35
35
  constructor(sharded?: boolean);
36
36
  protected getAutoIncrementClause(column: ColumnPlan): string;
37
37
  protected renderColumn(column: ColumnPlan): string;
38
+ protected foreignKeyClauses(table: TablePlan): string[];
38
39
  createTable(table: TablePlan): string;
39
40
  addForeignKey(...args: Parameters<MySQLDriver['addForeignKey']>): string;
40
41
  createMigrationsTable(): string;
package/dist/src/index.js CHANGED
@@ -18634,20 +18634,62 @@ class MySQLDriver {
18634
18634
  createEnumType(_enumTypeName, _values) {
18635
18635
  return "";
18636
18636
  }
18637
+ foreignKeyClauses(table) {
18638
+ return table.columns.filter((column) => column.references).map((column) => {
18639
+ const reference = column.references;
18640
+ const name = `${table.table}_${column.name}_fk`;
18641
+ let clause = `CONSTRAINT ${this.quoteIdentifier(name)} FOREIGN KEY (${this.quoteIdentifier(column.name)}) REFERENCES ${this.quoteIdentifier(reference.table)}(${this.quoteIdentifier(reference.column)})`;
18642
+ if (reference.onDelete)
18643
+ clause += ` ON DELETE ${reference.onDelete.toUpperCase()}`;
18644
+ if (reference.onUpdate)
18645
+ clause += ` ON UPDATE ${reference.onUpdate.toUpperCase()}`;
18646
+ return clause;
18647
+ });
18648
+ }
18637
18649
  createTable(table) {
18638
- const columns = table.columns.map((c) => this.renderColumn(c)).join(`,
18639
- `);
18650
+ const parts = [
18651
+ ...table.columns.map((c) => this.renderColumn(c)),
18652
+ ...this.foreignKeyClauses(table)
18653
+ ];
18640
18654
  return `CREATE TABLE IF NOT EXISTS ${this.quoteIdentifier(table.table)} (
18641
- ${columns}
18642
- );`;
18655
+ ${parts.join(`,
18656
+ `)}
18657
+ ) DEFAULT CHARSET=utf8mb4;`;
18643
18658
  }
18644
18659
  static KEY_PREFIX_CHARACTERS = 255;
18645
- needsKeyPrefix(column) {
18660
+ static MAX_KEY_BYTES = 3072;
18661
+ static BYTES_PER_CHARACTER = 4;
18662
+ keyPartWidth(column) {
18646
18663
  const rendered = this.getColumnType(column).toLowerCase();
18647
18664
  if (rendered.includes("text") || rendered.includes("blob") || rendered === "json")
18648
- return true;
18649
- const width = rendered.match(/^(?:var)?char\((\d+)\)$/)?.[1];
18650
- return width !== undefined && Number(width) >= 768;
18665
+ return { bytes: Number.POSITIVE_INFINITY, indexableWhole: false };
18666
+ const characters = rendered.match(/^(?:var)?char\((\d+)\)$/)?.[1];
18667
+ if (characters !== undefined)
18668
+ return { bytes: Number(characters) * MySQLDriver.BYTES_PER_CHARACTER, indexableWhole: true };
18669
+ return { bytes: 8, indexableWhole: true };
18670
+ }
18671
+ keyParts(tableName, index, columns) {
18672
+ const parts = index.columns.map((name) => {
18673
+ const column = columns?.find((one) => one.name === name);
18674
+ const width = column ? this.keyPartWidth(column) : { bytes: 0, indexableWhole: true };
18675
+ const prefixed = !width.indexableWhole;
18676
+ return {
18677
+ name,
18678
+ prefixed,
18679
+ bytes: prefixed ? MySQLDriver.KEY_PREFIX_CHARACTERS * MySQLDriver.BYTES_PER_CHARACTER : width.bytes,
18680
+ narrowable: !width.indexableWhole || width.bytes > MySQLDriver.KEY_PREFIX_CHARACTERS * MySQLDriver.BYTES_PER_CHARACTER
18681
+ };
18682
+ });
18683
+ const total = () => parts.reduce((sum, part) => sum + part.bytes, 0);
18684
+ while (total() > MySQLDriver.MAX_KEY_BYTES) {
18685
+ const widest = parts.filter((part) => part.narrowable && !part.prefixed).sort((a, b) => b.bytes - a.bytes)[0];
18686
+ if (!widest) {
18687
+ throw new Error(`[migrations] Index '${index.name}' on table '${tableName}' needs ${total()} bytes of key, over MySQL's ${MySQLDriver.MAX_KEY_BYTES}. ` + `Every column in it is already at its ${MySQLDriver.KEY_PREFIX_CHARACTERS}-character prefix, so shorten a column or drop one from the index.`);
18688
+ }
18689
+ widest.prefixed = true;
18690
+ widest.bytes = MySQLDriver.KEY_PREFIX_CHARACTERS * MySQLDriver.BYTES_PER_CHARACTER;
18691
+ }
18692
+ return parts.map((part) => part.prefixed ? `${this.quoteIdentifier(part.name)}(${MySQLDriver.KEY_PREFIX_CHARACTERS})` : this.quoteIdentifier(part.name));
18651
18693
  }
18652
18694
  createIndex(tableName, index, columns) {
18653
18695
  if (index.where) {
@@ -18655,11 +18697,7 @@ class MySQLDriver {
18655
18697
  }
18656
18698
  const kind = index.type === "unique" ? "UNIQUE " : "";
18657
18699
  const idxName = qualifiedIndexName(tableName, index.name);
18658
- const keyParts = index.columns.map((name) => {
18659
- const column = columns?.find((one) => one.name === name);
18660
- const quoted = this.quoteIdentifier(name);
18661
- return column && this.needsKeyPrefix(column) ? `${quoted}(${MySQLDriver.KEY_PREFIX_CHARACTERS})` : quoted;
18662
- }).join(", ");
18700
+ const keyParts = this.keyParts(tableName, index, columns).join(", ");
18663
18701
  return `CREATE ${kind}INDEX ${this.quoteIdentifier(idxName)} ON ${this.quoteIdentifier(tableName)} (${keyParts});`;
18664
18702
  }
18665
18703
  addForeignKey(tableName, columnName, refTable, refColumn, onDelete, onUpdate, existingConstraintNames = []) {
@@ -18772,14 +18810,6 @@ ${sql};` : `${sql};`;
18772
18810
  if (defaultValue) {
18773
18811
  parts.push(defaultValue);
18774
18812
  }
18775
- if (column.references) {
18776
- let reference = `REFERENCES ${this.quoteIdentifier(column.references.table)}(${this.quoteIdentifier(column.references.column)})`;
18777
- if (column.references.onDelete)
18778
- reference += ` ON DELETE ${column.references.onDelete.toUpperCase()}`;
18779
- if (column.references.onUpdate)
18780
- reference += ` ON UPDATE ${column.references.onUpdate.toUpperCase()}`;
18781
- parts.push(reference);
18782
- }
18783
18813
  return parts.join(" ");
18784
18814
  }
18785
18815
  }
@@ -19067,6 +19097,9 @@ var init_vitess = __esm(() => {
19067
19097
  const { references: _references, ...withoutReference } = column;
19068
19098
  return super.renderColumn(withoutReference);
19069
19099
  }
19100
+ foreignKeyClauses(table) {
19101
+ return this.sharded ? [] : super.foreignKeyClauses(table);
19102
+ }
19070
19103
  createTable(table) {
19071
19104
  return super.createTable(table);
19072
19105
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bun-query-builder",
3
3
  "type": "module",
4
- "version": "0.2.47",
4
+ "version": "0.2.49",
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",