@mikro-orm/core 7.0.9-dev.9 → 7.0.9

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 (206) hide show
  1. package/EntityManager.d.ts +884 -583
  2. package/EntityManager.js +1926 -1899
  3. package/MikroORM.d.ts +103 -74
  4. package/MikroORM.js +177 -179
  5. package/README.md +1 -1
  6. package/cache/CacheAdapter.d.ts +36 -36
  7. package/cache/FileCacheAdapter.d.ts +30 -24
  8. package/cache/FileCacheAdapter.js +80 -78
  9. package/cache/GeneratedCacheAdapter.d.ts +18 -20
  10. package/cache/GeneratedCacheAdapter.js +30 -30
  11. package/cache/MemoryCacheAdapter.d.ts +18 -20
  12. package/cache/MemoryCacheAdapter.js +35 -36
  13. package/cache/NullCacheAdapter.d.ts +16 -16
  14. package/cache/NullCacheAdapter.js +24 -24
  15. package/connections/Connection.d.ts +95 -84
  16. package/connections/Connection.js +165 -168
  17. package/drivers/DatabaseDriver.d.ts +187 -81
  18. package/drivers/DatabaseDriver.js +450 -444
  19. package/drivers/IDatabaseDriver.d.ts +440 -301
  20. package/entity/BaseEntity.d.ts +120 -83
  21. package/entity/BaseEntity.js +43 -43
  22. package/entity/Collection.d.ts +215 -181
  23. package/entity/Collection.js +730 -724
  24. package/entity/EntityAssigner.d.ts +88 -77
  25. package/entity/EntityAssigner.js +231 -230
  26. package/entity/EntityFactory.d.ts +67 -55
  27. package/entity/EntityFactory.js +457 -414
  28. package/entity/EntityHelper.d.ts +35 -23
  29. package/entity/EntityHelper.js +291 -279
  30. package/entity/EntityIdentifier.d.ts +4 -4
  31. package/entity/EntityIdentifier.js +10 -10
  32. package/entity/EntityLoader.d.ts +98 -72
  33. package/entity/EntityLoader.js +792 -761
  34. package/entity/EntityRepository.d.ts +316 -201
  35. package/entity/EntityRepository.js +213 -213
  36. package/entity/PolymorphicRef.d.ts +5 -5
  37. package/entity/PolymorphicRef.js +10 -10
  38. package/entity/Reference.d.ts +127 -83
  39. package/entity/Reference.js +281 -277
  40. package/entity/WrappedEntity.d.ts +115 -72
  41. package/entity/WrappedEntity.js +168 -166
  42. package/entity/defineEntity.d.ts +1359 -654
  43. package/entity/defineEntity.js +527 -518
  44. package/entity/utils.d.ts +13 -3
  45. package/entity/utils.js +71 -73
  46. package/entity/validators.js +43 -43
  47. package/entity/wrap.js +8 -8
  48. package/enums.d.ts +258 -253
  49. package/enums.js +251 -252
  50. package/errors.d.ts +114 -72
  51. package/errors.js +350 -253
  52. package/events/EventManager.d.ts +26 -14
  53. package/events/EventManager.js +79 -77
  54. package/events/EventSubscriber.d.ts +29 -29
  55. package/events/TransactionEventBroadcaster.d.ts +15 -8
  56. package/events/TransactionEventBroadcaster.js +14 -14
  57. package/exceptions.d.ts +23 -40
  58. package/exceptions.js +35 -52
  59. package/hydration/Hydrator.d.ts +42 -17
  60. package/hydration/Hydrator.js +43 -43
  61. package/hydration/ObjectHydrator.d.ts +50 -17
  62. package/hydration/ObjectHydrator.js +483 -418
  63. package/index.d.ts +116 -2
  64. package/index.js +10 -1
  65. package/logging/DefaultLogger.d.ts +34 -32
  66. package/logging/DefaultLogger.js +86 -86
  67. package/logging/Logger.d.ts +41 -41
  68. package/logging/SimpleLogger.d.ts +13 -11
  69. package/logging/SimpleLogger.js +22 -22
  70. package/logging/colors.d.ts +6 -6
  71. package/logging/colors.js +11 -10
  72. package/logging/inspect.js +7 -7
  73. package/metadata/EntitySchema.d.ts +214 -130
  74. package/metadata/EntitySchema.js +411 -412
  75. package/metadata/MetadataDiscovery.d.ts +114 -114
  76. package/metadata/MetadataDiscovery.js +1957 -1879
  77. package/metadata/MetadataProvider.d.ts +29 -26
  78. package/metadata/MetadataProvider.js +95 -97
  79. package/metadata/MetadataStorage.d.ts +38 -32
  80. package/metadata/MetadataStorage.js +118 -118
  81. package/metadata/MetadataValidator.d.ts +39 -39
  82. package/metadata/MetadataValidator.js +381 -338
  83. package/metadata/discover-entities.d.ts +5 -2
  84. package/metadata/discover-entities.js +35 -37
  85. package/metadata/types.d.ts +615 -531
  86. package/naming-strategy/AbstractNamingStrategy.d.ts +54 -39
  87. package/naming-strategy/AbstractNamingStrategy.js +90 -85
  88. package/naming-strategy/EntityCaseNamingStrategy.d.ts +6 -6
  89. package/naming-strategy/EntityCaseNamingStrategy.js +22 -22
  90. package/naming-strategy/MongoNamingStrategy.d.ts +6 -6
  91. package/naming-strategy/MongoNamingStrategy.js +18 -18
  92. package/naming-strategy/NamingStrategy.d.ts +109 -99
  93. package/naming-strategy/UnderscoreNamingStrategy.d.ts +7 -7
  94. package/naming-strategy/UnderscoreNamingStrategy.js +21 -21
  95. package/not-supported.js +7 -4
  96. package/package.json +1 -1
  97. package/platforms/ExceptionConverter.d.ts +1 -1
  98. package/platforms/ExceptionConverter.js +4 -4
  99. package/platforms/Platform.d.ts +312 -303
  100. package/platforms/Platform.js +695 -642
  101. package/serialization/EntitySerializer.d.ts +49 -26
  102. package/serialization/EntitySerializer.js +224 -218
  103. package/serialization/EntityTransformer.d.ts +10 -6
  104. package/serialization/EntityTransformer.js +219 -217
  105. package/serialization/SerializationContext.d.ts +27 -23
  106. package/serialization/SerializationContext.js +105 -105
  107. package/types/ArrayType.d.ts +8 -8
  108. package/types/ArrayType.js +33 -33
  109. package/types/BigIntType.d.ts +17 -10
  110. package/types/BigIntType.js +37 -37
  111. package/types/BlobType.d.ts +3 -3
  112. package/types/BlobType.js +13 -13
  113. package/types/BooleanType.d.ts +4 -4
  114. package/types/BooleanType.js +12 -12
  115. package/types/CharacterType.d.ts +2 -2
  116. package/types/CharacterType.js +6 -6
  117. package/types/DateTimeType.d.ts +5 -5
  118. package/types/DateTimeType.js +15 -15
  119. package/types/DateType.d.ts +5 -5
  120. package/types/DateType.js +15 -15
  121. package/types/DecimalType.d.ts +7 -7
  122. package/types/DecimalType.js +26 -26
  123. package/types/DoubleType.d.ts +3 -3
  124. package/types/DoubleType.js +12 -12
  125. package/types/EnumArrayType.d.ts +5 -5
  126. package/types/EnumArrayType.js +24 -24
  127. package/types/EnumType.d.ts +3 -3
  128. package/types/EnumType.js +11 -11
  129. package/types/FloatType.d.ts +3 -3
  130. package/types/FloatType.js +9 -9
  131. package/types/IntegerType.d.ts +3 -3
  132. package/types/IntegerType.js +9 -9
  133. package/types/IntervalType.d.ts +4 -4
  134. package/types/IntervalType.js +12 -12
  135. package/types/JsonType.d.ts +8 -8
  136. package/types/JsonType.js +32 -32
  137. package/types/MediumIntType.d.ts +1 -1
  138. package/types/MediumIntType.js +3 -3
  139. package/types/SmallIntType.d.ts +3 -3
  140. package/types/SmallIntType.js +9 -9
  141. package/types/StringType.d.ts +4 -4
  142. package/types/StringType.js +12 -12
  143. package/types/TextType.d.ts +3 -3
  144. package/types/TextType.js +9 -9
  145. package/types/TimeType.d.ts +5 -5
  146. package/types/TimeType.js +17 -17
  147. package/types/TinyIntType.d.ts +3 -3
  148. package/types/TinyIntType.js +10 -10
  149. package/types/Type.d.ts +83 -79
  150. package/types/Type.js +82 -82
  151. package/types/Uint8ArrayType.d.ts +4 -4
  152. package/types/Uint8ArrayType.js +21 -21
  153. package/types/UnknownType.d.ts +4 -4
  154. package/types/UnknownType.js +12 -12
  155. package/types/UuidType.d.ts +5 -5
  156. package/types/UuidType.js +19 -19
  157. package/types/index.d.ts +75 -49
  158. package/types/index.js +52 -26
  159. package/typings.d.ts +1254 -741
  160. package/typings.js +244 -233
  161. package/unit-of-work/ChangeSet.d.ts +26 -26
  162. package/unit-of-work/ChangeSet.js +56 -56
  163. package/unit-of-work/ChangeSetComputer.d.ts +12 -12
  164. package/unit-of-work/ChangeSetComputer.js +187 -179
  165. package/unit-of-work/ChangeSetPersister.d.ts +69 -50
  166. package/unit-of-work/ChangeSetPersister.js +465 -442
  167. package/unit-of-work/CommitOrderCalculator.d.ts +40 -40
  168. package/unit-of-work/CommitOrderCalculator.js +89 -88
  169. package/unit-of-work/IdentityMap.d.ts +31 -31
  170. package/unit-of-work/IdentityMap.js +105 -105
  171. package/unit-of-work/UnitOfWork.d.ts +181 -141
  172. package/unit-of-work/UnitOfWork.js +1236 -1222
  173. package/utils/AbstractMigrator.d.ts +111 -91
  174. package/utils/AbstractMigrator.js +275 -275
  175. package/utils/AbstractSchemaGenerator.d.ts +43 -34
  176. package/utils/AbstractSchemaGenerator.js +121 -122
  177. package/utils/AsyncContext.d.ts +3 -3
  178. package/utils/AsyncContext.js +34 -35
  179. package/utils/Configuration.d.ts +852 -808
  180. package/utils/Configuration.js +359 -344
  181. package/utils/Cursor.d.ts +40 -22
  182. package/utils/Cursor.js +135 -127
  183. package/utils/DataloaderUtils.d.ts +58 -43
  184. package/utils/DataloaderUtils.js +203 -198
  185. package/utils/EntityComparator.d.ts +99 -82
  186. package/utils/EntityComparator.js +829 -737
  187. package/utils/NullHighlighter.d.ts +1 -1
  188. package/utils/NullHighlighter.js +3 -3
  189. package/utils/QueryHelper.d.ts +79 -51
  190. package/utils/QueryHelper.js +372 -361
  191. package/utils/RawQueryFragment.d.ts +50 -34
  192. package/utils/RawQueryFragment.js +107 -105
  193. package/utils/RequestContext.d.ts +32 -32
  194. package/utils/RequestContext.js +52 -53
  195. package/utils/TransactionContext.d.ts +16 -16
  196. package/utils/TransactionContext.js +27 -27
  197. package/utils/TransactionManager.d.ts +58 -58
  198. package/utils/TransactionManager.js +199 -197
  199. package/utils/Utils.d.ts +204 -145
  200. package/utils/Utils.js +815 -815
  201. package/utils/clone.js +105 -114
  202. package/utils/env-vars.js +90 -88
  203. package/utils/fs-utils.d.ts +15 -15
  204. package/utils/fs-utils.js +180 -181
  205. package/utils/upsert-utils.d.ts +20 -5
  206. package/utils/upsert-utils.js +114 -116
