@mikro-orm/core 7.3.0-dev.10 → 7.3.0-dev.12
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/entity/defineEntity.d.ts +8 -1
- package/entity/defineEntity.js +8 -0
- package/errors.d.ts +6 -0
- package/errors.js +12 -0
- package/metadata/types.d.ts +12 -0
- package/package.json +1 -1
- package/platforms/Platform.d.ts +2 -0
- package/platforms/Platform.js +18 -0
- package/types/DecimalType.js +34 -1
- package/typings.d.ts +2 -1
- package/utils/Utils.js +1 -1
package/entity/defineEntity.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EntityManager } from '../EntityManager.js';
|
|
2
|
-
import type { ColumnType, PropertyOptions, ReferenceOptions, EnumOptions, EmbeddedOptions, ManyToOneOptions, OneToManyOptions, OneToOneOptions, ManyToManyOptions, IndexColumnOptions } from '../metadata/types.js';
|
|
2
|
+
import type { ColumnType, PropertyOptions, ReferenceOptions, EnumOptions, EmbeddedOptions, ManyToOneOptions, OneToManyOptions, OneToOneOptions, ManyToManyOptions, IndexColumnOptions, SequenceOptions } from '../metadata/types.js';
|
|
3
3
|
import type { AnyString, GeneratedColumnCallback, Constructor, CheckCallback, FilterQuery, EntityName, Dictionary, EntityMetadata, PrimaryKeyProp, EntityRepositoryType, Hidden, Opt, Primary, EntityClass, EntitySchemaWithMeta, InferEntity, MaybeReturnType, Ref, LazyRef, IndexCallback, TriggerCallback, FormulaCallback, EntityCtor, IsNever, IWrappedEntity, DefineConfig, Config, MaybePromise, IndexHints, OptionalProps, ExtractDefineEntityProperties } from '../typings.js';
|
|
4
4
|
import type { Raw } from '../utils/RawQueryFragment.js';
|
|
5
5
|
import type { ScalarReference } from './Reference.js';
|
|
@@ -130,6 +130,7 @@ export interface PropertyChain<in out Value, in out Options> {
|
|
|
130
130
|
unique(unique?: boolean): PropertyChain<Value, Options>;
|
|
131
131
|
comment(comment: string): PropertyChain<Value, Options>;
|
|
132
132
|
collation(collation: string): PropertyChain<Value, Options>;
|
|
133
|
+
sequence(sequence: SequenceOptions | number): PropertyChain<Value, Options>;
|
|
133
134
|
accessor(accessor?: string | boolean): PropertyChain<Value, Options>;
|
|
134
135
|
eager(eager?: boolean): HasKind<Options, 'm:1' | '1:m' | '1:1' | 'm:n'> extends true ? PropertyChain<Value, Options> : never;
|
|
135
136
|
cascade(...cascade: Cascade[]): HasKind<Options, 'm:1' | '1:m' | '1:1' | 'm:n'> extends true ? PropertyChain<Value, Options> : never;
|
|
@@ -486,6 +487,12 @@ export declare class UniversalPropertyOptionsBuilder<in out Value, in out Option
|
|
|
486
487
|
* Emits a `COLLATE` clause on the column definition; the accepted collation names are dialect-specific.
|
|
487
488
|
*/
|
|
488
489
|
collation(collation: string): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
|
|
490
|
+
/**
|
|
491
|
+
* Set the start value and increment of an autoincrement column. (SQL only)
|
|
492
|
+
* A number is a shorthand for `{ startWith }`.
|
|
493
|
+
* Applied only when the column is created (and by `orm.schema.clear()`), never diffed by the schema generator.
|
|
494
|
+
*/
|
|
495
|
+
sequence(sequence: SequenceOptions | number): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
|
|
489
496
|
/** mysql only */
|
|
490
497
|
extra(extra: string): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
|
|
491
498
|
/**
|
package/entity/defineEntity.js
CHANGED
|
@@ -323,6 +323,14 @@ export class UniversalPropertyOptionsBuilder {
|
|
|
323
323
|
collation(collation) {
|
|
324
324
|
return this.assignOptions({ collation });
|
|
325
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Set the start value and increment of an autoincrement column. (SQL only)
|
|
328
|
+
* A number is a shorthand for `{ startWith }`.
|
|
329
|
+
* Applied only when the column is created (and by `orm.schema.clear()`), never diffed by the schema generator.
|
|
330
|
+
*/
|
|
331
|
+
sequence(sequence) {
|
|
332
|
+
return this.assignOptions({ sequence: typeof sequence === 'number' ? { startWith: sequence } : sequence });
|
|
333
|
+
}
|
|
326
334
|
/** mysql only */
|
|
327
335
|
extra(extra) {
|
|
328
336
|
return this.assignOptions({ extra });
|
package/errors.d.ts
CHANGED
|
@@ -91,6 +91,12 @@ export declare class MetadataError<T extends AnyEntity = AnyEntity> extends Vali
|
|
|
91
91
|
static triggersNotSupportedByDriver(meta: EntityMetadata): MetadataError;
|
|
92
92
|
/** Thrown when row level security is declared on an entity using a driver that does not support it. */
|
|
93
93
|
static rowLevelSecurityNotSupportedByDriver(meta: EntityMetadata): MetadataError;
|
|
94
|
+
/** Thrown when the `sequence` option is declared on a property that is not autoincrement. */
|
|
95
|
+
static sequenceWithoutAutoincrement(meta: EntityMetadata, prop: EntityProperty): MetadataError;
|
|
96
|
+
/** Thrown when the `sequence` option is combined with an identity option list in `generated`. */
|
|
97
|
+
static sequenceWithIdentityOptions(meta: EntityMetadata, prop: EntityProperty): MetadataError;
|
|
98
|
+
/** Thrown when `sequence.incrementBy` is declared on a platform without a per-column increment. */
|
|
99
|
+
static sequenceIncrementNotSupported(meta: EntityMetadata, prop: EntityProperty, platform: string): MetadataError;
|
|
94
100
|
/** Thrown when row level security is declared on a non-root entity of an STI hierarchy. */
|
|
95
101
|
static rowLevelSecurityOnNonRootStiEntity(meta: EntityMetadata): MetadataError;
|
|
96
102
|
/** Thrown when two policies on the same entity are given the same explicit name. */
|
package/errors.js
CHANGED
|
@@ -296,6 +296,18 @@ export class MetadataError extends ValidationError {
|
|
|
296
296
|
static rowLevelSecurityNotSupportedByDriver(meta) {
|
|
297
297
|
return new MetadataError(`Entity ${meta.className} declares row level security which is not supported by the current driver. Row level security is only available with the PostgreSQL driver. To test a PostgreSQL app without a server, use the \`@mikro-orm/pglite\` driver instead of sqlite.`);
|
|
298
298
|
}
|
|
299
|
+
/** Thrown when the `sequence` option is declared on a property that is not autoincrement. */
|
|
300
|
+
static sequenceWithoutAutoincrement(meta, prop) {
|
|
301
|
+
return MetadataError.fromMessage(meta, prop, `defines the 'sequence' option, but is not an autoincrement property`);
|
|
302
|
+
}
|
|
303
|
+
/** Thrown when the `sequence` option is combined with an identity option list in `generated`. */
|
|
304
|
+
static sequenceWithIdentityOptions(meta, prop) {
|
|
305
|
+
return MetadataError.fromMessage(meta, prop, `defines the 'sequence' option together with identity options in 'generated', use only one of them`);
|
|
306
|
+
}
|
|
307
|
+
/** Thrown when `sequence.incrementBy` is declared on a platform without a per-column increment. */
|
|
308
|
+
static sequenceIncrementNotSupported(meta, prop, platform) {
|
|
309
|
+
return MetadataError.fromMessage(meta, prop, `defines 'sequence.incrementBy', but ${platform} does not support a per-column increment`);
|
|
310
|
+
}
|
|
299
311
|
/** Thrown when row level security is declared on a non-root entity of an STI hierarchy. */
|
|
300
312
|
static rowLevelSecurityOnNonRootStiEntity(meta) {
|
|
301
313
|
return new MetadataError(`Entity ${meta.className} declares row level security, but it is part of a single table inheritance hierarchy. Declare policies on the root entity ${meta.root.className} instead, as the whole hierarchy shares a single table.`);
|
package/metadata/types.d.ts
CHANGED
|
@@ -176,6 +176,12 @@ export interface PropertyOptions<Owner> {
|
|
|
176
176
|
* Explicitly specify the auto increment of the primary key.
|
|
177
177
|
*/
|
|
178
178
|
autoincrement?: boolean;
|
|
179
|
+
/**
|
|
180
|
+
* Start value and increment of an autoincrement column. (SQL only)
|
|
181
|
+
* Applied only when the column is created (and by `orm.schema.clear()`), never diffed by the schema generator.
|
|
182
|
+
* `incrementBy` is not supported on MySQL, MariaDB and SQLite.
|
|
183
|
+
*/
|
|
184
|
+
sequence?: SequenceOptions;
|
|
179
185
|
/**
|
|
180
186
|
* Add the property to the `returning` clause of inserts, updates and upserts, reloading the database value into the entity.
|
|
181
187
|
*/
|
|
@@ -587,6 +593,12 @@ export interface EnumOptions<T> extends PropertyOptions<T> {
|
|
|
587
593
|
/** for postgres, by default it uses text column with check constraint */
|
|
588
594
|
nativeEnumName?: string;
|
|
589
595
|
}
|
|
596
|
+
export interface SequenceOptions {
|
|
597
|
+
/** The first value the autoincrement column generates. */
|
|
598
|
+
startWith?: number;
|
|
599
|
+
/** The step between generated values. Not supported on MySQL, MariaDB and SQLite. */
|
|
600
|
+
incrementBy?: number;
|
|
601
|
+
}
|
|
590
602
|
export interface PrimaryKeyOptions<T> extends PropertyOptions<T> {
|
|
591
603
|
}
|
|
592
604
|
export interface SerializedPrimaryKeyOptions<T> extends PropertyOptions<T> {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.3.0-dev.
|
|
3
|
+
"version": "7.3.0-dev.12",
|
|
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",
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -325,6 +325,8 @@ export declare abstract class Platform {
|
|
|
325
325
|
supportsDownMigrations(): boolean;
|
|
326
326
|
/** Whether the platform supports deferred unique constraints. */
|
|
327
327
|
supportsDeferredUniqueConstraints(): boolean;
|
|
328
|
+
/** Whether autoincrement columns support a per-column increment (`sequence.incrementBy`). */
|
|
329
|
+
supportsAutoincrementIncrement(): boolean;
|
|
328
330
|
/** Whether the platform supports row level security (PostgreSQL). */
|
|
329
331
|
supportsRowLevelSecurity(): boolean;
|
|
330
332
|
/** Whether the driver can apply the session context on every pooled connection acquire (`sessionContext: 'connection'`). */
|
package/platforms/Platform.js
CHANGED
|
@@ -738,6 +738,10 @@ export class Platform {
|
|
|
738
738
|
supportsDeferredUniqueConstraints() {
|
|
739
739
|
return true;
|
|
740
740
|
}
|
|
741
|
+
/** Whether autoincrement columns support a per-column increment (`sequence.incrementBy`). */
|
|
742
|
+
supportsAutoincrementIncrement() {
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
741
745
|
/** Whether the platform supports row level security (PostgreSQL). */
|
|
742
746
|
supportsRowLevelSecurity() {
|
|
743
747
|
return false;
|
|
@@ -758,6 +762,20 @@ export class Platform {
|
|
|
758
762
|
if (meta.partitionBy && !this.supportsPartitionedTables()) {
|
|
759
763
|
throw new MetadataError(`Entity ${meta.className} uses partitionBy, but ${this.constructor.name} does not support partitioned tables`);
|
|
760
764
|
}
|
|
765
|
+
for (const prop of Object.values(meta.properties)) {
|
|
766
|
+
if (!prop.sequence) {
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
if (!prop.autoincrement) {
|
|
770
|
+
throw MetadataError.sequenceWithoutAutoincrement(meta, prop);
|
|
771
|
+
}
|
|
772
|
+
if (typeof prop.generated === 'string' && /identity\s*\(/i.test(prop.generated)) {
|
|
773
|
+
throw MetadataError.sequenceWithIdentityOptions(meta, prop);
|
|
774
|
+
}
|
|
775
|
+
if (prop.sequence.incrementBy != null && !this.supportsAutoincrementIncrement()) {
|
|
776
|
+
throw MetadataError.sequenceIncrementNotSupported(meta, prop, this.constructor.name);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
761
779
|
const declaresRls = meta.policies.length > 0 || !!meta.rowLevelSecurity;
|
|
762
780
|
if (declaresRls && !this.supportsRowLevelSecurity()) {
|
|
763
781
|
throw MetadataError.rowLevelSecurityNotSupportedByDriver(meta);
|
package/types/DecimalType.js
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import { Type } from './Type.js';
|
|
2
|
+
/** Scales a plain decimal string to an integer rounded half away from zero at `scale`, like the DB does. */
|
|
3
|
+
function toScaledInteger(value, scale) {
|
|
4
|
+
if (typeof value !== 'string') {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
const negative = value.startsWith('-');
|
|
8
|
+
const [int, fraction = ''] = (negative ? value.slice(1) : value).split('.');
|
|
9
|
+
const digits = int + fraction;
|
|
10
|
+
for (let i = 0; i < digits.length; i++) {
|
|
11
|
+
const code = digits.charCodeAt(i);
|
|
12
|
+
if (code < 48 || code > 57) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
let scaled = BigInt('0' + int + fraction.slice(0, scale).padEnd(scale, '0'));
|
|
17
|
+
if (fraction.charCodeAt(scale) >= 53) {
|
|
18
|
+
scaled++;
|
|
19
|
+
}
|
|
20
|
+
return negative ? -scaled : scaled;
|
|
21
|
+
}
|
|
2
22
|
/**
|
|
3
23
|
* Type that maps an SQL DECIMAL to a JS string or number.
|
|
4
24
|
*/
|
|
@@ -16,7 +36,20 @@ export class DecimalType extends Type {
|
|
|
16
36
|
return String(value);
|
|
17
37
|
}
|
|
18
38
|
compareValues(a, b) {
|
|
19
|
-
|
|
39
|
+
if (a === b) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
const scale = this.prop?.scale;
|
|
43
|
+
if (this.platform.formatDecimal(a, scale) !== this.platform.formatDecimal(b, scale)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
// doubles are exact only up to 15 significant digits, so only higher precision strings can differ past the numeric check
|
|
47
|
+
if ((this.prop?.precision ?? 0) <= 15 || this.compareAsType() !== 'string') {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
const scaledA = toScaledInteger(a, scale ?? 0);
|
|
51
|
+
const scaledB = toScaledInteger(b, scale ?? 0);
|
|
52
|
+
return scaledA == null || scaledB == null || scaledA === scaledB;
|
|
20
53
|
}
|
|
21
54
|
getColumnType(prop, platform) {
|
|
22
55
|
return platform.getDecimalTypeDeclarationSQL(prop);
|
package/typings.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { SerializeOptions } from './serialization/EntitySerializer.js';
|
|
|
12
12
|
import type { MetadataStorage } from './metadata/MetadataStorage.js';
|
|
13
13
|
import type { Routine } from './metadata/Routine.js';
|
|
14
14
|
import type { EntitySchema } from './metadata/EntitySchema.js';
|
|
15
|
-
import type { EntityPartitionBy, IndexColumnOptions } from './metadata/types.js';
|
|
15
|
+
import type { EntityPartitionBy, IndexColumnOptions, SequenceOptions } from './metadata/types.js';
|
|
16
16
|
import type { Type, types } from './types/index.js';
|
|
17
17
|
import type { Platform } from './platforms/Platform.js';
|
|
18
18
|
import type { Configuration } from './utils/Configuration.js';
|
|
@@ -986,6 +986,7 @@ export interface EntityProperty<Owner = any, Target = any> {
|
|
|
986
986
|
hasConvertToJSValueSQL: boolean;
|
|
987
987
|
hasConvertToDatabaseValueSQL: boolean;
|
|
988
988
|
autoincrement?: boolean;
|
|
989
|
+
sequence?: SequenceOptions;
|
|
989
990
|
returning?: boolean;
|
|
990
991
|
primary?: boolean;
|
|
991
992
|
serializedPrimaryKey: boolean;
|
package/utils/Utils.js
CHANGED
|
@@ -153,7 +153,7 @@ export function parseJsonSafe(value) {
|
|
|
153
153
|
/** Collection of general-purpose utility methods used throughout the ORM. */
|
|
154
154
|
export class Utils {
|
|
155
155
|
static PK_SEPARATOR = '~~~';
|
|
156
|
-
static #ORM_VERSION = '7.3.0-dev.
|
|
156
|
+
static #ORM_VERSION = '7.3.0-dev.12';
|
|
157
157
|
/** Default session variable name backing an RLS filter argument (`current_setting('mikro.<filter>.<arg>')`). */
|
|
158
158
|
static getRlsSettingName(filterName, argName) {
|
|
159
159
|
return `mikro.${filterName}.${argName}`;
|