@mikro-orm/sql 7.0.0-rc.2 → 7.0.0

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.
Files changed (66) hide show
  1. package/AbstractSqlConnection.d.ts +5 -4
  2. package/AbstractSqlConnection.js +20 -6
  3. package/AbstractSqlDriver.d.ts +19 -13
  4. package/AbstractSqlDriver.js +225 -47
  5. package/AbstractSqlPlatform.d.ts +35 -0
  6. package/AbstractSqlPlatform.js +51 -5
  7. package/PivotCollectionPersister.d.ts +2 -11
  8. package/PivotCollectionPersister.js +59 -59
  9. package/README.md +5 -4
  10. package/SqlEntityManager.d.ts +2 -2
  11. package/SqlEntityManager.js +5 -5
  12. package/dialects/index.d.ts +1 -0
  13. package/dialects/index.js +1 -0
  14. package/dialects/mssql/MsSqlNativeQueryBuilder.d.ts +2 -0
  15. package/dialects/mssql/MsSqlNativeQueryBuilder.js +8 -4
  16. package/dialects/mysql/BaseMySqlPlatform.d.ts +6 -0
  17. package/dialects/mysql/BaseMySqlPlatform.js +18 -2
  18. package/dialects/mysql/MySqlSchemaHelper.d.ts +1 -1
  19. package/dialects/mysql/MySqlSchemaHelper.js +25 -14
  20. package/dialects/oracledb/OracleDialect.d.ts +78 -0
  21. package/dialects/oracledb/OracleDialect.js +166 -0
  22. package/dialects/oracledb/OracleNativeQueryBuilder.d.ts +19 -0
  23. package/dialects/oracledb/OracleNativeQueryBuilder.js +249 -0
  24. package/dialects/oracledb/index.d.ts +2 -0
  25. package/dialects/oracledb/index.js +2 -0
  26. package/dialects/postgresql/BasePostgreSqlPlatform.d.ts +6 -0
  27. package/dialects/postgresql/BasePostgreSqlPlatform.js +49 -37
  28. package/dialects/postgresql/PostgreSqlSchemaHelper.js +75 -59
  29. package/dialects/sqlite/BaseSqliteConnection.js +2 -2
  30. package/dialects/sqlite/NodeSqliteDialect.js +3 -1
  31. package/dialects/sqlite/SqlitePlatform.d.ts +1 -0
  32. package/dialects/sqlite/SqlitePlatform.js +7 -1
  33. package/dialects/sqlite/SqliteSchemaHelper.js +23 -17
  34. package/index.d.ts +1 -1
  35. package/index.js +0 -1
  36. package/package.json +30 -30
  37. package/plugin/index.d.ts +1 -14
  38. package/plugin/index.js +13 -13
  39. package/plugin/transformer.d.ts +6 -22
  40. package/plugin/transformer.js +91 -82
  41. package/query/ArrayCriteriaNode.d.ts +1 -1
  42. package/query/CriteriaNode.js +28 -10
  43. package/query/CriteriaNodeFactory.js +20 -4
  44. package/query/NativeQueryBuilder.d.ts +28 -3
  45. package/query/NativeQueryBuilder.js +65 -3
  46. package/query/ObjectCriteriaNode.js +75 -31
  47. package/query/QueryBuilder.d.ts +199 -100
  48. package/query/QueryBuilder.js +544 -358
  49. package/query/QueryBuilderHelper.d.ts +18 -14
  50. package/query/QueryBuilderHelper.js +364 -147
  51. package/query/ScalarCriteriaNode.js +17 -8
  52. package/query/enums.d.ts +2 -0
  53. package/query/enums.js +2 -0
  54. package/query/raw.js +1 -1
  55. package/schema/DatabaseSchema.d.ts +7 -5
  56. package/schema/DatabaseSchema.js +68 -45
  57. package/schema/DatabaseTable.d.ts +8 -6
  58. package/schema/DatabaseTable.js +191 -107
  59. package/schema/SchemaComparator.d.ts +1 -3
  60. package/schema/SchemaComparator.js +76 -50
  61. package/schema/SchemaHelper.d.ts +2 -13
  62. package/schema/SchemaHelper.js +30 -9
  63. package/schema/SqlSchemaGenerator.d.ts +4 -14
  64. package/schema/SqlSchemaGenerator.js +26 -12
  65. package/typings.d.ts +10 -5
  66. package/tsconfig.build.tsbuildinfo +0 -1
@@ -7,6 +7,8 @@ import { FullTextType } from './FullTextType.js';
7
7
  export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
8
8
  schemaHelper = new PostgreSqlSchemaHelper(this);
9
9
  exceptionConverter = new PostgreSqlExceptionConverter();
10
+ /** Maps JS runtime type names to PostgreSQL cast types for JSON property access. @internal */
11
+ #jsonTypeCasts = { number: 'float8', bigint: 'int8', boolean: 'bool' };
10
12
  createNativeQueryBuilder() {
11
13
  return new PostgreSqlNativeQueryBuilder(this);
12
14
  }
