@mikro-orm/oracledb 7.1.0-dev.2 → 7.1.0-dev.21

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.
@@ -2,6 +2,8 @@ import { type AbstractSqlConnection, type CheckDef, type Column, type DatabaseSc
2
2
  /** Schema introspection helper for Oracle Database. */
3
3
  export declare class OracleSchemaHelper extends SchemaHelper {
4
4
  static readonly DEFAULT_VALUES: Record<string, string[]>;
5
+ private static readonly AUTO_NOT_NULL_RE;
6
+ private static readonly PARTIAL_INDEX_RE;
5
7
  getDatabaseExistsSQL(name: string): string;
6
8
  getAllTables(connection: AbstractSqlConnection, schemas?: string[], ctx?: Transaction): Promise<Table[]>;
7
9
  getListTablesSQL(schemaName?: string): string;
@@ -35,6 +37,9 @@ export declare class OracleSchemaHelper extends SchemaHelper {
35
37
  createTableColumn(column: Column, table: DatabaseTable, changedProperties?: Set<string>): string | undefined;
36
38
  alterTableColumn(column: Column, table: DatabaseTable, changedProperties: Set<string>): string[];
37
39
  getCreateIndexSQL(tableName: string, index: IndexDef, partialExpression?: boolean): string;
40
+ protected getIndexColumns(index: IndexDef): string;
41
+ /** Oracle has no native WHERE clause for indexes; the predicate is folded into CASE-WHEN columns. */
42
+ protected getIndexWhereClause(_index: IndexDef): string;
38
43
  createIndex(index: IndexDef, table: DatabaseTable, createPrimary?: boolean): string;
39
44
  dropForeignKey(tableName: string, constraintName: string): string;
40
45
  dropViewIfExists(name: string, schema?: string): string;
@@ -7,6 +7,12 @@ export class OracleSchemaHelper extends SchemaHelper {
7
7
  systimestamp: ['current_timestamp'],
8
8
  sysdate: ['current_timestamp'],
9
9
  };
10
+ // `stripAutoNotNullFilter` unwraps balanced per-clause parens before calling `.exec`, so we
11
+ // only need to match the bare form here.
12
+ static AUTO_NOT_NULL_RE = /^"?([^"\s()]+)"?\s+is\s+not\s+null$/i;
13
+ // Greedy `(.+)` so nested CASE expressions inside the predicate don't trip the match on
14
+ // an inner `then <col> end`.
15
+ static PARTIAL_INDEX_RE = /^\s*\(?\s*case\s+when\s+(.+)\s+then\s+"?([^"\s)]+)"?\s+end\s*\)?\s*$/is;
10
16
  getDatabaseExistsSQL(name) {
11
17
  return `select 1 from all_users where username = ${this.platform.quoteValue(name)}`;
12
18
  }