@@ -1,7 +1,6 @@
1
- import { EntityManagerType, } from './IDatabaseDriver.js';
1
+ import { EntityManagerType } from './IDatabaseDriver.js';
2
2
  import { Utils } from '../utils/Utils.js';
3
3
  import { Cursor } from '../utils/Cursor.js';
4
- import { EntityComparator } from '../utils/EntityComparator.js';
5
4
  import { isRaw, raw } from '../utils/RawQueryFragment.js';
6
5
  import { QueryOrderNumeric, ReferenceKind } from '../enums.js';
7
6
  import { EntityManager } from '../EntityManager.js';
@@ -13,474 +12,481 @@ import { JsonType } from '../types/JsonType.js';
13
12
  import { MikroORM } from '../MikroORM.js';
14
13
  /** Abstract base class for all database drivers, implementing common driver logic. */
15
14
  export class DatabaseDriver {
16
- config;
17
- dependencies;
18
- [EntityManagerType];
19
- connection;
20
- replicas = [];
21
- platform;
22
- comparator;
23
- metadata;
24
- constructor(config, dependencies) {
25
- this.config = config;
26
- this.dependencies = dependencies;
27
- }
28
- async nativeUpdateMany(entityName, where, data, options) {
29
- throw new Error(`Batch updates are not supported by ${this.constructor.name} driver`);
30
- }
31
- /** Creates a new EntityManager instance bound to this driver. */
32
- createEntityManager(useContext) {
33
- const EntityManagerClass = this.config.get('entityManager', EntityManager);
34
- return new EntityManagerClass(this.config, this, this.metadata, useContext);
35
- }
36
- /* v8 ignore next */
37
- async findVirtual(entityName, where, options) {
38
- throw new Error(`Virtual entities are not supported by ${this.constructor.name} driver.`);
39
- }
40
- /* v8 ignore next */
41
- async countVirtual(entityName, where, options) {
42
- throw new Error(`Counting virtual entities is not supported by ${this.constructor.name} driver.`);
43
- }
44
- async aggregate(entityName, pipeline) {
45
- throw new Error(`Aggregations are not supported by ${this.constructor.name} driver`);
46
- }
47
- async loadFromPivotTable(prop, owners, where, orderBy, ctx, options, pivotJoin) {
48
- throw new Error(`${this.constructor.name} does not use pivot tables`);
49
- }
50
- async syncCollections(collections, options) {
51
- for (const coll of collections) {
52
- /* v8 ignore else */
53
- if (!coll.property.owner) {
54
- if (coll.getSnapshot() === undefined) {
55
- throw ValidationError.cannotModifyInverseCollection(coll.owner, coll.property);
56
- }
57
- continue;
58
- }
59
- /* v8 ignore next */
60
- {
61
- const pk = coll.property.targetMeta.primaryKeys[0];
62
- const data = { [coll.property.name]: coll.getIdentifiers(pk) };
63
- await this.nativeUpdate(coll.owner.constructor, helper(coll.owner).getPrimaryKey(), data, options);
64
- }
15
+ config;
16
+ dependencies;
17
+ [EntityManagerType];
18
+ connection;
19
+ replicas = [];
20
+ platform;
21
+ comparator;
22
+ metadata;
23
+ constructor(config, dependencies) {
24
+ this.config = config;
25
+ this.dependencies = dependencies;
26
+ }
27
+ async nativeUpdateMany(entityName, where, data, options) {
28
+ throw new Error(`Batch updates are not supported by ${this.constructor.name} driver`);
29
+ }
30
+ /** Creates a new EntityManager instance bound to this driver. */
31
+ createEntityManager(useContext) {
32
+ const EntityManagerClass = this.config.get('entityManager', EntityManager);
33
+ return new EntityManagerClass(this.config, this, this.metadata, useContext);
34
+ }
35
+ /* v8 ignore next */
36
+ async findVirtual(entityName, where, options) {
37
+ throw new Error(`Virtual entities are not supported by ${this.constructor.name} driver.`);
38
+ }
39
+ /* v8 ignore next */
40
+ async countVirtual(entityName, where, options) {
41
+ throw new Error(`Counting virtual entities is not supported by ${this.constructor.name} driver.`);
42
+ }
43
+ async aggregate(entityName, pipeline) {
44
+ throw new Error(`Aggregations are not supported by ${this.constructor.name} driver`);
45
+ }
46
+ async loadFromPivotTable(prop, owners, where, orderBy, ctx, options, pivotJoin) {
47
+ throw new Error(`${this.constructor.name} does not use pivot tables`);
48
+ }
49
+ async syncCollections(collections, options) {
50
+ for (const coll of collections) {
51
+ /* v8 ignore else */
52
+ if (!coll.property.owner) {
53
+ if (coll.getSnapshot() === undefined) {
54
+ throw ValidationError.cannotModifyInverseCollection(coll.owner, coll.property);
65
55
  }
56
+ continue;
57
+ }
58
+ /* v8 ignore next */
59
+ {
60
+ const pk = coll.property.targetMeta.primaryKeys[0];
61
+ const data = { [coll.property.name]: coll.getIdentifiers(pk) };
62
+ await this.nativeUpdate(coll.owner.constructor, helper(coll.owner).getPrimaryKey(), data, options);
63
+ }
66
64
  }
67
- /** Maps raw database result to entity data, converting column names to property names. */
68
- mapResult(result, meta, populate = []) {
69
- if (!result || !meta) {
70
- return result ?? null;
71
- }
72
- return this.comparator.mapResult(meta, result);
73
- }
74
- /** Opens the primary connection and all read replicas. */
75
- async connect(options) {
76
- await this.connection.connect(options);
77
- await Promise.all(this.replicas.map(replica => replica.connect()));
78
- return this.connection;
79
- }
80
- /** Closes all connections and re-establishes them. */
81
- async reconnect(options) {
82
- await this.close(true);
83
- await this.connect(options);
84
- return this.connection;
65
+ }
66
+ /** Maps raw database result to entity data, converting column names to property names. */
67
+ mapResult(result, meta, populate = []) {
68
+ if (!result || !meta) {
69
+ return result ?? null;
85
70
  }
86
- /** Returns the write connection or a random read replica. */
87
- getConnection(type = 'write') {
88
- if (type === 'write' || this.replicas.length === 0) {
89
- return this.connection;
90
- }
91
- const rand = Utils.randomInt(0, this.replicas.length - 1);
92
- return this.replicas[rand];
71
+ return this.comparator.mapResult(meta, result);
72
+ }
73
+ /** Opens the primary connection and all read replicas. */
74
+ async connect(options) {
75
+ await this.connection.connect(options);
76
+ await Promise.all(this.replicas.map(replica => replica.connect()));
77
+ return this.connection;
78
+ }
79
+ /** Closes all connections and re-establishes them. */
80
+ async reconnect(options) {
81
+ await this.close(true);
82
+ await this.connect(options);
83
+ return this.connection;
84
+ }
85
+ /** Returns the write connection or a random read replica. */
86
+ getConnection(type = 'write') {
87
+ if (type === 'write' || this.replicas.length === 0) {
88
+ return this.connection;
93
89
  }
94
- /** Closes the primary connection and all read replicas. */
95
- async close(force) {
96
- await Promise.all(this.replicas.map(replica => replica.close(force)));
97
- await this.connection.close(force);
90
+ const rand = Utils.randomInt(0, this.replicas.length - 1);
91
+ return this.replicas[rand];
92
+ }
93
+ /** Closes the primary connection and all read replicas. */
94
+ async close(force) {
95
+ await Promise.all(this.replicas.map(replica => replica.close(force)));
96
+ await this.connection.close(force);
97
+ }
98
+ /** Returns the database platform abstraction for this driver. */
99
+ getPlatform() {
100
+ return this.platform;
101
+ }
102
+ /** Sets the metadata storage and initializes the comparator for all connections. */
103
+ setMetadata(metadata) {
104
+ this.metadata = metadata;
105
+ this.comparator = this.config.getComparator(metadata);
106
+ this.connection.setMetadata(metadata);
107
+ this.connection.setPlatform(this.platform);
108
+ this.replicas.forEach(replica => {
109
+ replica.setMetadata(metadata);
110
+ replica.setPlatform(this.platform);
111
+ });
112
+ }
113
+ /** Returns the metadata storage used by this driver. */
114
+ getMetadata() {
115
+ return this.metadata;
116
+ }
117
+ /** Returns the names of native database dependencies required by this driver. */
118
+ getDependencies() {
119
+ return this.dependencies;
120
+ }
121
+ isPopulated(meta, prop, hint, name) {
122
+ if (hint.field === prop.name || hint.field === name || hint.all) {
123
+ return true;
98
124
  }
99
- /** Returns the database platform abstraction for this driver. */
100
- getPlatform() {
101
- return this.platform;
125
+ if (prop.embedded && hint.children && meta.properties[prop.embedded[0]].name === hint.field) {
126
+ return hint.children.some(c => this.isPopulated(meta, prop, c, prop.embedded[1]));
102
127
  }
103
- /** Sets the metadata storage and initializes the comparator for all connections. */
104
- setMetadata(metadata) {
105
- this.metadata = metadata;
106
- this.comparator = new EntityComparator(this.metadata, this.platform);
107
- this.connection.setMetadata(metadata);
108
- this.connection.setPlatform(this.platform);
109
- this.replicas.forEach(replica => {
110
- replica.setMetadata(metadata);
111
- replica.setPlatform(this.platform);
112
- });
128
+ return false;
129
+ }
130
+ processCursorOptions(meta, options, orderBy) {
131
+ const { first, last, before, after, overfetch } = options;
132
+ const limit = first ?? last;
133
+ const isLast = !first && !!last;
134
+ const definition = Cursor.getDefinition(meta, orderBy);
135
+ const $and = [];
136
+ // allow POJO as well, we care only about the correct key being present
137
+ const isCursor = (val, key) => {
138
+ return !!val && typeof val === 'object' && key in val;
139
+ };
140
+ const createCursor = (val, key, inverse = false) => {
141
+ let def = isCursor(val, key) ? val[key] : val;
142
+ if (Utils.isPlainObject(def)) {
143
+ def = Cursor.for(meta, def, orderBy);
144
+ }
145
+ /* v8 ignore next */
146
+ const offsets = def ? Cursor.decode(def) : [];
147
+ if (definition.length === offsets.length) {
148
+ return this.createCursorCondition(definition, offsets, inverse, meta);
149
+ }
150
+ /* v8 ignore next */
151
+ return {};
152
+ };
153
+ if (after) {
154
+ $and.push(createCursor(after, 'endCursor'));
113
155
  }
114
- /** Returns the metadata storage used by this driver. */
115
- getMetadata() {
116
- return this.metadata;
156
+ if (before) {
157
+ $and.push(createCursor(before, 'startCursor', true));
117
158
  }
118
- /** Returns the names of native database dependencies required by this driver. */
119
- getDependencies() {
120
- return this.dependencies;
159
+ if (limit != null) {
160
+ options.limit = limit + (overfetch ? 1 : 0);
121
161
  }
122
- isPopulated(meta, prop, hint, name) {
123
- if (hint.field === prop.name || hint.field === name || hint.all) {
124
- return true;
162
+ const createOrderBy = (prop, direction) => {
163
+ if (Utils.isPlainObject(direction)) {
164
+ const value = Utils.getObjectQueryKeys(direction).reduce((o, key) => {
165
+ Object.assign(o, createOrderBy(key, direction[key]));
166
+ return o;
167
+ }, {});
168
+ return { [prop]: value };
169
+ }
170
+ const desc = direction === QueryOrderNumeric.DESC || direction.toString().toLowerCase() === 'desc';
171
+ const dir = Utils.xor(desc, isLast) ? 'desc' : 'asc';
172
+ return { [prop]: dir };
173
+ };
174
+ return {
175
+ orderBy: definition.map(([prop, direction]) => createOrderBy(prop, direction)),
176
+ where: $and.length > 1 ? { $and } : { ...$and[0] },
177
+ };
178
+ }
179
+ createCursorCondition(definition, offsets, inverse, meta) {
180
+ const createCondition = (prop, direction, offset, eq = false, path = prop) => {
181
+ if (Utils.isPlainObject(direction)) {
182
+ if (offset === undefined) {
183
+ throw CursorError.missingValue(meta.className, path);
125
184
  }
126
- if (prop.embedded && hint.children && meta.properties[prop.embedded[0]].name === hint.field) {
127
- return hint.children.some(c => this.isPopulated(meta, prop, c, prop.embedded[1]));
185
+ const value = Utils.keys(direction).reduce((o, key) => {
186
+ Object.assign(o, createCondition(key, direction[key], offset?.[key], eq, `${path}.${key}`));
187
+ return o;
188
+ }, {});
189
+ return { [prop]: value };
190
+ }
191
+ const isDesc = direction === QueryOrderNumeric.DESC || direction.toString().toLowerCase() === 'desc';
192
+ const dirStr = direction.toString().toLowerCase();
193
+ let nullsFirst;
194
+ if (dirStr.includes('nulls first')) {
195
+ nullsFirst = true;
196
+ } else if (dirStr.includes('nulls last')) {
197
+ nullsFirst = false;
198
+ } else {
199
+ // Default: NULLS LAST for ASC, NULLS FIRST for DESC (matches most databases)
200
+ nullsFirst = isDesc;
201
+ }
202
+ const operator = Utils.xor(isDesc, inverse) ? '$lt' : '$gt';
203
+ // For leaf-level properties, undefined means missing value
204
+ if (offset === undefined) {
205
+ throw CursorError.missingValue(meta.className, path);
206
+ }
207
+ // Handle null offset (intentional null cursor value)
208
+ if (offset === null) {
209
+ if (eq) {
210
+ // Equal to null
211
+ return { [prop]: null };
128
212
  }
129
- return false;
130
- }
131
- processCursorOptions(meta, options, orderBy) {
132
- const { first, last, before, after, overfetch } = options;
133
- const limit = first ?? last;
134
- const isLast = !first && !!last;
135
- const definition = Cursor.getDefinition(meta, orderBy);
136
- const $and = [];
137
- // allow POJO as well, we care only about the correct key being present
138
- const isCursor = (val, key) => {
139
- return !!val && typeof val === 'object' && key in val;
140
- };
141
- const createCursor = (val, key, inverse = false) => {
142
- let def = isCursor(val, key) ? val[key] : val;
143
- if (Utils.isPlainObject(def)) {
144
- def = Cursor.for(meta, def, orderBy);
145
- }
146
- /* v8 ignore next */
147
- const offsets = def ? Cursor.decode(def) : [];
148
- if (definition.length === offsets.length) {
149
- return this.createCursorCondition(definition, offsets, inverse, meta);
150
- }
151
- /* v8 ignore next */
152
- return {};
153
- };
154
- if (after) {
155
- $and.push(createCursor(after, 'endCursor'));
213
+ // Strict comparison with null cursor value
214
+ // hasItemsAfterNull: forward + nullsFirst, or backward + nullsLast
215
+ const hasItemsAfterNull = Utils.xor(nullsFirst, inverse);
216
+ if (hasItemsAfterNull) {
217
+ return { [prop]: { $ne: null } };
156
218
  }
157
- if (before) {
158
- $and.push(createCursor(before, 'startCursor', true));
219
+ // No items after null in this direction, return impossible condition
220
+ return { [prop]: [] };
221
+ }
222
+ // Non-null offset
223
+ return { [prop]: { [operator + (eq ? 'e' : '')]: offset } };
224
+ };
225
+ const [order, ...otherOrders] = definition;
226
+ const [offset, ...otherOffsets] = offsets;
227
+ const [prop, direction] = order;
228
+ if (!otherOrders.length) {
229
+ return createCondition(prop, direction, offset);
230
+ }
231
+ return {
232
+ ...createCondition(prop, direction, offset, true),
233
+ $or: [
234
+ createCondition(prop, direction, offset),
235
+ this.createCursorCondition(otherOrders, otherOffsets, inverse, meta),
236
+ ],
237
+ };
238
+ }
239
+ /** @internal */
240
+ mapDataToFieldNames(data, stringifyJsonArrays, properties, convertCustomTypes, object) {
241
+ if (!properties || data == null) {
242
+ return data;
243
+ }
244
+ data = Object.assign({}, data); // copy first
245
+ Object.keys(data).forEach(k => {
246
+ const prop = properties[k];
247
+ if (!prop) {
248
+ return;
249
+ }
250
+ if (prop.embeddedProps && !prop.object && !object) {
251
+ const copy = data[k];
252
+ delete data[k];
253
+ Object.assign(
254
+ data,
255
+ this.mapDataToFieldNames(copy, stringifyJsonArrays, prop.embeddedProps, convertCustomTypes),
256
+ );
257
+ return;
258
+ }
259
+ if (prop.embeddedProps && (object || prop.object)) {
260
+ const copy = data[k];
261
+ delete data[k];
262
+ if (prop.array) {
263
+ data[prop.fieldNames[0]] = copy?.map(item =>
264
+ this.mapDataToFieldNames(item, stringifyJsonArrays, prop.embeddedProps, convertCustomTypes, true),
265
+ );
266
+ } else {
267
+ data[prop.fieldNames[0]] = this.mapDataToFieldNames(
268
+ copy,
269
+ stringifyJsonArrays,
270
+ prop.embeddedProps,
271
+ convertCustomTypes,
272
+ true,
273
+ );
159
274
  }
160
- if (limit != null) {
161
- options.limit = limit + (overfetch ? 1 : 0);
275
+ if (stringifyJsonArrays && prop.array && !object) {
276
+ data[prop.fieldNames[0]] = this.platform.convertJsonToDatabaseValue(data[prop.fieldNames[0]]);
162
277
  }
163
- const createOrderBy = (prop, direction) => {
164
- if (Utils.isPlainObject(direction)) {
165
- const value = Utils.getObjectQueryKeys(direction).reduce((o, key) => {
166
- Object.assign(o, createOrderBy(key, direction[key]));
167
- return o;
168
- }, {});
169
- return { [prop]: value };
170
- }
171
- const desc = direction === QueryOrderNumeric.DESC || direction.toString().toLowerCase() === 'desc';
172
- const dir = Utils.xor(desc, isLast) ? 'desc' : 'asc';
173
- return { [prop]: dir };
174
- };
175
- return {
176
- orderBy: definition.map(([prop, direction]) => createOrderBy(prop, direction)),
177
- where: ($and.length > 1 ? { $and } : { ...$and[0] }),
178
- };
179
- }
180
- createCursorCondition(definition, offsets, inverse, meta) {
181
- const createCondition = (prop, direction, offset, eq = false, path = prop) => {
182
- if (Utils.isPlainObject(direction)) {
183
- if (offset === undefined) {
184
- throw CursorError.missingValue(meta.className, path);
185
- }
186
- const value = Utils.keys(direction).reduce((o, key) => {
187
- Object.assign(o, createCondition(key, direction[key], offset?.[key], eq, `${path}.${key}`));
188
- return o;
189
- }, {});
190
- return { [prop]: value };
191
- }
192
- const isDesc = direction === QueryOrderNumeric.DESC || direction.toString().toLowerCase() === 'desc';
193
- const dirStr = direction.toString().toLowerCase();
194
- let nullsFirst;
195
- if (dirStr.includes('nulls first')) {
196
- nullsFirst = true;
197
- }
198
- else if (dirStr.includes('nulls last')) {
199
- nullsFirst = false;
200
- }
201
- else {
202
- // Default: NULLS LAST for ASC, NULLS FIRST for DESC (matches most databases)
203
- nullsFirst = isDesc;
204
- }
205
- const operator = Utils.xor(isDesc, inverse) ? '$lt' : '$gt';
206
- // For leaf-level properties, undefined means missing value
207
- if (offset === undefined) {
208
- throw CursorError.missingValue(meta.className, path);
209
- }
210
- // Handle null offset (intentional null cursor value)
211
- if (offset === null) {
212
- if (eq) {
213
- // Equal to null
214
- return { [prop]: null };
215
- }
216
- // Strict comparison with null cursor value
217
- // hasItemsAfterNull: forward + nullsFirst, or backward + nullsLast
218
- const hasItemsAfterNull = Utils.xor(nullsFirst, inverse);
219
- if (hasItemsAfterNull) {
220
- return { [prop]: { $ne: null } };
221
- }
222
- // No items after null in this direction, return impossible condition
223
- return { [prop]: [] };
224
- }
225
- // Non-null offset
226
- return { [prop]: { [operator + (eq ? 'e' : '')]: offset } };
227
- };
228
- const [order, ...otherOrders] = definition;
229
- const [offset, ...otherOffsets] = offsets;
230
- const [prop, direction] = order;
231
- if (!otherOrders.length) {
232
- return createCondition(prop, direction, offset);
278
+ return;
279
+ }
280
+ // Handle polymorphic relations - convert tuple or PolymorphicRef to separate columns
281
+ // Tuple format: ['discriminator', id] or ['discriminator', id1, id2] for composite keys
282
+ // Must be checked BEFORE joinColumns array handling since polymorphic uses fieldNames (includes discriminator)
283
+ if (prop.polymorphic && prop.fieldNames && prop.fieldNames.length >= 2) {
284
+ let discriminator;
285
+ let ids;
286
+ if (Array.isArray(data[k]) && typeof data[k][0] === 'string' && prop.discriminatorMap?.[data[k][0]]) {
287
+ // Tuple format: ['discriminator', ...ids]
288
+ const [disc, ...rest] = data[k];
289
+ discriminator = disc;
290
+ ids = rest;
291
+ } else if (data[k] instanceof PolymorphicRef) {
292
+ // PolymorphicRef wrapper (internal use)
293
+ discriminator = data[k].discriminator;
294
+ const polyId = data[k].id;
295
+ // Handle object-style composite key IDs like { tenantId: 1, orgId: 100 }
296
+ if (polyId && typeof polyId === 'object' && !Array.isArray(polyId)) {
297
+ const targetEntity = prop.discriminatorMap?.[discriminator];
298
+ const targetMeta = this.metadata.get(targetEntity);
299
+ ids = targetMeta.primaryKeys.map(pk => polyId[pk]);
300
+ } else {
301
+ ids = Utils.asArray(polyId);
302
+ }
233
303
  }
234
- return {
235
- ...createCondition(prop, direction, offset, true),
236
- $or: [
237
- createCondition(prop, direction, offset),
238
- this.createCursorCondition(otherOrders, otherOffsets, inverse, meta),
239
- ],
240
- };
241
- }
242
- /** @internal */
243
- mapDataToFieldNames(data, stringifyJsonArrays, properties, convertCustomTypes, object) {
244
- if (!properties || data == null) {
245
- return data;
304
+ if (discriminator) {
305
+ const discriminatorColumn = prop.fieldNames[0];
306
+ const idColumns = prop.fieldNames.slice(1);
307
+ delete data[k];
308
+ data[discriminatorColumn] = discriminator;
309
+ idColumns.forEach((col, idx) => {
310
+ data[col] = ids[idx];
311
+ });
312
+ return;
246
313
  }
247
- data = Object.assign({}, data); // copy first
248
- Object.keys(data).forEach(k => {
249
- const prop = properties[k];
250
- if (!prop) {
251
- return;
252
- }
253
- if (prop.embeddedProps && !prop.object && !object) {
254
- const copy = data[k];
255
- delete data[k];
256
- Object.assign(data, this.mapDataToFieldNames(copy, stringifyJsonArrays, prop.embeddedProps, convertCustomTypes));
257
- return;
258
- }
259
- if (prop.embeddedProps && (object || prop.object)) {
260
- const copy = data[k];
261
- delete data[k];
262
- if (prop.array) {
263
- data[prop.fieldNames[0]] = copy?.map((item) => this.mapDataToFieldNames(item, stringifyJsonArrays, prop.embeddedProps, convertCustomTypes, true));
264
- }
265
- else {
266
- data[prop.fieldNames[0]] = this.mapDataToFieldNames(copy, stringifyJsonArrays, prop.embeddedProps, convertCustomTypes, true);
267
- }
268
- if (stringifyJsonArrays && prop.array && !object) {
269
- data[prop.fieldNames[0]] = this.platform.convertJsonToDatabaseValue(data[prop.fieldNames[0]]);
270
- }
271
- return;
272
- }
273
- // Handle polymorphic relations - convert tuple or PolymorphicRef to separate columns
274
- // Tuple format: ['discriminator', id] or ['discriminator', id1, id2] for composite keys
275
- // Must be checked BEFORE joinColumns array handling since polymorphic uses fieldNames (includes discriminator)
276
- if (prop.polymorphic && prop.fieldNames && prop.fieldNames.length >= 2) {
277
- let discriminator;
278
- let ids;
279
- if (Array.isArray(data[k]) && typeof data[k][0] === 'string' && prop.discriminatorMap?.[data[k][0]]) {
280
- // Tuple format: ['discriminator', ...ids]
281
- const [disc, ...rest] = data[k];
282
- discriminator = disc;
283
- ids = rest;
284
- }
285
- else if (data[k] instanceof PolymorphicRef) {
286
- // PolymorphicRef wrapper (internal use)
287
- discriminator = data[k].discriminator;
288
- const polyId = data[k].id;
289
- // Handle object-style composite key IDs like { tenantId: 1, orgId: 100 }
290
- if (polyId && typeof polyId === 'object' && !Array.isArray(polyId)) {
291
- const targetEntity = prop.discriminatorMap?.[discriminator];
292
- const targetMeta = this.metadata.get(targetEntity);
293
- ids = targetMeta.primaryKeys.map(pk => polyId[pk]);
294
- }
295
- else {
296
- ids = Utils.asArray(polyId);
297
- }
298
- }
299
- if (discriminator) {
300
- const discriminatorColumn = prop.fieldNames[0];
301
- const idColumns = prop.fieldNames.slice(1);
302
- delete data[k];
303
- data[discriminatorColumn] = discriminator;
304
- idColumns.forEach((col, idx) => {
305
- data[col] = ids[idx];
306
- });
307
- return;
308
- }
309
- }
310
- if (prop.joinColumns && Array.isArray(data[k])) {
311
- const copy = Utils.flatten(data[k]);
312
- delete data[k];
313
- prop.joinColumns.forEach((joinColumn, idx) => (data[joinColumn] = copy[idx]));
314
- return;
315
- }
316
- if (prop.joinColumns?.length > 1 && data[k] == null) {
317
- delete data[k];
318
- prop.ownColumns.forEach(joinColumn => (data[joinColumn] = null));
319
- return;
320
- }
321
- if (prop.customType &&
322
- convertCustomTypes &&
323
- !(prop.customType instanceof JsonType && object) &&
324
- !isRaw(data[k])) {
325
- data[k] = prop.customType.convertToDatabaseValue(data[k], this.platform, {
326
- fromQuery: true,
327
- key: k,
328
- mode: 'query-data',
329
- });
330
- }
331
- if (prop.hasConvertToDatabaseValueSQL && !prop.object && !isRaw(data[k])) {
332
- const quoted = this.platform.quoteValue(data[k]);
333
- const sql = prop.customType.convertToDatabaseValueSQL(quoted, this.platform);
334
- data[k] = raw(sql.replace(/\?/g, '\\?'));
335
- }
336
- if (prop.fieldNames) {
337
- Utils.renameKey(data, k, prop.fieldNames[0]);
338
- }
314
+ }
315
+ if (prop.joinColumns && Array.isArray(data[k])) {
316
+ const copy = Utils.flatten(data[k]);
317
+ delete data[k];
318
+ (prop.ownColumns ?? prop.joinColumns).forEach(col => (data[col] = copy[prop.joinColumns.indexOf(col)]));
319
+ return;
320
+ }
321
+ if (prop.joinColumns?.length > 1 && data[k] == null) {
322
+ delete data[k];
323
+ prop.ownColumns.forEach(joinColumn => (data[joinColumn] = null));
324
+ return;
325
+ }
326
+ if (
327
+ prop.customType &&
328
+ convertCustomTypes &&
329
+ !(prop.customType instanceof JsonType && object) &&
330
+ !isRaw(data[k])
331
+ ) {
332
+ data[k] = prop.customType.convertToDatabaseValue(data[k], this.platform, {
333
+ fromQuery: true,
334
+ key: k,
335
+ mode: 'query-data',
339
336
  });
340
- return data;
337
+ }
338
+ if (prop.hasConvertToDatabaseValueSQL && !prop.object && !isRaw(data[k])) {
339
+ const quoted = this.platform.quoteValue(data[k]);
340
+ const sql = prop.customType.convertToDatabaseValueSQL(quoted, this.platform);
341
+ data[k] = raw(sql.replace(/\?/g, '\\?'));
342
+ }
343
+ if (prop.fieldNames) {
344
+ Utils.renameKey(data, k, prop.fieldNames[0]);
345
+ }
346
+ });
347
+ return data;
348
+ }
349
+ inlineEmbeddables(meta, data, where) {
350
+ /* v8 ignore next */
351
+ if (data == null) {
352
+ return;
341
353
  }
342
- inlineEmbeddables(meta, data, where) {
343
- /* v8 ignore next */
344
- if (data == null) {
345
- return;
346
- }
347
- Utils.keys(data).forEach(k => {
348
- if (Utils.isOperator(k)) {
349
- Utils.asArray(data[k]).forEach(payload => this.inlineEmbeddables(meta, payload, where));
350
- }
351
- });
352
- meta.props.forEach(prop => {
353
- if (prop.kind === ReferenceKind.EMBEDDED && prop.object && !where && Utils.isObject(data[prop.name])) {
354
- return;
355
- }
356
- if (prop.kind === ReferenceKind.EMBEDDED && Utils.isObject(data[prop.name])) {
357
- const props = prop.embeddedProps;
358
- let unknownProp = false;
359
- Object.keys(data[prop.name]).forEach(kk => {
360
- // explicitly allow `$exists`, `$eq`, `$ne` and `$elemMatch` operators here as they can't be misused this way
361
- const operator = Object.keys(data[prop.name]).some(f => Utils.isOperator(f) && !['$exists', '$ne', '$eq', '$elemMatch'].includes(f));
362
- if (operator) {
363
- throw ValidationError.cannotUseOperatorsInsideEmbeddables(meta.class, prop.name, data);
364
- }
365
- if (prop.object && where) {
366
- const inline = (payload, sub, path) => {
367
- if (sub.kind === ReferenceKind.EMBEDDED && Utils.isObject(payload[sub.embedded[1]])) {
368
- return Object.keys(payload[sub.embedded[1]]).forEach(kkk => {
369
- if (!sub.embeddedProps[kkk]) {
370
- throw ValidationError.invalidEmbeddableQuery(meta.class, kkk, sub.type);
371
- }
372
- inline(payload[sub.embedded[1]], sub.embeddedProps[kkk], [...path, sub.fieldNames[0]]);
373
- });
374
- }
375
- data[`${path.join('.')}.${sub.fieldNames[0]}`] = payload[sub.embedded[1]];
376
- };
377
- const parentPropName = kk.substring(0, kk.indexOf('.'));
378
- // we might be using some native JSON operator, e.g. with mongodb's `$geoWithin` or `$exists`
379
- if (props[kk]) {
380
- /* v8 ignore next */
381
- inline(data[prop.name], props[kk] || props[parentPropName], [prop.fieldNames[0]]);
382
- }
383
- else if (props[parentPropName]) {
384
- data[`${prop.fieldNames[0]}.${kk}`] = data[prop.name][kk];
385
- }
386
- else {
387
- unknownProp = true;
388
- }
389
- }
390
- else if (props[kk]) {
391
- data[props[kk].fieldNames[0]] = data[prop.name][props[kk].embedded[1]];
392
- }
393
- else {
394
- throw ValidationError.invalidEmbeddableQuery(meta.class, kk, prop.type);
395
- }
354
+ Utils.keys(data).forEach(k => {
355
+ if (Utils.isOperator(k)) {
356
+ Utils.asArray(data[k]).forEach(payload => this.inlineEmbeddables(meta, payload, where));
357
+ }
358
+ });
359
+ meta.props.forEach(prop => {
360
+ if (prop.kind === ReferenceKind.EMBEDDED && prop.object && !where && Utils.isObject(data[prop.name])) {
361
+ return;
362
+ }
363
+ if (prop.kind === ReferenceKind.EMBEDDED && Utils.isObject(data[prop.name])) {
364
+ const props = prop.embeddedProps;
365
+ let unknownProp = false;
366
+ Object.keys(data[prop.name]).forEach(kk => {
367
+ // explicitly allow `$exists`, `$eq`, `$ne` and `$elemMatch` operators here as they can't be misused this way
368
+ const operator = Object.keys(data[prop.name]).some(
369
+ f => Utils.isOperator(f) && !['$exists', '$ne', '$eq', '$elemMatch'].includes(f),
370
+ );
371
+ if (operator) {
372
+ throw ValidationError.cannotUseOperatorsInsideEmbeddables(meta.class, prop.name, data);
373
+ }
374
+ if (prop.object && where) {
375
+ const inline = (payload, sub, path) => {
376
+ if (sub.kind === ReferenceKind.EMBEDDED && Utils.isObject(payload[sub.embedded[1]])) {
377
+ return Object.keys(payload[sub.embedded[1]]).forEach(kkk => {
378
+ if (!sub.embeddedProps[kkk]) {
379
+ throw ValidationError.invalidEmbeddableQuery(meta.class, kkk, sub.type);
380
+ }
381
+ inline(payload[sub.embedded[1]], sub.embeddedProps[kkk], [...path, sub.fieldNames[0]]);
396
382
  });
397
- if (!unknownProp) {
398
- delete data[prop.name];
399
- }
383
+ }
384
+ data[`${path.join('.')}.${sub.fieldNames[0]}`] = payload[sub.embedded[1]];
385
+ };
386
+ const parentPropName = kk.substring(0, kk.indexOf('.'));
387
+ // we might be using some native JSON operator, e.g. with mongodb's `$geoWithin` or `$exists`
388
+ if (props[kk]) {
389
+ /* v8 ignore next */
390
+ inline(data[prop.name], props[kk] || props[parentPropName], [prop.fieldNames[0]]);
391
+ } else if (props[parentPropName]) {
392
+ data[`${prop.fieldNames[0]}.${kk}`] = data[prop.name][kk];
393
+ } else {
394
+ unknownProp = true;
400
395
  }
396
+ } else if (props[kk]) {
397
+ data[props[kk].fieldNames[0]] = data[prop.name][props[kk].embedded[1]];
398
+ } else {
399
+ throw ValidationError.invalidEmbeddableQuery(meta.class, kk, prop.type);
400
+ }
401
401
  });
402
- }
403
- getPrimaryKeyFields(meta) {
404
- return meta.getPrimaryProps().flatMap(pk => pk.fieldNames);
405
- }
406
- createReplicas(cb) {
407
- const replicas = this.config.get('replicas', []);
408
- const ret = [];
409
- const props = [
410
- 'dbName',
411
- 'clientUrl',
412
- 'host',
413
- 'port',
414
- 'user',
415
- 'password',
416
- 'multipleStatements',
417
- 'pool',
418
- 'name',
419
- 'driverOptions',
420
- ];
421
- for (const conf of replicas) {
422
- const replicaConfig = Utils.copy(conf);
423
- for (const prop of props) {
424
- if (conf[prop]) {
425
- continue;
426
- }
427
- // do not copy options that can be inferred from explicitly provided `clientUrl`
428
- if (conf.clientUrl && ['clientUrl', 'host', 'port', 'user', 'password'].includes(prop)) {
429
- continue;
430
- }
431
- if (conf.clientUrl && prop === 'dbName' && new URL(conf.clientUrl).pathname) {
432
- continue;
433
- }
434
- replicaConfig[prop] = this.config.get(prop);
435
- }
436
- ret.push(cb(replicaConfig));
402
+ if (!unknownProp) {
403
+ delete data[prop.name];
437
404
  }
438
- return ret;
439
- }
440
- /** Acquires a pessimistic lock on the given entity. */
441
- async lockPessimistic(entity, options) {
442
- throw new Error(`Pessimistic locks are not supported by ${this.constructor.name} driver`);
443
- }
444
- /**
445
- * @inheritDoc
446
- */
447
- convertException(exception) {
448
- if (exception instanceof DriverException) {
449
- return exception;
405
+ }
406
+ });
407
+ }
408
+ getPrimaryKeyFields(meta) {
409
+ return meta.getPrimaryProps().flatMap(pk => pk.fieldNames);
410
+ }
411
+ createReplicas(cb) {
412
+ const replicas = this.config.get('replicas', []);
413
+ const ret = [];
414
+ const props = [
415
+ 'dbName',
416
+ 'clientUrl',
417
+ 'host',
418
+ 'port',
419
+ 'user',
420
+ 'password',
421
+ 'multipleStatements',
422
+ 'pool',
423
+ 'name',
424
+ 'driverOptions',
425
+ ];
426
+ for (const conf of replicas) {
427
+ const replicaConfig = Utils.copy(conf);
428
+ for (const prop of props) {
429
+ if (conf[prop]) {
430
+ continue;
431
+ }
432
+ // do not copy options that can be inferred from explicitly provided `clientUrl`
433
+ if (conf.clientUrl && ['clientUrl', 'host', 'port', 'user', 'password'].includes(prop)) {
434
+ continue;
450
435
  }
451
- return this.platform.getExceptionConverter().convertException(exception);
436
+ if (conf.clientUrl && prop === 'dbName' && new URL(conf.clientUrl).pathname) {
437
+ continue;
438
+ }
439
+ replicaConfig[prop] = this.config.get(prop);
440
+ }
441
+ ret.push(cb(replicaConfig));
452
442
  }
453
- rethrow(promise) {
454
- return promise.catch(e => {
455
- throw this.convertException(e);
456
- });
443
+ return ret;
444
+ }
445
+ /** Acquires a pessimistic lock on the given entity. */
446
+ async lockPessimistic(entity, options) {
447
+ throw new Error(`Pessimistic locks are not supported by ${this.constructor.name} driver`);
448
+ }
449
+ /**
450
+ * @inheritDoc
451
+ */
452
+ convertException(exception) {
453
+ if (exception instanceof DriverException) {
454
+ return exception;
457
455
  }
458
- /**
459
- * @internal
460
- */
461
- getTableName(meta, options, quote = true) {
462
- const schema = this.getSchemaName(meta, options);
463
- const tableName = schema && schema !== this.platform.getDefaultSchemaName() ? `${schema}.${meta.tableName}` : meta.tableName;
464
- if (quote) {
465
- return this.platform.quoteIdentifier(tableName);
466
- }
467
- return tableName;
456
+ return this.platform.getExceptionConverter().convertException(exception);
457
+ }
458
+ rethrow(promise) {
459
+ return promise.catch(e => {
460
+ throw this.convertException(e);
461
+ });
462
+ }
463
+ /**
464
+ * @internal
465
+ */
466
+ getTableName(meta, options, quote = true) {
467
+ const schema = this.getSchemaName(meta, options);
468
+ const tableName =
469
+ schema && schema !== this.platform.getDefaultSchemaName() ? `${schema}.${meta.tableName}` : meta.tableName;
470
+ if (quote) {
471
+ return this.platform.quoteIdentifier(tableName);
468
472
  }
469
- /**
470
- * @internal
471
- */
472
- getSchemaName(meta, options) {
473
- if (meta?.schema && meta.schema !== '*') {
474
- return meta.schema;
475
- }
476
- if (options?.schema === '*') {
477
- return this.config.get('schema');
478
- }
479
- const schemaName = meta?.schema === '*' ? this.config.getSchema() : meta?.schema;
480
- return options?.schema ?? options?.parentSchema ?? schemaName ?? this.config.getSchema();
473
+ return tableName;
474
+ }
475
+ /**
476
+ * @internal
477
+ */
478
+ getSchemaName(meta, options) {
479
+ if (meta?.schema && meta.schema !== '*') {
480
+ return meta.schema;
481
481
  }
482
- /** @internal */
483
- getORMClass() {
484
- return MikroORM;
482
+ if (options?.schema === '*') {
483
+ return this.config.get('schema');
485
484
  }
485
+ const schemaName = meta?.schema === '*' ? this.config.getSchema() : meta?.schema;
486
+ return options?.schema ?? options?.parentSchema ?? schemaName ?? this.config.getSchema();
487
+ }
488
+ /** @internal */
489
+ getORMClass() {
490
+ return MikroORM;
491
+ }
486
492
  }