@carno.js/orm 1.0.7 → 1.0.8

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.
@@ -15,6 +15,8 @@ export declare class SqlBuilder<T> {
15
15
  private _modelTransformer?;
16
16
  private _joinManager?;
17
17
  private readonly boundGetAlias;
18
+ private quoteId;
19
+ private qualifyTable;
18
20
  constructor(model: new () => T);
19
21
  private get modelTransformer();
20
22
  private get joinManager();
@@ -37,7 +39,6 @@ export declare class SqlBuilder<T> {
37
39
  cache(cache: boolean | number | Date | undefined): SqlBuilder<T>;
38
40
  load(load: string[]): SqlBuilder<T>;
39
41
  count(): SqlBuilder<T>;
40
- private getPrimaryKeyColumnName;
41
42
  private shouldUseCache;
42
43
  private getCacheTtl;
43
44
  private getCachedResult;
@@ -63,7 +64,6 @@ export declare class SqlBuilder<T> {
63
64
  private attachOneToManyRelations;
64
65
  private removeDuplicatesByPrimaryKey;
65
66
  private getPrimaryKeyName;
66
- private getPrimaryKeyNameForEntity;
67
67
  executeCount(): Promise<number>;
68
68
  private logExecution;
69
69
  inTransaction<T>(callback: (builder: SqlBuilder<T>) => Promise<T>): Promise<T>;
@@ -10,6 +10,16 @@ const model_transformer_1 = require("./query/model-transformer");
10
10
  const sql_column_manager_1 = require("./query/sql-column-manager");
11
11
  const sql_join_manager_1 = require("./query/sql-join-manager");
12
12
  class SqlBuilder {
13
+ quoteId(identifier) {
14
+ const q = this.driver.getIdentifierQuote();
15
+ return `${q}${identifier}${q}`;
16
+ }
17
+ qualifyTable(schema, tableName) {
18
+ if (this.driver.dbType === 'mysql') {
19
+ return this.quoteId(tableName);
20
+ }
21
+ return `${this.quoteId(schema)}.${this.quoteId(tableName)}`;
22
+ }
13
23
  constructor(model) {
14
24
  this.statements = {};
15
25
  this.aliases = new Set();
@@ -24,12 +34,12 @@ class SqlBuilder {
24
34
  this.statements.hooks = this.entity.hooks;
25
35
  // Pre-bind once
26
36
  this.boundGetAlias = this.getAlias.bind(this);
27
- this.columnManager = new sql_column_manager_1.SqlColumnManager(this.entityStorage, this.statements, this.entity);
37
+ this.columnManager = new sql_column_manager_1.SqlColumnManager(this.entityStorage, this.statements, this.entity, this.driver);
28
38
  const applyJoinWrapper = (relationship, value, alias) => {
29
39
  return this.joinManager.applyJoin(relationship, value, alias);
30
40
  };
31
- this.conditionBuilder = new sql_condition_builder_1.SqlConditionBuilder(this.entityStorage, applyJoinWrapper, this.statements);
32
- const subqueryBuilder = new sql_subquery_builder_1.SqlSubqueryBuilder(this.entityStorage, () => this.conditionBuilder);
41
+ this.conditionBuilder = new sql_condition_builder_1.SqlConditionBuilder(this.entityStorage, applyJoinWrapper, this.statements, this.driver);
42
+ const subqueryBuilder = new sql_subquery_builder_1.SqlSubqueryBuilder(this.entityStorage, () => this.conditionBuilder, this.driver);
33
43
  this.conditionBuilder.setSubqueryBuilder(subqueryBuilder);
34
44
  }
35
45
  // Lazy getter for modelTransformer - only created when transform is needed
@@ -53,7 +63,7 @@ class SqlBuilder {
53
63
  this.statements.columns = columns;
54
64
  this.originalColumns = columns || [];
55
65
  this.statements.alias = this.getAlias(tableName);
56
- this.statements.table = `"${schema}"."${tableName}"`;
66
+ this.statements.table = this.qualifyTable(schema, tableName);
57
67
  return this;
58
68
  }
59
69
  setStrategy(strategy = 'joined') {
@@ -70,7 +80,7 @@ class SqlBuilder {
70
80
  this.statements.statement = 'insert';
71
81
  this.statements.instance = value_processor_1.ValueProcessor.createInstance(processedValues, this.model, 'insert');
72
82
  this.statements.alias = this.getAlias(tableName);
73
- this.statements.table = `"${schema}"."${tableName}"`;
83
+ this.statements.table = this.qualifyTable(schema, tableName);
74
84
  this.statements.values = this.withUpdatedValues(this.withDefaultValues(processedValues, this.entity), this.entity);
75
85
  this.reflectToValues();
76
86
  return this;
@@ -80,7 +90,7 @@ class SqlBuilder {
80
90
  const processedValues = value_processor_1.ValueProcessor.processForUpdate(values, this.entity);
81
91
  this.statements.statement = 'update';
82
92
  this.statements.alias = this.getAlias(tableName);
83
- this.statements.table = `${schema}.${tableName}`;
93
+ this.statements.table = this.qualifyTable(schema, tableName);
84
94
  this.statements.values = this.withUpdatedValues(processedValues, this.entity);
85
95
  this.statements.instance = value_processor_1.ValueProcessor.createInstance(processedValues, this.model, 'update');
86
96
  return this;
@@ -89,7 +99,7 @@ class SqlBuilder {
89
99
  const { tableName, schema } = this.getTableName();
90
100
  this.statements.statement = 'delete';
91
101
  this.statements.alias = this.getAlias(tableName);
92
- this.statements.table = `${schema}.${tableName}`;
102
+ this.statements.table = this.qualifyTable(schema, tableName);
93
103
  return this;
94
104
  }
95
105
  where(where) {
@@ -143,20 +153,16 @@ class SqlBuilder {
143
153
  const { tableName, schema } = this.getTableName();
144
154
  this.statements.statement = 'count';
145
155
  this.statements.alias = this.getAlias(tableName);
146
- this.statements.table = `"${schema}"."${tableName}"`;
156
+ this.statements.table = this.qualifyTable(schema, tableName);
147
157
  return this;
148
158
  }
149
- getPrimaryKeyColumnName(entity) {
150
- // Logic to resolve the entity primary key column name
151
- // Replace this with your own logic based on your project structure
152
- // For example, if the primary key is always 'id', you can return 'id'.
153
- // If the logic becomes more complex, add a method on Options to resolve the primary key.
154
- return 'id';
155
- }
156
159
  shouldUseCache() {
157
160
  if (this.statements.statement !== 'select') {
158
161
  return false;
159
162
  }
163
+ if (this.statements.cache === false) {
164
+ return false;
165
+ }
160
166
  if (this.statements.cache instanceof Date) {
161
167
  return this.statements.cache.getTime() > Date.now();
162
168
  }
@@ -203,6 +209,9 @@ class SqlBuilder {
203
209
  if (this.shouldUseCache()) {
204
210
  await this.setCachedResult(result);
205
211
  }
212
+ if (this.isWriteOperation()) {
213
+ await this.invalidateCache();
214
+ }
206
215
  return result;
207
216
  }
208
217
  isWriteOperation() {
@@ -213,6 +222,11 @@ class SqlBuilder {
213
222
  if (!this.cacheManager) {
214
223
  return;
215
224
  }
225
+ const cacheConfig = orm_1.Orm.getInstance().connection.cache;
226
+ const shouldInvalidate = cacheConfig?.invalidateCacheOnWrite ?? true;
227
+ if (!shouldInvalidate) {
228
+ return;
229
+ }
216
230
  await this.cacheManager.invalidate(this.statements);
217
231
  }
218
232
  prepareColumns() {
@@ -299,9 +313,9 @@ class SqlBuilder {
299
313
  for (const row of rows) {
300
314
  const models = this.modelTransformer.transform(this.model, this.statements, row);
301
315
  this.afterHooks(models);
302
- await this.joinManager.handleSelectJoin(row, models);
303
316
  results.push(models);
304
317
  }
318
+ await this.joinManager.handleSelectJoinBatch(rows, results);
305
319
  return results;
306
320
  }
307
321
  hasOneToManyJoinedJoin() {
@@ -404,7 +418,7 @@ class SqlBuilder {
404
418
  if (!entity) {
405
419
  return models;
406
420
  }
407
- const primaryKey = this.getPrimaryKeyNameForEntity(entity);
421
+ const primaryKey = entity._primaryKeyPropertyName || 'id';
408
422
  const seen = new Set();
409
423
  const unique = [];
410
424
  for (const model of models) {
@@ -417,15 +431,7 @@ class SqlBuilder {
417
431
  return unique;
418
432
  }
419
433
  getPrimaryKeyName() {
420
- return this.getPrimaryKeyNameForEntity(this.entity);
421
- }
422
- getPrimaryKeyNameForEntity(entity) {
423
- for (const prop in entity.properties) {
424
- if (entity.properties[prop].options.isPrimary) {
425
- return prop;
426
- }
427
- }
428
- return 'id';
434
+ return this.entity._primaryKeyPropertyName || 'id';
429
435
  }
430
436
  async executeCount() {
431
437
  const result = await this.execute();
@@ -570,7 +576,9 @@ class SqlBuilder {
570
576
  applyOnInsert(values, key, property) {
571
577
  const columnName = property.options.columnName;
572
578
  values[columnName] = property.options.onInsert();
573
- this.updatedColumns.push(`${this.statements.alias}."${columnName}" as "${this.statements.alias}_${columnName}"`);
579
+ const col = this.quoteId(columnName);
580
+ const aliasedCol = this.quoteId(`${this.statements.alias}_${columnName}`);
581
+ this.updatedColumns.push(`${this.statements.alias}.${col} as ${aliasedCol}`);
574
582
  }
575
583
  withUpdatedValues(values, entityOptions) {
576
584
  const properties = Object.entries(entityOptions.properties).filter(([_, value]) => value.options.onUpdate);
@@ -580,7 +588,9 @@ class SqlBuilder {
580
588
  applyOnUpdate(values, property) {
581
589
  const columnName = property.options.columnName;
582
590
  values[columnName] = property.options.onUpdate();
583
- this.updatedColumns.push(`${this.statements.alias}."${columnName}" as "${this.statements.alias}_${columnName}"`);
591
+ const col = this.quoteId(columnName);
592
+ const aliasedCol = this.quoteId(`${this.statements.alias}_${columnName}`);
593
+ this.updatedColumns.push(`${this.statements.alias}.${col} as ${aliasedCol}`);
584
594
  }
585
595
  callHook(type, model) {
586
596
  const hooks = this.statements.hooks?.filter(hook => hook.type === type) || [];
@@ -49,6 +49,11 @@ export declare abstract class BaseEntity {
49
49
  * @return {boolean} Returns true if the object has been persisted, otherwise false.
50
50
  */
51
51
  isPersisted(): boolean;
52
+ /**
53
+ * Removes this entity from the database.
54
+ * Uses cached primary key property name instead of hardcoded 'id'.
55
+ */
56
+ remove(): Promise<void>;
52
57
  toJSON(): Record<string, any>;
53
58
  private serializeWithEntity;
54
59
  private serializeWithMetadata;
@@ -111,8 +111,12 @@ class BaseEntity {
111
111
  if (this.$_isPersisted) {
112
112
  qb.update(this._changedValues);
113
113
  qb.setInstance(this);
114
+ // Use cached primary key property name instead of hardcoded 'id'
115
+ const storage = entities_1.EntityStorage.getInstance();
116
+ const options = storage.get(this.constructor);
117
+ const pkName = options?._primaryKeyPropertyName || 'id';
114
118
  // @ts-ignore
115
- qb.where({ id: this._oldValues.id });
119
+ qb.where({ [pkName]: this._oldValues[pkName] });
116
120
  }
117
121
  else {
118
122
  qb.insert(this._oldValues);
@@ -134,6 +138,19 @@ class BaseEntity {
134
138
  isPersisted() {
135
139
  return this.$_isPersisted;
136
140
  }
141
+ /**
142
+ * Removes this entity from the database.
143
+ * Uses cached primary key property name instead of hardcoded 'id'.
144
+ */
145
+ async remove() {
146
+ const qb = this.createQueryBuilder();
147
+ const storage = entities_1.EntityStorage.getInstance();
148
+ const options = storage.get(this.constructor);
149
+ const pkName = options?._primaryKeyPropertyName || 'id';
150
+ // @ts-ignore
151
+ qb.delete().where({ [pkName]: this._oldValues[pkName] });
152
+ await qb.execute();
153
+ }
137
154
  toJSON() {
138
155
  const storage = entities_1.EntityStorage.getInstance();
139
156
  const entity = storage.get(this.constructor);
@@ -18,6 +18,8 @@ export type Options = {
18
18
  propertyName: string;
19
19
  }[];
20
20
  schema?: string;
21
+ _primaryKeyPropertyName?: string;
22
+ _primaryKeyColumnName?: string;
21
23
  };
22
24
  export declare class EntityStorage {
23
25
  static instance: EntityStorage;
@@ -34,6 +36,12 @@ export declare class EntityStorage {
34
36
  }[]): void;
35
37
  get(entity: Function): Options;
36
38
  entries(): MapIterator<[Function, Options]>;
39
+ /**
40
+ * Computa metadados da primary key a partir das propriedades da entidade.
41
+ * Chamado uma vez durante o registro da entidade para lookups O(1).
42
+ * @private
43
+ */
44
+ private computePrimaryKeyInfo;
37
45
  static getInstance(): EntityStorage;
38
46
  snapshot(values: Options): Promise<SnapshotTable>;
39
47
  private snapshotColumns;
@@ -112,6 +112,8 @@ let EntityStorage = EntityStorage_1 = class EntityStorage {
112
112
  const indexes = core_1.Metadata.get("indexes", entity.target) || [];
113
113
  const uniques = core_1.Metadata.get("uniques", entity.target) || [];
114
114
  const columnMap = buildIndexColumnMap(properties, relations);
115
+ // Compute primary key cache once during registration
116
+ const pkInfo = this.computePrimaryKeyInfo(properties);
115
117
  this.entities.set(entity.target, {
116
118
  properties: properties,
117
119
  hideProperties: Object.entries(properties)
@@ -123,6 +125,8 @@ let EntityStorage = EntityStorage_1 = class EntityStorage {
123
125
  hooks,
124
126
  tableName: entityName,
125
127
  ...entity.options,
128
+ _primaryKeyPropertyName: pkInfo.propertyName,
129
+ _primaryKeyColumnName: pkInfo.columnName,
126
130
  });
127
131
  }
128
132
  get(entity) {
@@ -131,6 +135,26 @@ let EntityStorage = EntityStorage_1 = class EntityStorage {
131
135
  entries() {
132
136
  return this.entities.entries();
133
137
  }
138
+ /**
139
+ * Computa metadados da primary key a partir das propriedades da entidade.
140
+ * Chamado uma vez durante o registro da entidade para lookups O(1).
141
+ * @private
142
+ */
143
+ computePrimaryKeyInfo(properties) {
144
+ for (const prop in properties) {
145
+ if (properties[prop].options.isPrimary) {
146
+ return {
147
+ propertyName: prop,
148
+ columnName: properties[prop].options.columnName,
149
+ };
150
+ }
151
+ }
152
+ // Fallback para 'id' (backward compatibility)
153
+ return {
154
+ propertyName: 'id',
155
+ columnName: 'id',
156
+ };
157
+ }
134
158
  static getInstance() {
135
159
  const scoped = orm_session_context_1.ormSessionContext.getStorage();
136
160
  if (scoped) {
@@ -13,7 +13,7 @@ export declare abstract class BunDriverBase implements Partial<DriverInterface>
13
13
  constructor(options: ConnectionSettings);
14
14
  protected buildConnectionString(options: ConnectionSettings): string;
15
15
  protected abstract getProtocol(): string;
16
- protected abstract getIdentifierQuote(): string;
16
+ abstract getIdentifierQuote(): string;
17
17
  connect(): Promise<void>;
18
18
  protected buildPoolOptions(options: ConnectionSettings): {
19
19
  max: number;
@@ -29,6 +29,7 @@ export declare abstract class BunDriverBase implements Partial<DriverInterface>
29
29
  transaction<T>(callback: (tx: SQL) => Promise<T>): Promise<T>;
30
30
  protected toDatabaseValue(value: unknown): string | number | boolean;
31
31
  protected escapeIdentifier(identifier: string): string;
32
+ protected formatDateForMysql(value: Date): string;
32
33
  protected buildWhereClause(where: string | undefined): string;
33
34
  protected buildOrderByClause(orderBy: string[] | undefined): string;
34
35
  protected buildLimitClause(limit: number | undefined): string;
@@ -41,7 +42,7 @@ export declare abstract class BunDriverBase implements Partial<DriverInterface>
41
42
  beforeSql: string;
42
43
  columnType: string;
43
44
  };
44
- protected abstract handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number): Promise<{
45
+ protected abstract handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number, context: any): Promise<{
45
46
  query: any;
46
47
  startTime: number;
47
48
  sql: string;
@@ -76,7 +76,10 @@ class BunDriverBase {
76
76
  return "NULL";
77
77
  }
78
78
  if (value instanceof Date) {
79
- return `'${value.toISOString()}'`;
79
+ const formatted = this.dbType === "mysql"
80
+ ? this.formatDateForMysql(value)
81
+ : value.toISOString();
82
+ return `'${formatted}'`;
80
83
  }
81
84
  switch (typeof value) {
82
85
  case "string":
@@ -94,6 +97,13 @@ class BunDriverBase {
94
97
  escapeIdentifier(identifier) {
95
98
  return `"${identifier}"`;
96
99
  }
100
+ formatDateForMysql(value) {
101
+ return value
102
+ .toISOString()
103
+ .replace('T', ' ')
104
+ .replace('Z', '')
105
+ .replace(/\.\d{3}/, '');
106
+ }
97
107
  buildWhereClause(where) {
98
108
  if (!where) {
99
109
  return "";
@@ -149,7 +159,7 @@ class BunDriverBase {
149
159
  if (statement.statement === "insert") {
150
160
  const sql = this.buildInsertSqlWithReturn(statement);
151
161
  const result = await context.unsafe(sql);
152
- return this.handleInsertReturn(statement, result, sql, startTime);
162
+ return this.handleInsertReturn(statement, result, sql, startTime, context);
153
163
  }
154
164
  const sql = this.buildStatementSql(statement);
155
165
  const result = await context.unsafe(sql);
@@ -210,7 +220,10 @@ class BunDriverBase {
210
220
  return "";
211
221
  return statement.join
212
222
  .map((join) => {
213
- const table = `${join.joinSchema}.${join.joinTable}`;
223
+ const q = this.getIdentifierQuote();
224
+ const table = this.dbType === 'mysql'
225
+ ? `${q}${join.joinTable}${q}`
226
+ : `${join.joinSchema}.${join.joinTable}`;
214
227
  return ` ${join.type} JOIN ${table} ${join.joinAlias} ON ${join.on}`;
215
228
  })
216
229
  .join("");
@@ -4,14 +4,14 @@ export declare class BunMysqlDriver extends BunDriverBase implements DriverInter
4
4
  readonly dbType: "mysql";
5
5
  constructor(options: ConnectionSettings);
6
6
  protected getProtocol(): string;
7
- protected getIdentifierQuote(): string;
7
+ getIdentifierQuote(): string;
8
8
  protected buildAutoIncrementType(colDiff: ColDiff): string;
9
9
  protected buildEnumType(schema: string | undefined, tableName: string, colDiff: ColDiff): {
10
10
  beforeSql: string;
11
11
  columnType: string;
12
12
  };
13
13
  protected appendReturningClause(sql: string, statement: Statement<any>): string;
14
- protected handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number): Promise<{
14
+ protected handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number, context: any): Promise<{
15
15
  query: any;
16
16
  startTime: number;
17
17
  sql: string;
@@ -28,7 +28,7 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
28
28
  appendReturningClause(sql, statement) {
29
29
  return sql;
30
30
  }
31
- async handleInsertReturn(statement, result, sql, startTime) {
31
+ async handleInsertReturn(statement, result, sql, startTime, context) {
32
32
  if (!statement.columns) {
33
33
  return {
34
34
  query: { rows: Array.isArray(result) ? result : [] },
@@ -36,10 +36,28 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
36
36
  sql,
37
37
  };
38
38
  }
39
- const insertId = result.lastInsertRowid;
39
+ let insertId;
40
+ // Check if ID was manually provided in the values
41
+ if (statement.values && statement.values.id) {
42
+ insertId = statement.values.id;
43
+ }
44
+ else {
45
+ // For AUTO_INCREMENT, use LAST_INSERT_ID()
46
+ const lastIdResult = await context.unsafe('SELECT LAST_INSERT_ID() as id');
47
+ insertId = lastIdResult[0]?.id;
48
+ }
49
+ if (!insertId) {
50
+ // If no ID available, return empty result
51
+ return {
52
+ query: { rows: [] },
53
+ startTime,
54
+ sql,
55
+ };
56
+ }
40
57
  const cols = statement.columns.join(', ').replaceAll(`${statement.alias}.`, '');
41
- const selectSql = `SELECT ${cols} FROM ${statement.table} WHERE id = ${insertId}`;
42
- const selectResult = await this.sql.unsafe(selectSql);
58
+ const idValue = this.toDatabaseValue(insertId);
59
+ const selectSql = `SELECT ${cols} FROM ${statement.table} WHERE id = ${idValue}`;
60
+ const selectResult = await context.unsafe(selectSql);
43
61
  return {
44
62
  query: { rows: Array.isArray(selectResult) ? selectResult : [] },
45
63
  startTime,
@@ -58,7 +76,7 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
58
76
  }
59
77
  getCreateTableInstruction(schema, tableName, creates) {
60
78
  let beforeSql = ``;
61
- const st = `CREATE TABLE \`${schema}\`.\`${tableName}\` (${creates
79
+ const st = `CREATE TABLE \`${tableName}\` (${creates
62
80
  .map((colDiff) => {
63
81
  const isAutoIncrement = colDiff.colChanges?.autoIncrement;
64
82
  let sql = ``;
@@ -92,7 +110,7 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
92
110
  return beforeSql + st;
93
111
  }
94
112
  getAlterTableFkInstruction(schema, tableName, colDiff, fk) {
95
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD CONSTRAINT \`${tableName}_${colDiff.colName}_fk\` FOREIGN KEY (\`${colDiff.colName}\`) REFERENCES \`${fk.referencedTableName}\` (\`${fk.referencedColumnName}\`);`;
113
+ return `ALTER TABLE \`${tableName}\` ADD CONSTRAINT \`${tableName}_${colDiff.colName}_fk\` FOREIGN KEY (\`${colDiff.colName}\`) REFERENCES \`${fk.referencedTableName}\` (\`${fk.referencedColumnName}\`);`;
96
114
  }
97
115
  getCreateIndex(index, schema, tableName) {
98
116
  const properties = index.properties || [];
@@ -103,7 +121,7 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
103
121
  throw new Error("Partial indexes are only supported on postgres.");
104
122
  }
105
123
  const columns = properties.map((prop) => `\`${prop}\``).join(', ');
106
- return `CREATE INDEX \`${index.name}\` ON \`${schema}\`.\`${tableName}\` (${columns});`;
124
+ return `CREATE INDEX \`${index.name}\` ON \`${tableName}\` (${columns});`;
107
125
  }
108
126
  getAddColumn(schema, tableName, colName, colDiff, colDiffInstructions) {
109
127
  let sql = ``;
@@ -111,10 +129,10 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
111
129
  const enumValues = colDiff.colChanges.enumItems
112
130
  .map((item) => `'${item}'`)
113
131
  .join(', ');
114
- sql += `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD COLUMN \`${colDiff.colName}\` ENUM(${enumValues})`;
132
+ sql += `ALTER TABLE \`${tableName}\` ADD COLUMN \`${colDiff.colName}\` ENUM(${enumValues})`;
115
133
  }
116
134
  else {
117
- sql += `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD COLUMN \`${colName}\` ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''}`;
135
+ sql += `ALTER TABLE \`${tableName}\` ADD COLUMN \`${colName}\` ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''}`;
118
136
  }
119
137
  if (!colDiff.colChanges?.nullable) {
120
138
  sql += ' NOT NULL';
@@ -131,15 +149,15 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
131
149
  colDiffInstructions.push(sql.concat(';'));
132
150
  if (colDiff.colChanges?.foreignKeys) {
133
151
  colDiff.colChanges.foreignKeys.forEach((fk) => {
134
- colDiffInstructions.push(`ALTER TABLE \`${schema}\`.\`${tableName}\` ADD CONSTRAINT \`${tableName}_${colName}_fk\` FOREIGN KEY (\`${colName}\`) REFERENCES \`${fk.referencedTableName}\` (\`${fk.referencedColumnName}\`);`);
152
+ colDiffInstructions.push(`ALTER TABLE \`${tableName}\` ADD CONSTRAINT \`${tableName}_${colName}_fk\` FOREIGN KEY (\`${colName}\`) REFERENCES \`${fk.referencedTableName}\` (\`${fk.referencedColumnName}\`);`);
135
153
  });
136
154
  }
137
155
  }
138
156
  getDropColumn(colDiffInstructions, schema, tableName, colName) {
139
- colDiffInstructions.push(`ALTER TABLE \`${schema}\`.\`${tableName}\` DROP COLUMN IF EXISTS \`${colName}\`;`);
157
+ colDiffInstructions.push(`ALTER TABLE \`${tableName}\` DROP COLUMN IF EXISTS \`${colName}\`;`);
140
158
  }
141
159
  getDropIndex(index, schema, tableName) {
142
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` DROP INDEX \`${index.name}\`;`;
160
+ return `ALTER TABLE \`${tableName}\` DROP INDEX \`${index.name}\`;`;
143
161
  }
144
162
  getCreateUniqueConstraint(unique, schema, tableName) {
145
163
  const properties = unique.properties || [];
@@ -147,37 +165,37 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
147
165
  throw new Error("Unique properties are required.");
148
166
  }
149
167
  const columns = properties.map((prop) => `\`${prop}\``).join(', ');
150
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD CONSTRAINT \`${unique.name}\` UNIQUE (${columns});`;
168
+ return `ALTER TABLE \`${tableName}\` ADD CONSTRAINT \`${unique.name}\` UNIQUE (${columns});`;
151
169
  }
152
170
  getDropUniqueConstraint(unique, schema, tableName) {
153
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` DROP INDEX \`${unique.name}\`;`;
171
+ return `ALTER TABLE \`${tableName}\` DROP INDEX \`${unique.name}\`;`;
154
172
  }
155
173
  getAlterTableType(schema, tableName, colName, colDiff) {
156
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''};`;
174
+ return `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''};`;
157
175
  }
158
176
  getAlterTableDefaultInstruction(schema, tableName, colName, colDiff) {
159
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` ALTER COLUMN \`${colName}\` SET DEFAULT ${colDiff.colChanges.default};`;
177
+ return `ALTER TABLE \`${tableName}\` ALTER COLUMN \`${colName}\` SET DEFAULT ${colDiff.colChanges.default};`;
160
178
  }
161
179
  getAlterTablePrimaryKeyInstruction(schema, tableName, colName, colDiff) {
162
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD PRIMARY KEY (\`${colName}\`);`;
180
+ return `ALTER TABLE \`${tableName}\` ADD PRIMARY KEY (\`${colName}\`);`;
163
181
  }
164
182
  getDropConstraint(param, schema, tableName) {
165
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` DROP FOREIGN KEY \`${param.name}\`;`;
183
+ return `ALTER TABLE \`${tableName}\` DROP FOREIGN KEY \`${param.name}\`;`;
166
184
  }
167
185
  getAddUniqueConstraint(schema, tableName, colName) {
168
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD UNIQUE (\`${colName}\`);`;
186
+ return `ALTER TABLE \`${tableName}\` ADD UNIQUE (\`${colName}\`);`;
169
187
  }
170
188
  getAlterTableDropNullInstruction(schema, tableName, colName, colDiff) {
171
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType} NULL;`;
189
+ return `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType} NULL;`;
172
190
  }
173
191
  getAlterTableDropNotNullInstruction(schema, tableName, colName, colDiff) {
174
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType} NOT NULL;`;
192
+ return `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType} NOT NULL;`;
175
193
  }
176
194
  getAlterTableEnumInstruction(schema, tableName, colName, colDiff) {
177
195
  const enumValues = colDiff.colChanges.enumItems
178
196
  .map((item) => `'${item}'`)
179
197
  .join(', ');
180
- return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ENUM(${enumValues});`;
198
+ return `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${colName}\` ENUM(${enumValues});`;
181
199
  }
182
200
  getDropTypeEnumInstruction(param, schema, tableName) {
183
201
  return '';
@@ -224,7 +242,7 @@ class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
224
242
  return match[1].split(',').map((v) => v.trim().replace(/'/g, ''));
225
243
  }
226
244
  async index(tableName, options) {
227
- const result = await this.sql.unsafe(`SHOW INDEX FROM \`${tableName}\` FROM \`${options.schema || 'information_schema'}\``);
245
+ const result = await this.sql.unsafe(`SHOW INDEX FROM \`${tableName}\``);
228
246
  return result
229
247
  .filter((row) => row.Key_name !== 'PRIMARY')
230
248
  .map((row) => {
@@ -4,14 +4,14 @@ export declare class BunPgDriver extends BunDriverBase implements DriverInterfac
4
4
  readonly dbType: "postgres";
5
5
  constructor(options: ConnectionSettings);
6
6
  protected getProtocol(): string;
7
- protected getIdentifierQuote(): string;
7
+ getIdentifierQuote(): string;
8
8
  protected buildAutoIncrementType(colDiff: ColDiff): string;
9
9
  protected buildEnumType(schema: string | undefined, tableName: string, colDiff: ColDiff): {
10
10
  beforeSql: string;
11
11
  columnType: string;
12
12
  };
13
13
  protected appendReturningClause(sql: string, statement: Statement<any>): string;
14
- protected handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number): Promise<{
14
+ protected handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number, context: any): Promise<{
15
15
  query: any;
16
16
  startTime: number;
17
17
  sql: string;
@@ -29,7 +29,7 @@ class BunPgDriver extends bun_driver_base_1.BunDriverBase {
29
29
  const cols = statement.columns.join(', ').replaceAll(`${statement.alias}.`, '');
30
30
  return `${sql} RETURNING ${cols}`;
31
31
  }
32
- async handleInsertReturn(statement, result, sql, startTime) {
32
+ async handleInsertReturn(statement, result, sql, startTime, context) {
33
33
  return {
34
34
  query: { rows: Array.isArray(result) ? result : [] },
35
35
  startTime,
@@ -0,0 +1,12 @@
1
+ import { ConnectionSettings, DriverInterface } from './driver.interface';
2
+ export type DriverType = 'postgres' | 'mysql';
3
+ export type DriverClass = new (options: ConnectionSettings) => DriverInterface;
4
+ export declare function getDriverType(): DriverType;
5
+ export declare function getDriverClass(type: DriverType): DriverClass;
6
+ export declare function getDefaultConnectionSettings(type: DriverType): {
7
+ host: string;
8
+ port: number;
9
+ database: string;
10
+ username: string;
11
+ password: string;
12
+ };
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDriverType = getDriverType;
4
+ exports.getDriverClass = getDriverClass;
5
+ exports.getDefaultConnectionSettings = getDefaultConnectionSettings;
6
+ const bun_pg_driver_1 = require("./bun-pg.driver");
7
+ const bun_mysql_driver_1 = require("./bun-mysql.driver");
8
+ function getDriverType() {
9
+ const envDriver = process.env.DB_DRIVER?.toLowerCase();
10
+ return envDriver === 'mysql' ? 'mysql' : 'postgres';
11
+ }
12
+ function getDriverClass(type) {
13
+ return type === 'mysql' ? bun_mysql_driver_1.BunMysqlDriver : bun_pg_driver_1.BunPgDriver;
14
+ }
15
+ function getDefaultConnectionSettings(type) {
16
+ if (type === 'mysql') {
17
+ return {
18
+ host: 'localhost',
19
+ port: 3306,
20
+ database: 'mysql_test',
21
+ username: 'root',
22
+ password: 'root',
23
+ };
24
+ }
25
+ return {
26
+ host: 'localhost',
27
+ port: 5433,
28
+ database: 'postgres',
29
+ username: 'postgres',
30
+ password: 'postgres',
31
+ };
32
+ }
@@ -5,6 +5,7 @@ import { ValueObject } from "../common/value-object";
5
5
  export interface DriverInterface {
6
6
  connectionString: string;
7
7
  readonly dbType: "postgres" | "mysql";
8
+ getIdentifierQuote(): string;
8
9
  executeStatement(statement: Statement<any>): Promise<{
9
10
  query: any;
10
11
  startTime: number;
@@ -46,6 +47,7 @@ export type SnapshotConstraintInfo = {
46
47
  };
47
48
  export interface CacheSettings {
48
49
  maxKeysPerTable?: number;
50
+ invalidateCacheOnWrite?: boolean;
49
51
  }
50
52
  export interface ConnectionSettings<T extends DriverInterface = DriverInterface> {
51
53
  host?: string;