@mikro-orm/sql 7.1.12-dev.1 → 7.1.12-dev.10
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.
|
@@ -69,6 +69,8 @@ export declare class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
69
69
|
createTrigger(table: DatabaseTable, trigger: SqlTriggerDef): string;
|
|
70
70
|
/** Generates SQL to drop a PostgreSQL trigger and its associated function. */
|
|
71
71
|
dropTrigger(table: DatabaseTable, trigger: SqlTriggerDef): string;
|
|
72
|
+
/** Flattens `;\n` inside the dollar-quoted blocks of a raw DDL expression, which are not statement boundaries. */
|
|
73
|
+
private flattenDollarQuotedBodies;
|
|
72
74
|
createRoutine(routine: SqlRoutineDef): string;
|
|
73
75
|
dropRoutine(routine: SqlRoutineDef): string;
|
|
74
76
|
getAllRoutines(connection: AbstractSqlConnection, schemas?: string[]): Promise<SqlRoutineDef[]>;
|
|
@@ -3,6 +3,8 @@ import { SchemaHelper, stripStatementNewlines } from '../../schema/SchemaHelper.
|
|
|
3
3
|
import { normalizePartitionBound, normalizePartitionDefinition } from '../../schema/partitioning.js';
|
|
4
4
|
/** PostGIS system views that should be automatically ignored */
|
|
5
5
|
const POSTGIS_VIEWS = ['geography_columns', 'geometry_columns'];
|
|
6
|
+
/** Dollar-quote delimiter, e.g. `$$` or `$body$`, captured so `split` keeps it. */
|
|
7
|
+
const DOLLAR_QUOTE_TAG = /(\$(?:[A-Za-z_]\w*)?\$)/;
|
|
6
8
|
export class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
7
9
|
static DEFAULT_VALUES = {
|
|
8
10
|
'now()': ['now()', 'current_timestamp'],
|
|
@@ -505,7 +507,7 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
505
507
|
/** Generates SQL to create a PostgreSQL trigger and its associated function. */
|
|
506
508
|
createTrigger(table, trigger) {
|
|
507
509
|
if (trigger.expression) {
|
|
508
|
-
return trigger.expression;
|
|
510
|
+
return this.flattenDollarQuotedBodies(trigger.expression);
|
|
509
511
|
}
|
|
510
512
|
const timing = trigger.timing.toUpperCase();
|
|
511
513
|
const events = trigger.events.map(e => e.toUpperCase()).join(' OR ');
|
|
@@ -523,9 +525,24 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
523
525
|
const fnName = this.getSchemaQualifiedTriggerFnName(table, trigger);
|
|
524
526
|
return `drop trigger if exists ${triggerName} on ${table.getQuotedName()};\ndrop function if exists ${fnName}()`;
|
|
525
527
|
}
|
|
528
|
+
/** Flattens `;\n` inside the dollar-quoted blocks of a raw DDL expression, which are not statement boundaries. */
|
|
529
|
+
flattenDollarQuotedBodies(ddl) {
|
|
530
|
+
let openTag = '';
|
|
531
|
+
return ddl
|
|
532
|
+
.split(DOLLAR_QUOTE_TAG)
|
|
533
|
+
.map((part, i) => {
|
|
534
|
+
// the capture group puts the delimiters on the odd indexes
|
|
535
|
+
if (i % 2 === 1) {
|
|
536
|
+
openTag = openTag === part ? '' : openTag || part;
|
|
537
|
+
return part;
|
|
538
|
+
}
|
|
539
|
+
return openTag ? stripStatementNewlines(part) : part;
|
|
540
|
+
})
|
|
541
|
+
.join('');
|
|
542
|
+
}
|
|
526
543
|
createRoutine(routine) {
|
|
527
544
|
if (routine.expression) {
|
|
528
|
-
return routine.expression;
|
|
545
|
+
return this.flattenDollarQuotedBodies(routine.expression);
|
|
529
546
|
}
|
|
530
547
|
const qualifiedName = this.qualifiedRoutineName(routine);
|
|
531
548
|
const params = this.formatRoutineParams(routine);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/sql",
|
|
3
|
-
"version": "7.1.12-dev.
|
|
3
|
+
"version": "7.1.12-dev.10",
|
|
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.5"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@mikro-orm/core": "^7.1.11"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@mikro-orm/core": "7.1.12-dev.
|
|
56
|
+
"@mikro-orm/core": "7.1.12-dev.10"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">= 22.17.0"
|
package/schema/DatabaseTable.js
CHANGED
|
@@ -1030,8 +1030,12 @@ export class DatabaseTable {
|
|
|
1030
1030
|
// mysql stores decimal defaults padded to scale (`0` → `0.00`); collapse to canonical numeric form
|
|
1031
1031
|
// so the metadata-side (`0`) and introspection-side (`0.00`) snapshots agree
|
|
1032
1032
|
let defaultValue = c.default ?? null;
|
|
1033
|
-
if (defaultValue != null && c.mappedType instanceof DecimalType
|
|
1034
|
-
|
|
1033
|
+
if (defaultValue != null && c.mappedType instanceof DecimalType) {
|
|
1034
|
+
// string defaults like `default: '0.00'` are quoted in metadata, so strip the quotes first
|
|
1035
|
+
const unquoted = defaultValue.replace(/^'(.*)'$/, '$1');
|
|
1036
|
+
if (Number.isFinite(+unquoted)) {
|
|
1037
|
+
defaultValue = this.#platform.formatDecimal(unquoted, c.scale).toString();
|
|
1038
|
+
}
|
|
1035
1039
|
}
|
|
1036
1040
|
const normalized = {
|
|
1037
1041
|
name: c.name,
|
|
@@ -89,6 +89,7 @@ export declare class SchemaComparator {
|
|
|
89
89
|
private diffViewExpression;
|
|
90
90
|
private diffTrigger;
|
|
91
91
|
parseJsonDefault(defaultValue?: string | null): Dictionary | string | null;
|
|
92
|
+
private parseDecimalDefault;
|
|
92
93
|
hasSameDefaultValue(from: Column, to: Column): boolean;
|
|
93
94
|
private mapColumnToProperty;
|
|
94
95
|
private log;
|
|
@@ -993,6 +993,10 @@ export class SchemaComparator {
|
|
|
993
993
|
const val = defaultValue.replace(/^(_\w+\\)?'(.*?)\\?'$/, '$2').replace(/^\(?'(.*?)'\)?$/, '$1');
|
|
994
994
|
return parseJsonSafe(val);
|
|
995
995
|
}
|
|
996
|
+
parseDecimalDefault(defaultValue) {
|
|
997
|
+
const value = +('' + defaultValue).replace(/^'(.+)'$/, '$1');
|
|
998
|
+
return Number.isFinite(value) ? value : null;
|
|
999
|
+
}
|
|
996
1000
|
hasSameDefaultValue(from, to) {
|
|
997
1001
|
if (from.default == null ||
|
|
998
1002
|
from.default.toString().toLowerCase() === 'null' ||
|
|
@@ -1018,10 +1022,15 @@ export class SchemaComparator {
|
|
|
1018
1022
|
const defaultValueTo = to.default.toLowerCase().replace('current_timestamp', 'now').replace(/\(\)$/, '');
|
|
1019
1023
|
return defaultValueFrom === defaultValueTo;
|
|
1020
1024
|
}
|
|
1021
|
-
// mysql
|
|
1022
|
-
//
|
|
1023
|
-
if (to.mappedType instanceof DecimalType
|
|
1024
|
-
|
|
1025
|
+
// mysql pads decimal defaults to scale (`0` → `0.00`) and postgres reports them unquoted
|
|
1026
|
+
// while metadata keeps them quoted; compare numerically so neither churns a no-op migration
|
|
1027
|
+
if (to.mappedType instanceof DecimalType) {
|
|
1028
|
+
const defaultValueFrom = this.parseDecimalDefault(from.default);
|
|
1029
|
+
const defaultValueTo = this.parseDecimalDefault(to.default);
|
|
1030
|
+
if (defaultValueFrom != null && defaultValueTo != null) {
|
|
1031
|
+
return (this.#platform.formatDecimal(defaultValueFrom, to.scale) ===
|
|
1032
|
+
this.#platform.formatDecimal(defaultValueTo, to.scale));
|
|
1033
|
+
}
|
|
1025
1034
|
}
|
|
1026
1035
|
if (from.default && to.default) {
|
|
1027
1036
|
return from.default.toString().toLowerCase() === to.default.toString().toLowerCase();
|