@@ -113,8 +115,10 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
113
115
  }
114
116
  getMappedType(type) {
115
117
  switch (this.extractSimpleType(type)) {
116
- case 'tsvector': return Type.getType(FullTextType);
117
- default: return super.getMappedType(type);
118
+ case 'tsvector':
119
+ return Type.getType(FullTextType);
120
+ default:
121
+ return super.getMappedType(type);
118
122
  }
119
123
  }
120
124
  getRegExpOperator(val, flags) {
@@ -132,7 +136,7 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
132
136
  return { $re: val.source };
133
137
  }
134
138
  isBigIntProperty(prop) {
135
- return super.isBigIntProperty(prop) || (['bigserial', 'int8'].includes(prop.columnTypes?.[0]));
139
+ return super.isBigIntProperty(prop) || ['bigserial', 'int8'].includes(prop.columnTypes?.[0]);
136
140
  }
137
141
  getArrayDeclarationSQL() {
138
142
  return 'text[]';
@@ -166,7 +170,7 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
166
170
  return ['begin'];
167
171
  }
168
172
  marshallArray(values) {
169
- const quote = (v) => v === '' || v.match(/["{},\\]/) ? JSON.stringify(v) : v;
173
+ const quote = (v) => (v === '' || /["{},\\]/.exec(v) ? JSON.stringify(v) : v);
170
174
  return `{${values.map(v => quote('' + v)).join(',')}}`;
171
175
  }
172
176
  /* v8 ignore next */
@@ -174,11 +178,14 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
174
178
  if (value === '{}') {
175
179
  return [];
176
180
  }
177
- return value.substring(1, value.length - 1).split(',').map(v => {
181
+ return value
182
+ .substring(1, value.length - 1)
183
+ .split(',')
184
+ .map(v => {
178
185
  if (v === `""`) {
179
186
  return '';
180
187
  }
181
- if (v.match(/"(.*)"/)) {
188
+ if (/"(.*)"/.exec(v)) {
182
189
  return v.substring(1, v.length - 1).replaceAll('\\"', '"');
183
190
  }
184
191
  return v;
@@ -210,15 +217,11 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
210
217
  const last = path.pop();
211
218
  const root = this.quoteIdentifier(aliased ? `${ALIAS_REPLACEMENT}.${first}` : first);
212
219
  type = typeof type === 'string' ? this.getMappedType(type).runtimeType : String(type);
213
- const types = {
214
- number: 'float8',
215
- bigint: 'int8',
216
- boolean: 'bool',
217
- };
218
- const cast = (key) => raw(type in types ? `(${key})::${types[type]}` : key);
220
+ const cast = (key) => raw(type in this.#jsonTypeCasts ? `(${key})::${this.#jsonTypeCasts[type]}` : key);
219
221
  let lastOperator = '->>';
220
222
  // force `->` for operator payloads with array values
221
- if (Utils.isPlainObject(value) && Object.keys(value).every(key => ARRAY_OPERATORS.includes(key) && Array.isArray(value[key]))) {
223
+ if (Utils.isPlainObject(value) &&
224
+ Object.keys(value).every(key => ARRAY_OPERATORS.includes(key) && Array.isArray(value[key]))) {
222
225
  lastOperator = '->';
223
226
  }
224
227
  if (path.length === 0) {
@@ -227,8 +230,7 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
227
230
  return cast(`${root}->${path.map(a => this.quoteValue(a)).join('->')}${lastOperator}'${last}'`);
228
231
  }
229
232
  getJsonIndexDefinition(index) {
230
- return index.columnNames
231
- .map(column => {
233
+ return index.columnNames.map(column => {
232
234
  if (!column.includes('.')) {
233
235
  return column;
234
236
  }
@@ -286,26 +288,26 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
286
288
  getDefaultMappedType(type) {
287
289
  const normalizedType = this.extractSimpleType(type);
288
290
  const map = {
289
- 'int2': 'smallint',
290
- 'smallserial': 'smallint',
291
- 'int': 'integer',
292
- 'int4': 'integer',
293
- 'serial': 'integer',
294
- 'serial4': 'integer',
295
- 'int8': 'bigint',
296
- 'bigserial': 'bigint',
297
- 'serial8': 'bigint',
298
- 'numeric': 'decimal',
299
- 'bool': 'boolean',
300
- 'real': 'float',
301
- 'float4': 'float',
302
- 'float8': 'double',
303
- 'timestamp': 'datetime',
304
- 'timestamptz': 'datetime',
305
- 'bytea': 'blob',
306
- 'jsonb': 'json',
291
+ int2: 'smallint',
292
+ smallserial: 'smallint',
293
+ int: 'integer',
294
+ int4: 'integer',
295
+ serial: 'integer',
296
+ serial4: 'integer',
297
+ int8: 'bigint',
298
+ bigserial: 'bigint',
299
+ serial8: 'bigint',
300
+ numeric: 'decimal',
301
+ bool: 'boolean',
302
+ real: 'float',
303
+ float4: 'float',
304
+ float8: 'double',
305
+ timestamp: 'datetime',
306
+ timestamptz: 'datetime',
307
+ bytea: 'blob',
308
+ jsonb: 'json',
307
309
  'character varying': 'varchar',
308
- 'bpchar': 'character',
310
+ bpchar: 'character',
309
311
  };
310
312
  return super.getDefaultMappedType(map[normalizedType] ?? type);
311
313
  }
@@ -339,11 +341,21 @@ export class BasePostgreSqlPlatform extends AbstractSqlPlatform {
339
341
  */
340
342
  castColumn(prop) {
341
343
  switch (prop?.columnTypes?.[0]) {
342
- case this.getUuidTypeDeclarationSQL({}): return '::text';
343
- case this.getBooleanTypeDeclarationSQL(): return '::int';
344
- default: return '';
344
+ case this.getUuidTypeDeclarationSQL({}):
345
+ return '::text';
346
+ case this.getBooleanTypeDeclarationSQL():
347
+ return '::int';
348
+ default:
349
+ return '';
345
350
  }
346
351
  }
352
+ getJsonArrayFromSQL(column, alias, _properties) {
353
+ return `jsonb_array_elements(${column}) as ${this.quoteIdentifier(alias)}`;
354
+ }
355
+ getJsonArrayElementPropertySQL(alias, property, type) {
356
+ const expr = `${this.quoteIdentifier(alias)}->>${this.quoteValue(property)}`;
357
+ return type in this.#jsonTypeCasts ? `(${expr})::${this.#jsonTypeCasts[type]}` : expr;
358
+ }
347
359
  getDefaultClientUrl() {
348
360
  return 'postgresql://postgres@127.0.0.1:5432';
349
361
  }
@@ -1,4 +1,4 @@
1
- import { DeferMode, EnumType, Type, Utils } from '@mikro-orm/core';
1
+ import { DeferMode, EnumType, Type, Utils, } from '@mikro-orm/core';
2
2
  import { SchemaHelper } from '../../schema/SchemaHelper.js';
3
3
  /** PostGIS system views that should be automatically ignored */
4
4
  const POSTGIS_VIEWS = ['geography_columns', 'geometry_columns'];
@@ -19,27 +19,27 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
19
19
  return `set names '${charset}';\n\n`;
20
20
  }
21
21
  getCreateDatabaseSQL(name) {
22
- return `create database ${name}`;
22
+ return `create database ${this.quote(name)}`;
23
23
  }
24
24
  getListTablesSQL() {
25
- return `select table_name, table_schema as schema_name, `
26
- + `(select pg_catalog.obj_description(c.oid) from pg_catalog.pg_class c
27
- where c.oid = (select ('"' || table_schema || '"."' || table_name || '"')::regclass::oid) and c.relname = table_name) as table_comment `
28
- + `from information_schema.tables `
29
- + `where ${this.getIgnoredNamespacesConditionSQL('table_schema')} `
30
- + `and table_name != 'geometry_columns' and table_name != 'spatial_ref_sys' and table_type != 'VIEW' `
31
- + `and table_name not in (select inhrelid::regclass::text from pg_inherits) `
32
- + `order by table_name`;
25
+ return (`select table_name, table_schema as schema_name, ` +
26
+ `(select pg_catalog.obj_description(c.oid) from pg_catalog.pg_class c
27
+ where c.oid = (select ('"' || table_schema || '"."' || table_name || '"')::regclass::oid) and c.relname = table_name) as table_comment ` +
28
+ `from information_schema.tables ` +
29
+ `where ${this.getIgnoredNamespacesConditionSQL('table_schema')} ` +
30
+ `and table_name != 'geometry_columns' and table_name != 'spatial_ref_sys' and table_type != 'VIEW' ` +
31
+ `and table_name not in (select inhrelid::regclass::text from pg_inherits) ` +
32
+ `order by table_name`);
33
33
  }
34
34
  getIgnoredViewsCondition() {
35
35
  return POSTGIS_VIEWS.map(v => `table_name != '${v}'`).join(' and ');
36
36
  }
37
37
  getListViewsSQL() {
38
- return `select table_name as view_name, table_schema as schema_name, view_definition `
39
- + `from information_schema.views `
40
- + `where ${this.getIgnoredNamespacesConditionSQL('table_schema')} `
41
- + `and ${this.getIgnoredViewsCondition()} `
42
- + `order by table_name`;
38
+ return (`select table_name as view_name, table_schema as schema_name, view_definition ` +
39
+ `from information_schema.views ` +
40
+ `where ${this.getIgnoredNamespacesConditionSQL('table_schema')} ` +
41
+ `and ${this.getIgnoredViewsCondition()} ` +
42
+ `order by table_name`);
43
43
  }
44
44
  async loadViews(schema, connection) {
45
45
  const views = await connection.execute(this.getListViewsSQL());
@@ -51,10 +51,10 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
51
51
  }
52
52
  }
53
53
  getListMaterializedViewsSQL() {
54
- return `select matviewname as view_name, schemaname as schema_name, definition as view_definition `
55
- + `from pg_matviews `
56
- + `where ${this.getIgnoredNamespacesConditionSQL('schemaname')} `
57
- + `order by matviewname`;
54
+ return (`select matviewname as view_name, schemaname as schema_name, definition as view_definition ` +
55
+ `from pg_matviews ` +
56
+ `where ${this.getIgnoredNamespacesConditionSQL('schemaname')} ` +
57
+ `order by matviewname`);
58
58
  }
59
59
  async loadMaterializedViews(schema, connection, schemaName) {
60
60
  const views = await connection.execute(this.getListMaterializedViewsSQL());
@@ -78,9 +78,9 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
78
78
  return `refresh materialized view${concurrent} ${this.quote(this.getTableName(name, schema))}`;
79
79
  }
80
80
  async getNamespaces(connection) {
81
- const sql = `select schema_name from information_schema.schemata `
82
- + `where ${this.getIgnoredNamespacesConditionSQL()} `
83
- + `order by schema_name`;
81
+ const sql = `select schema_name from information_schema.schemata ` +
82
+ `where ${this.getIgnoredNamespacesConditionSQL()} ` +
83
+ `order by schema_name`;
84
84
  const res = await connection.execute(sql);
85
85
  return res.map(row => row.schema_name);
86
86
  }
@@ -90,13 +90,11 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
90
90
  'tiger',
91
91
  'topology',
92
92
  /* v8 ignore next */
93
- ...this.platform.getConfig().get('schemaGenerator').ignoreSchema ?? [],
94
- ].map(s => this.platform.quoteValue(s)).join(', ');
95
- const ignoredPrefixes = [
96
- 'pg_',
97
- 'crdb_',
98
- '_timescaledb_',
99
- ].map(p => `"${column}" not like '${p}%'`).join(' and ');
93
+ ...(this.platform.getConfig().get('schemaGenerator').ignoreSchema ?? []),
94
+ ]
95
+ .map(s => this.platform.quoteValue(s))
96
+ .join(', ');
97
+ const ignoredPrefixes = ['pg_', 'crdb_', '_timescaledb_'].map(p => `"${column}" not like '${p}%'`).join(' and ');
100
98
  return `${ignoredPrefixes} and "${column}" not in (${ignored})`;
101
99
  }
102
100
  async loadInformationSchema(schema, connection, tables, schemas) {
@@ -130,9 +128,7 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
130
128
  const key = this.getTableKey(index);
131
129
  // Extract INCLUDE columns from expression first, to filter them from key columns
132
130
  const includeMatch = index.expression?.match(/include\s*\(([^)]+)\)/i);
133
- const includeColumns = includeMatch
134
- ? includeMatch[1].split(',').map((col) => unquote(col.trim()))
135
- : [];
131
+ const includeColumns = includeMatch ? includeMatch[1].split(',').map((col) => unquote(col.trim())) : [];
136
132
  // Filter out INCLUDE columns from the column definitions to get only key columns
137
133
  const keyColumnDefs = index.index_def.filter((col) => !includeColumns.includes(unquote(col)));
138
134
  // Parse sort order and NULLS ordering from the full expression
@@ -156,7 +152,7 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
156
152
  if (index.condeferrable) {
157
153
  indexDef.deferMode = index.condeferred ? DeferMode.INITIALLY_DEFERRED : DeferMode.INITIALLY_IMMEDIATE;
158
154
  }
159
- if (index.index_def.some((col) => col.match(/[(): ,"'`]/)) || index.expression?.match(/ where /i)) {
155
+ if (index.index_def.some((col) => /[(): ,"'`]/.exec(col)) || index.expression?.match(/ where /i)) {
160
156
  indexDef.expression = index.expression;
161
157
  }
162
158
  if (index.deferrable) {
@@ -194,7 +190,7 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
194
190
  // Extract just the column list from the expression (between first parens after USING)
195
191
  // Pattern: ... USING method (...columns...) [INCLUDE (...)] [WHERE ...]
196
192
  // Note: pg_get_indexdef always returns a valid expression with USING clause
197
- const usingMatch = expression.match(/using\s+\w+\s*\(/i);
193
+ const usingMatch = /using\s+\w+\s*\(/i.exec(expression);
198
194
  const startIdx = usingMatch.index + usingMatch[0].length - 1; // Position of opening (
199
195
  const columnsStr = this.extractParenthesizedContent(expression, startIdx);
200
196
  // Use the column names from columnDefs and find their modifiers in the expression
@@ -213,12 +209,12 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
213
209
  result.sort = 'DESC';
214
210
  }
215
211
  // Extract NULLS ordering
216
- const nullsMatch = modifiers.match(/nulls\s+(first|last)/i);
212
+ const nullsMatch = /nulls\s+(first|last)/i.exec(modifiers);
217
213
  if (nullsMatch) {
218
214
  result.nulls = nullsMatch[1].toUpperCase();
219
215
  }
220
216
  // Extract collation
221
- const collateMatch = modifiers.match(/collate\s+"?([^"\s,)]+)"?/i);
217
+ const collateMatch = /collate\s+"?([^"\s,)]+)"?/i.exec(modifiers);
222
218
  if (collateMatch) {
223
219
  result.collation = collateMatch[1];
224
220
  }
@@ -268,17 +264,18 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
268
264
  where (${[...tablesBySchemas.entries()].map(([schema, tables]) => `(table_schema = ${this.platform.quoteValue(schema)} and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(',')}))`).join(' or ')})
269
265
  order by ordinal_position`;
270
266
  const allColumns = await connection.execute(sql);
271
- const str = (val) => val != null ? '' + val : val;
267
+ const str = (val) => (val != null ? '' + val : val);
272
268
  const ret = {};
273
269
  for (const col of allColumns) {
274
270
  const mappedType = connection.getPlatform().getMappedType(col.data_type);
275
- const increments = (col.column_default?.includes('nextval') || col.is_identity === 'YES') && connection.getPlatform().isNumericColumn(mappedType);
271
+ const increments = (col.column_default?.includes('nextval') || col.is_identity === 'YES') &&
272
+ connection.getPlatform().isNumericColumn(mappedType);
276
273
  const key = this.getTableKey(col);
277
274
  ret[key] ??= [];
278
- let type = col.data_type.toLowerCase() === 'array'
279
- ? col.udt_name.replace(/^_(.*)$/, '$1[]')
280
- : col.udt_name;
281
- if (col.data_type === 'USER-DEFINED' && col.udt_schema && col.udt_schema !== this.platform.getDefaultSchemaName()) {
275
+ let type = col.data_type.toLowerCase() === 'array' ? col.udt_name.replace(/^_(.*)$/, '$1[]') : col.udt_name;
276
+ if (col.data_type === 'USER-DEFINED' &&
277
+ col.udt_schema &&
278
+ col.udt_schema !== this.platform.getDefaultSchemaName()) {
282
279
  type = `${col.udt_schema}.${type}`;
283
280
  }
284
281
  if (type === 'bpchar') {
@@ -305,7 +302,13 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
305
302
  default: str(this.normalizeDefaultValue(col.column_default, col.length)),
306
303
  unsigned: increments,
307
304
  autoincrement: increments,
308
- generated: col.is_identity === 'YES' ? (col.identity_generation === 'BY DEFAULT' ? 'by default as identity' : 'identity') : (col.generation_expression ? col.generation_expression + ' stored' : undefined),
305
+ generated: col.is_identity === 'YES'
306
+ ? col.identity_generation === 'BY DEFAULT'
307
+ ? 'by default as identity'
308
+ : 'identity'
309
+ : col.generation_expression
310
+ ? col.generation_expression + ' stored'
311
+ : undefined,
309
312
  comment: col.column_comment,
310
313
  };
311
314
  if (nativeEnums?.[column.type]) {
@@ -321,10 +324,16 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
321
324
  const sql = this.getChecksSQL(tablesBySchemas);
322
325
  const allChecks = await connection.execute(sql);
323
326
  const ret = {};
327
+ const seen = new Set();
324
328
  for (const check of allChecks) {
325
329
  const key = this.getTableKey(check);
330
+ const dedupeKey = `${key}:${check.name}`;
331
+ if (seen.has(dedupeKey)) {
332
+ continue;
333
+ }
334
+ seen.add(dedupeKey);
326
335
  ret[key] ??= [];
327
- const m = check.expression.match(/^check \(\((.*)\)\)$/i);
336
+ const m = /^check \(\((.*)\)\)$/is.exec(check.expression);
328
337
  const def = m?.[1].replace(/\((.*?)\)::\w+/g, '$1');
329
338
  ret[key].push({
330
339
  name: check.name,
@@ -353,18 +362,23 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
353
362
  const allFks = await connection.execute(sql);
354
363
  const ret = {};
355
364
  function mapReferentialIntegrity(value, def) {
356
- const match = ['n', 'd'].includes(value) && def.match(/ON DELETE (SET (NULL|DEFAULT) \(.*?\))/);
365
+ const match = ['n', 'd'].includes(value) && /ON DELETE (SET (NULL|DEFAULT) \(.*?\))/.exec(def);
357
366
  if (match) {
358
367
  return match[1];
359
368
  }
360
369
  /* v8 ignore next */
361
370
  switch (value) {
362
- case 'r': return 'RESTRICT';
363
- case 'c': return 'CASCADE';
364
- case 'n': return 'SET NULL';
365
- case 'd': return 'SET DEFAULT';
371
+ case 'r':
372
+ return 'RESTRICT';
373
+ case 'c':
374
+ return 'CASCADE';
375
+ case 'n':
376
+ return 'SET NULL';
377
+ case 'd':
378
+ return 'SET DEFAULT';
366
379
  case 'a':
367
- default: return 'NO ACTION';
380
+ default:
381
+ return 'NO ACTION';
368
382
  }
369
383
  }
370
384
  for (const fk of allFks) {
@@ -451,10 +465,10 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
451
465
  let items;
452
466
  /* v8 ignore next */
453
467
  if (m3) {
454
- items = m3.map((item) => item.trim().match(/^\(?'(.*)'/)?.[1]);
468
+ items = m3.map((item) => /^\(?'(.*)'/.exec(item.trim())?.[1]);
455
469
  }
456
470
  else {
457
- items = m2[1].split(',').map((item) => item.trim().match(/^\(?'(.*)'/)?.[1]);
471
+ items = m2[1].split(',').map((item) => /^\(?'(.*)'/.exec(item.trim())?.[1]);
458
472
  }
459
473
  items = items.filter(item => item !== undefined);
460
474
  if (items.length > 0) {
@@ -591,7 +605,7 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
591
605
  if (!defaultValue || typeof defaultValue !== 'string') {
592
606
  return super.normalizeDefaultValue(defaultValue, length, PostgreSqlSchemaHelper.DEFAULT_VALUES);
593
607
  }
594
- const match = defaultValue.match(/^'(.*)'::(.*)$/);
608
+ const match = /^'(.*)'::(.*)$/.exec(defaultValue);
595
609
  if (match) {
596
610
  if (match[2] === 'integer') {
597
611
  return +match[1];
@@ -603,8 +617,8 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
603
617
  appendComments(table) {
604
618
  const sql = [];
605
619
  if (table.comment) {
606
- const comment = this.platform.quoteValue(table.comment).replace(/^'|'$/g, '');
607
- sql.push(`comment on table ${table.getQuotedName()} is ${this.platform.quoteValue(this.processComment(comment))}`);
620
+ const comment = this.platform.quoteValue(this.processComment(table.comment));
621
+ sql.push(`comment on table ${table.getQuotedName()} is ${comment}`);
608
622
  }
609
623
  for (const column of table.getColumns()) {
610
624
  if (column.comment) {
@@ -645,7 +659,8 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
645
659
  */
646
660
  getIndexColumns(index) {
647
661
  if (index.columns?.length) {
648
- return index.columns.map(col => {
662
+ return index.columns
663
+ .map(col => {
649
664
  let colDef = this.quote(col.name);
650
665
  // PostgreSQL supports collation with double quotes
651
666
  if (col.collation) {
@@ -660,7 +675,8 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
660
675
  colDef += ` nulls ${col.nulls}`;
661
676
  }
662
677
  return colDef;
663
- }).join(', ');
678
+ })
679
+ .join(', ');
664
680
  }
665
681
  return index.columnNames.map(c => this.quote(c)).join(', ');
666
682
  }
@@ -702,12 +718,12 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
702
718
  from pg_constraint pgc
703
719
  join pg_namespace nsp on nsp.oid = pgc.connamespace
704
720
  join pg_class cls on pgc.conrelid = cls.oid
705
- join information_schema.constraint_column_usage ccu on pgc.conname = ccu.constraint_name and nsp.nspname = ccu.constraint_schema
721
+ join information_schema.constraint_column_usage ccu on pgc.conname = ccu.constraint_name and nsp.nspname = ccu.constraint_schema and cls.relname = ccu.table_name
706
722
  where contype = 'c' and (${[...tablesBySchemas.entries()].map(([schema, tables]) => `ccu.table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(',')}) and ccu.table_schema = ${this.platform.quoteValue(schema)}`).join(' or ')})
707
723
  order by pgc.conname`;
708
724
  }
709
725
  inferLengthFromColumnType(type) {
710
- const match = type.match(/^(\w+(?:\s+\w+)*)\s*(?:\(\s*(\d+)\s*\)|$)/);
726
+ const match = /^(\w+(?:\s+\w+)*)\s*(?:\(\s*(\d+)\s*\)|$)/.exec(type);
711
727
  if (!match) {
712
728
  return;
713
729
  }
@@ -2,8 +2,8 @@ import { CompiledQuery } from 'kysely';
2
2
  import { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
3
3
  export class BaseSqliteConnection extends AbstractSqlConnection {
4
4
  createKyselyDialect(options) {
5
- throw new Error('No SQLite dialect configured. Pass a Kysely dialect via the `driverOptions` config option, '
6
- + 'e.g. `new NodeSqliteDialect(...)` for node:sqlite or a custom dialect for other libraries.');
5
+ throw new Error('No SQLite dialect configured. Pass a Kysely dialect via the `driverOptions` config option, ' +
6
+ 'e.g. `new NodeSqliteDialect(...)` for node:sqlite or a custom dialect for other libraries.');
7
7
  }
8
8
  async connect(options) {
9
9
  await super.connect(options);
@@ -33,7 +33,9 @@ export class NodeSqliteDialect extends SqliteDialect {
33
33
  get: (params) => stmt.get(...params),
34
34
  };
35
35
  },
36
- close() { db.close(); },
36
+ close() {
37
+ db.close();
38
+ },
37
39
  };
38
40
  },
39
41
  });
@@ -75,5 +75,6 @@ export declare class SqlitePlatform extends AbstractSqlPlatform {
75
75
  convertVersionValue(value: Date | number, prop: EntityProperty): number | {
76
76
  $in: (string | number)[];
77
77
  };
78
+ getJsonArrayElementPropertySQL(alias: string, property: string, _type: string): string;
78
79
  quoteValue(value: any): string;
79
80
  }
@@ -125,11 +125,17 @@ export class SqlitePlatform extends AbstractSqlPlatform {
125
125
  convertVersionValue(value, prop) {
126
126
  if (prop.runtimeType === 'Date') {
127
127
  const ts = +value;
128
- const str = new Date(ts).toISOString().replace('T', ' ').replace(/\.\d{3}Z$/, '');
128
+ const str = new Date(ts)
129
+ .toISOString()
130
+ .replace('T', ' ')
131
+ .replace(/\.\d{3}Z$/, '');
129
132
  return { $in: [ts, str] };
130
133
  }
131
134
  return value;
132
135
  }
136
+ getJsonArrayElementPropertySQL(alias, property, _type) {
137
+ return `json_extract(${this.quoteIdentifier(alias)}.value, '$.${this.quoteJsonKey(property)}')`;
138
+ }
133
139
  quoteValue(value) {
134
140
  if (value instanceof Date) {
135
141
  return '' + +value;
@@ -31,8 +31,8 @@ export class SqliteSchemaHelper extends SchemaHelper {
31
31
  return '';
32
32
  }
33
33
  getListTablesSQL() {
34
- return `select name as table_name from sqlite_master where type = 'table' and name != 'sqlite_sequence' and name != 'geometry_columns' and name != 'spatial_ref_sys' `
35
- + `union all select name as table_name from sqlite_temp_master where type = 'table' order by name`;
34
+ return (`select name as table_name from sqlite_master where type = 'table' and name != 'sqlite_sequence' and name != 'geometry_columns' and name != 'spatial_ref_sys' ` +
35
+ `union all select name as table_name from sqlite_temp_master where type = 'table' order by name`);
36
36
  }
37
37
  async getAllTables(connection, schemas) {
38
38
  const databases = await this.getDatabaseList(connection);
@@ -183,9 +183,11 @@ export class SqliteSchemaHelper extends SchemaHelper {
183
183
  getDropColumnsSQL(tableName, columns, schemaName) {
184
184
  /* v8 ignore next */
185
185
  const name = this.quote((schemaName && schemaName !== this.platform.getDefaultSchemaName() ? schemaName + '.' : '') + tableName);
186
- return columns.map(column => {
186
+ return columns
187
+ .map(column => {
187
188
  return `alter table ${name} drop column ${this.quote(column.name)}`;
188
- }).join(';\n');
189
+ })
190
+ .join(';\n');
189
191
  }
190
192
  getCreateIndexSQL(tableName, index) {
191
193
  /* v8 ignore next */
@@ -218,7 +220,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
218
220
  const columns = {};
219
221
  const constraints = [];
220
222
  // extract all columns definitions
221
- let columnsDef = sql.replaceAll('\n', '').match(new RegExp(`create table [\`"']?.*?[\`"']? \\((.*)\\)`, 'i'))?.[1];
223
+ let columnsDef = new RegExp(`create table [\`"']?.*?[\`"']? \\((.*)\\)`, 'i').exec(sql.replaceAll('\n', ''))?.[1];
222
224
  /* v8 ignore next */
223
225
  if (columnsDef) {
224
226
  if (columnsDef.includes(', constraint ')) {
@@ -228,7 +230,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
228
230
  for (let i = cols.length - 1; i >= 0; i--) {
229
231
  const col = cols[i];
230
232
  const re = ` *, *[\`"']?${col.name}[\`"']? (.*)`;
231
- const columnDef = columnsDef.match(new RegExp(re, 'i'));
233
+ const columnDef = new RegExp(re, 'i').exec(columnsDef);
232
234
  if (columnDef) {
233
235
  columns[col.name] = { name: col.name, definition: columnDef[1] };
234
236
  columnsDef = columnsDef.substring(0, columnDef.index);
@@ -258,7 +260,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
258
260
  * Extracts the SELECT part from a CREATE VIEW statement.
259
261
  */
260
262
  extractViewDefinition(viewDefinition) {
261
- const match = viewDefinition?.match(/create\s+view\s+[`"']?\w+[`"']?\s+as\s+(.*)/i);
263
+ const match = /create\s+view\s+[`"']?\w+[`"']?\s+as\s+(.*)/i.exec(viewDefinition);
262
264
  /* v8 ignore next - fallback for non-standard view definitions */
263
265
  return match ? match[1] : viewDefinition;
264
266
  }
@@ -305,7 +307,11 @@ export class SqliteSchemaHelper extends SchemaHelper {
305
307
  return null;
306
308
  }
307
309
  // simple values that are returned as-is from pragma (no wrapping needed)
308
- if (/^-?\d/.test(value) || /^[xX]'/.test(value) || value[0] === "'" || value[0] === '"' || value[0] === '(') {
310
+ if (/^-?\d/.test(value) ||
311
+ /^[xX]'/.test(value) ||
312
+ value.startsWith("'") ||
313
+ value.startsWith('"') ||
314
+ value.startsWith('(')) {
309
315
  return value;
310
316
  }
311
317
  const lower = value.toLowerCase();
@@ -323,10 +329,10 @@ export class SqliteSchemaHelper extends SchemaHelper {
323
329
  return checkConstraints.reduce((o, item) => {
324
330
  // check constraints are defined as (note that last closing paren is missing):
325
331
  // `type` text check (`type` in ('local', 'global')
326
- const match = item.match(/[`["']([^`\]"']+)[`\]"'] text check \(.* \((.*)\)/i);
332
+ const match = /[`["']([^`\]"']+)[`\]"'] text check \(.* \((.*)\)/i.exec(item);
327
333
  /* v8 ignore next */
328
334
  if (match) {
329
- o[match[1]] = match[2].split(',').map((item) => item.trim().match(/^\(?'(.*)'/)[1]);
335
+ o[match[1]] = match[2].split(',').map((item) => /^\(?'(.*)'/.exec(item.trim())[1]);
330
336
  }
331
337
  return o;
332
338
  }, {});
@@ -369,7 +375,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
369
375
  const checks = [];
370
376
  for (const key of Object.keys(columns)) {
371
377
  const column = columns[key];
372
- const expression = column.definition.match(/ (check \((.*)\))/i);
378
+ const expression = / (check \((.*)\))/i.exec(column.definition);
373
379
  if (expression) {
374
380
  checks.push({
375
381
  name: this.platform.getConfig().getNamingStrategy().indexName(tableName, [column.name], 'check'),
@@ -380,7 +386,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
380
386
  }
381
387
  }
382
388
  for (const constraint of constraints) {
383
- const expression = constraint.match(/constraint *[`"']?(.*?)[`"']? * (check \((.*)\))/i);
389
+ const expression = /constraint *[`"']?(.*?)[`"']? * (check \((.*)\))/i.exec(constraint);
384
390
  if (expression) {
385
391
  checks.push({
386
392
  name: expression[1],
@@ -453,10 +459,10 @@ export class SqliteSchemaHelper extends SchemaHelper {
453
459
  alterTable(diff, safe) {
454
460
  const ret = [];
455
461
  const [schemaName, tableName] = this.splitTableName(diff.name);
456
- if (Utils.hasObjectKeys(diff.removedChecks)
457
- || Utils.hasObjectKeys(diff.changedChecks)
458
- || Utils.hasObjectKeys(diff.changedForeignKeys)
459
- || Utils.hasObjectKeys(diff.changedColumns)) {
462
+ if (Utils.hasObjectKeys(diff.removedChecks) ||
463
+ Utils.hasObjectKeys(diff.changedChecks) ||
464
+ Utils.hasObjectKeys(diff.changedForeignKeys) ||
465
+ Utils.hasObjectKeys(diff.changedColumns)) {
460
466
  return this.getAlterTempTableSQL(diff);
461
467
  }
462
468
  for (const index of Object.values(diff.removedIndexes)) {
@@ -496,7 +502,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
496
502
  return ret;
497
503
  }
498
504
  getAlterTempTableSQL(changedTable) {
499
- const tempName = `${(changedTable.toTable.name)}__temp_alter`;
505
+ const tempName = `${changedTable.toTable.name}__temp_alter`;
500
506
  const quotedName = this.quote(changedTable.toTable.name);
501
507
  const quotedTempName = this.quote(tempName);
502
508
  const [first, ...rest] = this.createTable(changedTable.toTable);
package/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export * from './query/index.js';
13
13
  export { raw } from './query/index.js';
14
14
  export * from './schema/index.js';
15
15
  export * from './dialects/index.js';
16
- export * from './typings.js';
16
+ export type * from './typings.js';
17
17
  export * from './plugin/index.js';
18
18
  export { SqlEntityManager as EntityManager } from './SqlEntityManager.js';
19
19
  export { SqlEntityRepository as EntityRepository } from './SqlEntityRepository.js';
package/index.js CHANGED
@@ -13,7 +13,6 @@ export * from './query/index.js';
13
13
  export { raw } from './query/index.js';
14
14
  export * from './schema/index.js';
15
15
  export * from './dialects/index.js';
16
- export * from './typings.js';
17
16
  export * from './plugin/index.js';
18
17
  export { SqlEntityManager as EntityManager } from './SqlEntityManager.js';
19
18
  export { SqlEntityRepository as EntityRepository } from './SqlEntityRepository.js';