@@ -210,16 +216,19 @@ export class OracleSchemaHelper extends SchemaHelper {
210
216
  if (isPrimary) {
211
217
  continue;
212
218
  }
219
+ const partialMatch = typeof index.expression === 'string' ? OracleSchemaHelper.PARTIAL_INDEX_RE.exec(index.expression) : null;
213
220
  const indexDef = {
214
- columnNames: [index.column_name],
221
+ columnNames: [partialMatch ? partialMatch[2] : index.column_name],
215
222
  keyName: index.index_name,
216
223
  unique: index.is_unique === 'YES',
217
- primary: false, // We skip PK indexes above, so this is always false
224
+ primary: false,
218
225
  constraint: isConstraintIndex || index.is_unique === 'YES',
219
226
  };
220
- // Handle function-based indexes (expression indexes)
221
- /* v8 ignore start: expression index branches */
222
- if (index.expression) {
227
+ /* v8 ignore start: function-based (non-partial) index branches */
228
+ if (partialMatch) {
229
+ indexDef.where = partialMatch[1].trim();
230
+ }
231
+ else if (index.expression) {
223
232
  indexDef.expression = index.expression;
224
233
  }
225
234
  else if (index.column_name?.match(/[(): ,"'`]/)) {
@@ -231,6 +240,17 @@ export class OracleSchemaHelper extends SchemaHelper {
231
240
  }
232
241
  for (const key of Object.keys(ret)) {
233
242
  ret[key] = await this.mapIndexes(ret[key]);
243
+ for (const idx of ret[key]) {
244
+ if (idx.where) {
245
+ const stripped = this.stripAutoNotNullFilter(idx.where, idx.columnNames, OracleSchemaHelper.AUTO_NOT_NULL_RE);
246
+ if (stripped === '') {
247
+ delete idx.where;
248
+ }
249
+ else {
250
+ idx.where = stripped;
251
+ }
252
+ }
253
+ }
234
254
  }
235
255
  return ret;
236
256
  }
@@ -503,6 +523,16 @@ export class OracleSchemaHelper extends SchemaHelper {
503
523
  }
504
524
  return super.getCreateIndexSQL(tableName, index);
505
525
  }
526
+ getIndexColumns(index) {
527
+ if (index.where) {
528
+ return this.emulatePartialIndexColumns(index);
529
+ }
530
+ return super.getIndexColumns(index);
531
+ }
532
+ /** Oracle has no native WHERE clause for indexes; the predicate is folded into CASE-WHEN columns. */
533
+ getIndexWhereClause(_index) {
534
+ return '';
535
+ }
506
536
  createIndex(index, table, createPrimary = false) {
507
537
  if (index.primary) {
508
538
  return '';
@@ -524,10 +554,21 @@ export class OracleSchemaHelper extends SchemaHelper {
524
554
  const quotedTableName = table.getQuotedName();
525
555
  if (index.unique) {
526
556
  const nullableCols = index.columnNames.filter(column => table.getColumn(column)?.nullable);
557
+ const autoNotNull = nullableCols.length
558
+ ? nullableCols.map(c => `${this.quote(c)} is not null`).join(' and ')
559
+ : '';
560
+ if (index.where) {
561
+ // Wrap the user predicate in parens before ANDing the auto-NOT-NULL guard — otherwise a
562
+ // disjunctive `a = 1 or b = 2` would rebind as `a = 1 or (b = 2 and <col> is not null)`.
563
+ const predicate = autoNotNull ? `(${index.where}) and ${autoNotNull}` : index.where;
564
+ return `create unique index ${this.quote(index.keyName)} on ${quotedTableName} (${index.columnNames
565
+ .map(c => `case when ${predicate} then ${this.quote(c)} end`)
566
+ .join(', ')})`;
567
+ }
527
568
  return `create unique index ${this.quote(index.keyName)} on ${quotedTableName} (${index.columnNames
528
569
  .map(c => {
529
570
  if (table.getColumn(c)?.nullable) {
530
- return `case when ${nullableCols.map(c => `${this.quote(c)} is not null`).join(' and ')} then ${this.quote(c)} end`;
571
+ return `case when ${autoNotNull} then ${this.quote(c)} end`;
531
572
  }
532
573
  return this.quote(c);
533
574
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/oracledb",
3
- "version": "7.1.0-dev.2",
3
+ "version": "7.1.0-dev.21",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite, MSSQL and Oracle databases.",
5
5
  "keywords": [
6
6
  "data-mapper",
@@ -42,15 +42,15 @@
42
42
  "copy": "node ../../scripts/copy.mjs"
43
43
  },
44
44
  "dependencies": {
45
- "@mikro-orm/sql": "7.1.0-dev.2",
45
+ "@mikro-orm/sql": "7.1.0-dev.21",
46
46
  "kysely": "0.28.16",
47
47
  "oracledb": "6.10.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@mikro-orm/core": "^7.0.11"
50
+ "@mikro-orm/core": "^7.0.12"
51
51
  },
52
52
  "peerDependencies": {
53
- "@mikro-orm/core": "7.1.0-dev.2"
53
+ "@mikro-orm/core": "7.1.0-dev.21"
54
54
  },
55
55
  "engines": {
56
56
  "node": ">= 22.17.0"