@mikro-orm/sql 7.2.6-dev.2 → 7.2.6-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.
package/AbstractSqlConnection.js
CHANGED
|
@@ -130,6 +130,10 @@ export class AbstractSqlConnection extends Connection {
|
|
|
130
130
|
}
|
|
131
131
|
catch (rollbackError) {
|
|
132
132
|
this.logger.warn('query', `Failed to roll back transaction: ${rollbackError.message}`);
|
|
133
|
+
// the inner writes are still part of the outer transaction, so it must not commit them
|
|
134
|
+
if (options.ctx) {
|
|
135
|
+
options.ctx.failedSavepointRollback ??= new Error(`Cannot commit the transaction, rolling back to savepoint "${trx.savepointName}" failed: ${rollbackError.message}`, { cause: rollbackError });
|
|
136
|
+
}
|
|
133
137
|
}
|
|
134
138
|
throw error;
|
|
135
139
|
}
|
|
@@ -203,6 +207,9 @@ export class AbstractSqlConnection extends Connection {
|
|
|
203
207
|
if (ctx.isRolledBack) {
|
|
204
208
|
return;
|
|
205
209
|
}
|
|
210
|
+
if ('failedSavepointRollback' in ctx) {
|
|
211
|
+
throw ctx.failedSavepointRollback;
|
|
212
|
+
}
|
|
206
213
|
await eventBroadcaster?.dispatchEvent(EventType.beforeTransactionCommit, ctx);
|
|
207
214
|
if ('savepointName' in ctx) {
|
|
208
215
|
await ctx.releaseSavepoint(ctx.savepointName).execute();
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -825,11 +825,11 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
825
825
|
value = this.platform.cloneEmbeddable(value);
|
|
826
826
|
for (let i = 0; i < value.length; i++) {
|
|
827
827
|
const item = value[i];
|
|
828
|
-
value[i] = this.mapDataToFieldNames(item, false, prop
|
|
828
|
+
value[i] = this.mapDataToFieldNames(item, false, this.variantProps(prop, item), options.convertCustomTypes);
|
|
829
829
|
}
|
|
830
830
|
}
|
|
831
831
|
else {
|
|
832
|
-
value = this.mapDataToFieldNames(value, false, prop
|
|
832
|
+
value = this.mapDataToFieldNames(value, false, this.variantProps(prop, value), options.convertCustomTypes);
|
|
833
833
|
}
|
|
834
834
|
}
|
|
835
835
|
if (typeof value === 'undefined' && this.platform.usesDefaultKeyword()) {
|
|
@@ -1095,11 +1095,11 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1095
1095
|
if (prop.array && value) {
|
|
1096
1096
|
for (let i = 0; i < value.length; i++) {
|
|
1097
1097
|
const item = value[i];
|
|
1098
|
-
value[i] = this.mapDataToFieldNames(item, false, prop
|
|
1098
|
+
value[i] = this.mapDataToFieldNames(item, false, this.variantProps(prop, item), options.convertCustomTypes);
|
|
1099
1099
|
}
|
|
1100
1100
|
}
|
|
1101
1101
|
else {
|
|
1102
|
-
value = this.mapDataToFieldNames(value, false, prop
|
|
1102
|
+
value = this.mapDataToFieldNames(value, false, this.variantProps(prop, value), options.convertCustomTypes);
|
|
1103
1103
|
}
|
|
1104
1104
|
}
|
|
1105
1105
|
params.push(value ?? null);
|
|
@@ -2115,7 +2115,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
2115
2115
|
if (prop.formula) {
|
|
2116
2116
|
const quotedAlias = this.platform.quoteIdentifier(tableAlias).toString();
|
|
2117
2117
|
const table = this.createFormulaTable(quotedAlias, meta, schema);
|
|
2118
|
-
const columns = meta.createColumnMappingObject(p => qb.helper.getTPTAliasForProperty(p.name, tableAlias),
|
|
2118
|
+
const columns = meta.createColumnMappingObject(p => qb.helper.getTPTAliasForProperty(p.name, tableAlias), quotedAlias);
|
|
2119
2119
|
return [raw(`${this.evaluateFormula(prop.formula, columns, table)} as ${aliased}`)];
|
|
2120
2120
|
}
|
|
2121
2121
|
if (prop.customTypes?.some(type => !!type?.convertToJSValueSQL)) {
|
|
@@ -2539,9 +2539,9 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
2539
2539
|
ret.push('*');
|
|
2540
2540
|
}
|
|
2541
2541
|
if (ret.length > 0 && !hasExplicitFields && addFormulas) {
|
|
2542
|
-
//
|
|
2542
|
+
// `toString()` must yield the quoted alias like `QueryBuilder.finalize()`, which dedupes formulas by rendered SQL
|
|
2543
2543
|
const quotedAlias = this.platform.quoteIdentifier(alias);
|
|
2544
|
-
const columns = meta.createColumnMappingObject(alias);
|
|
2544
|
+
const columns = meta.createColumnMappingObject(alias, quotedAlias.toString());
|
|
2545
2545
|
const effectiveSchema = schema ?? (meta.schema !== '*' ? meta.schema : undefined);
|
|
2546
2546
|
for (const prop of meta.props) {
|
|
2547
2547
|
if (lazyProps.includes(prop)) {
|
|
@@ -330,10 +330,9 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
330
330
|
return columnDefs.map(colDef => {
|
|
331
331
|
const name = unquote(colDef);
|
|
332
332
|
const result = { name };
|
|
333
|
-
//
|
|
334
|
-
// Create a pattern that matches the column name (quoted or unquoted) followed by modifiers
|
|
333
|
+
// Match the column (quoted or unquoted) as a whole list item, so `id` never matches inside `author_id`
|
|
335
334
|
const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
336
|
-
const colPattern = new RegExp(`"?${escapedName}"
|
|
335
|
+
const colPattern = new RegExp(`(?:^|,)\\s*"?${escapedName}"?(?=\\s|,|$)\\s*([^,)]*?)(?:,|$)`, 'i');
|
|
337
336
|
const colMatch = columnsStr.match(colPattern);
|
|
338
337
|
if (colMatch) {
|
|
339
338
|
const modifiers = colMatch[1];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/sql",
|
|
3
|
-
"version": "7.2.6-dev.
|
|
3
|
+
"version": "7.2.6-dev.21",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"data-mapper",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"copy": "node ../../scripts/copy.mjs"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"kysely": "0.29.
|
|
50
|
+
"kysely": "0.29.7"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@mikro-orm/core": "^7.2.5"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@mikro-orm/core": "7.2.6-dev.
|
|
56
|
+
"@mikro-orm/core": "7.2.6-dev.21"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">= 22.17.0"
|
package/schema/DatabaseTable.js
CHANGED
|
@@ -924,6 +924,17 @@ export class DatabaseTable {
|
|
|
924
924
|
};
|
|
925
925
|
return [expand(rootProp, 1)];
|
|
926
926
|
}
|
|
927
|
+
// object embedded property index, the JSON keys are the field names of the embedded properties
|
|
928
|
+
if (rootProp?.embeddable && rootProp.object && rootProp.embeddedProps[parts[1]]) {
|
|
929
|
+
let p = rootProp.embeddedProps[parts[1]];
|
|
930
|
+
let i = 2;
|
|
931
|
+
while (i < parts.length && p.embeddedProps?.[parts[i]]) {
|
|
932
|
+
p = p.embeddedProps[parts[i]];
|
|
933
|
+
i++;
|
|
934
|
+
}
|
|
935
|
+
// a path below the last embedded property targets plain JSON keys, kept as they are
|
|
936
|
+
return [[...p.embeddedPath, ...parts.slice(i)].join('.')];
|
|
937
|
+
}
|
|
927
938
|
// json index, we need to rename the column only
|
|
928
939
|
if (rootProp) {
|
|
929
940
|
return [prop.replace(root, rootProp.fieldNames[0])];
|
|
@@ -866,16 +866,10 @@ export class SchemaComparator {
|
|
|
866
866
|
if (cols1.length === 0 && cols2.length === 0) {
|
|
867
867
|
return true;
|
|
868
868
|
}
|
|
869
|
-
//
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
// Compare each column's options
|
|
874
|
-
// Note: We don't check c1.name !== c2.name because the indexes already have matching columnNames
|
|
875
|
-
// and the columns array is derived from those same column names
|
|
876
|
-
for (let i = 0; i < cols1.length; i++) {
|
|
877
|
-
const c1 = cols1[i];
|
|
878
|
-
const c2 = cols2[i];
|
|
869
|
+
// introspection may omit entries for columns with default options, so match them by name
|
|
870
|
+
for (const name of index1.columnNames) {
|
|
871
|
+
const c1 = cols1.find(c => c.name === name) ?? { name };
|
|
872
|
+
const c2 = cols2.find(c => c.name === name) ?? { name };
|
|
879
873
|
const sort1 = c1.sort?.toUpperCase() ?? 'ASC';
|
|
880
874
|
const sort2 = c2.sort?.toUpperCase() ?? 'ASC';
|
|
881
875
|
if (sort1 !== sort2) {
|