@mikro-orm/sql 7.3.0-dev.10 → 7.3.0-dev.11

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.
@@ -37,6 +37,7 @@ export declare class BaseMySqlPlatform extends AbstractSqlPlatform {
37
37
  getDefaultMappedType(type: string): Type<unknown>;
38
38
  isNumericColumn(mappedType: Type<unknown>): boolean;
39
39
  supportsUnsigned(): boolean;
40
+ supportsAutoincrementIncrement(): boolean;
40
41
  /** MySQL/MariaDB identifier limit. */
41
42
  getMaxIdentifierLength(): number;
42
43
  getIndexName(tableName: string, columns: string[], type: 'index' | 'unique' | 'foreign' | 'primary' | 'sequence' | 'check'): string;
@@ -90,6 +90,9 @@ export class BaseMySqlPlatform extends AbstractSqlPlatform {
90
90
  supportsUnsigned() {
91
91
  return true;
92
92
  }
93
+ supportsAutoincrementIncrement() {
94
+ return false;
95
+ }
93
96
  /** MySQL/MariaDB identifier limit. */
94
97
  getMaxIdentifierLength() {
95
98
  return 64;
@@ -20,6 +20,8 @@ export declare class MySqlSchemaHelper extends SchemaHelper {
20
20
  tableExists(connection: AbstractSqlConnection, tableName: string, schemaName: string | undefined, ctx?: Transaction): Promise<boolean>;
21
21
  disableForeignKeysSQL(): string;
22
22
  enableForeignKeysSQL(): string;
23
+ getResetSequenceSQL(tableName: string, schemaName: string | undefined, columnName: string, startWith: number): string;
24
+ getAddColumnsSQL(table: DatabaseTable, columns: Column[]): string[];
23
25
  finalizeTable(table: DatabaseTable, charset: string, collate?: string): string;
24
26
  getListTablesSQL(): string;
25
27
  getListViewsSQL(): string;
@@ -42,12 +42,25 @@ export class MySqlSchemaHelper extends SchemaHelper {
42
42
  enableForeignKeysSQL() {
43
43
  return 'set foreign_key_checks = 1;';
44
44
  }
45
+ getResetSequenceSQL(tableName, schemaName, columnName, startWith) {
46
+ return `alter table ${this.quote(this.getTableName(tableName, schemaName))} auto_increment = ${startWith}`;
47
+ }
48
+ getAddColumnsSQL(table, columns) {
49
+ const [sql, ...rest] = super.getAddColumnsSQL(table, columns);
50
+ const startWith = columns.find(column => column.autoincrement)?.sequence?.startWith;
51
+ // the table option numbers the existing rows of the added column from the declared start too
52
+ return [startWith != null ? `${sql}, auto_increment = ${startWith}` : sql, ...rest];
53
+ }
45
54
  finalizeTable(table, charset, collate) {
46
55
  let sql = ` default character set ${charset}`;
47
56
  if (collate) {
48
57
  sql += ` collate ${collate}`;
49
58
  }
50
59
  sql += ' engine = InnoDB';
60
+ const startWith = table.getColumns().find(column => column.autoincrement)?.sequence?.startWith;
61
+ if (startWith != null) {
62
+ sql += ` auto_increment = ${startWith}`;
63
+ }
51
64
  if (table.comment) {
52
65
  sql += ` comment = ${this.platform.quoteValue(table.comment)}`;
53
66
  }
@@ -29,6 +29,7 @@ export declare class PostgreSqlSchemaHelper extends SchemaHelper {
29
29
  loadMaterializedViews(schema: DatabaseSchema, connection: AbstractSqlConnection, schemaName?: string, ctx?: Transaction): Promise<void>;
30
30
  createMaterializedView(name: string, schema: string | undefined, definition: string, withData?: boolean): string;
31
31
  createTable(table: DatabaseTable, alter?: boolean): string[];
32
+ getResetSequenceSQL(tableName: string, schemaName: string | undefined, columnName: string, startWith: number): string;
32
33
  dropMaterializedViewIfExists(name: string, schema?: string): string;
33
34
  refreshMaterializedView(name: string, schema?: string, concurrently?: boolean): string;
34
35
  getNamespaces(connection: AbstractSqlConnection, ctx?: Transaction): Promise<string[]>;
@@ -134,6 +135,7 @@ export declare class PostgreSqlSchemaHelper extends SchemaHelper {
134
135
  castColumn(name: string, type: string): string;
135
136
  dropForeignKey(tableName: string, constraintName: string): string;
136
137
  getPostAlterTable(tableDiff: TableDifference, safe: boolean): string[];
138
+ getAddColumnsSQL(table: DatabaseTable, columns: Column[]): string[];
137
139
  private getAlterColumnAutoincrement;
138
140
  getChangeColumnCommentSQL(tableName: string, to: Column, schemaName?: string): string;
139
141
  alterTableComment(table: DatabaseTable, comment?: string): string;
@@ -106,10 +106,23 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
106
106
  }
107
107
  createTable(table, alter) {
108
108
  const partitioning = table.getPartitioning();
109
+ const [createTable, ...rest] = super.createTable(table, alter);
110
+ // `serial` columns can't declare sequence options inline, so alter the implicit sequence right after creating the table
111
+ const sequences = table
112
+ .getColumns()
113
+ .filter(column => column.autoincrement && !column.generated && this.getSequenceOptionsSQL(column))
114
+ .map(column => {
115
+ const sequence = `pg_get_serial_sequence(${this.platform.quoteValue(table.getQuotedName())}, ${this.platform.quoteValue(column.name)})`;
116
+ const { startWith = -1, incrementBy = 1 } = column.sequence;
117
+ // `alter sequence` keeps the ascending bounds of the serial, so a descending one gets the bounds and start of a fresh sequence
118
+ const options = incrementBy < 0
119
+ ? `no minvalue maxvalue ${Math.max(startWith, -1)} start with ${startWith} increment by ${incrementBy}`
120
+ : this.getSequenceOptionsSQL(column);
121
+ return `do $$ begin execute format('alter sequence %s ${options} restart', ${sequence}); end $$`;
122
+ });
109
123
  if (!partitioning) {
110
- return super.createTable(table, alter);
124
+ return [createTable, ...sequences, ...rest];
111
125
  }
112
- const [createTable, ...rest] = super.createTable(table, alter);
113
126
  const partitions = partitioning.partitions.map(partition => {
114
127
  const partitionName = this.quote(this.getTableName(partition.name, partition.schema ?? table.schema));
115
128
  return `create table ${partitionName} partition of ${table.getQuotedName()} ${partition.bound}`;
@@ -119,7 +132,12 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
119
132
  // regex replacement tokens like `$$`, `$&`, or `$1` inside user-supplied expressions (e.g., a
120
133
  // callback that returns a dollar-quoted literal) are not interpreted as back-references.
121
134
  const spliced = `${createTable.slice(0, -1)} partition by ${partitioning.definition};`;
122
- return [spliced, ...rest, ...partitions];
135
+ return [spliced, ...sequences, ...rest, ...partitions];
136
+ }
137
+ getResetSequenceSQL(tableName, schemaName, columnName, startWith) {
138
+ const table = this.platform.quoteValue(this.quote(this.getTableName(tableName, schemaName)));
139
+ // `truncate … restart identity` goes back to the start the sequence was created with, which the metadata may not match
140
+ return `select setval(pg_get_serial_sequence(${table}, ${this.platform.quoteValue(columnName)}), ${startWith}, false)`;
123
141
  }
124
142
  dropMaterializedViewIfExists(name, schema) {
125
143
  return `drop materialized view if exists ${this.quote(this.getTableName(name, schema))} cascade`;
@@ -387,15 +405,16 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
387
405
  data_type,
388
406
  is_identity,
389
407
  identity_generation,
390
- identity_start,
391
- identity_increment,
392
408
  generation_expression,
393
409
  pg_catalog.col_description(pgc.oid, cols.ordinal_position::int) column_comment,
394
- coll.collname as collation_name
410
+ coll.collname as collation_name,
411
+ seq.seqstart as sequence_start,
412
+ seq.seqincrement as sequence_increment
395
413
  from information_schema.columns cols
396
414
  join pg_class pgc on cols.table_name = pgc.relname
397
415
  join pg_attribute pga on pgc.oid = pga.attrelid and cols.column_name = pga.attname
398
416
  left join pg_collation coll on pga.attcollation = coll.oid and coll.collname <> 'default'
417
+ left join pg_sequence seq on seq.seqrelid = pg_get_serial_sequence(quote_ident(cols.table_schema) || '.' || quote_ident(cols.table_name), cols.column_name)::regclass
399
418
  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 ')})
400
419
  order by ordinal_position`;
401
420
  const allColumns = await connection.execute(sql, [], 'all', ctx);
@@ -435,14 +454,6 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
435
454
  type += `(${col.numeric_precision},${col.numeric_scale})`;
436
455
  }
437
456
  const length = this.inferLengthFromColumnType(type) === -1 ? -1 : col.length;
438
- // a descending sequence starts at -1 by default
439
- const defaultIdentityStart = col.identity_increment?.startsWith('-') ? '-1' : '1';
440
- // read back non-default identity options, so `identity (start with 1000)` does not diff against plain `identity`
441
- const identityOptions = [
442
- col.identity_start !== defaultIdentityStart && `start with ${col.identity_start}`,
443
- col.identity_increment !== '1' && `increment by ${col.identity_increment}`,
444
- ].filter(Boolean);
445
- const identitySuffix = identityOptions.length > 0 ? ` (${identityOptions.join(' ')})` : '';
446
457
  const column = {
447
458
  name: col.column_name,
448
459
  type,
@@ -454,8 +465,11 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
454
465
  default: str(this.normalizeDefaultValue(col.column_default, col.length)),
455
466
  unsigned: increments,
456
467
  autoincrement: increments,
468
+ sequence: increments ? this.getIntrospectedSequence(col.sequence_start, col.sequence_increment) : undefined,
457
469
  generated: col.is_identity === 'YES'
458
- ? (col.identity_generation === 'BY DEFAULT' ? 'by default as identity' : 'identity') + identitySuffix
470
+ ? col.identity_generation === 'BY DEFAULT'
471
+ ? 'by default as identity'
472
+ : 'identity'
459
473
  : col.generation_expression
460
474
  ? col.generation_expression + ' stored'
461
475
  : undefined,
@@ -1040,11 +1054,15 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
1040
1054
  columnType = this.quote(columnType);
1041
1055
  }
1042
1056
  }
1043
- if (column.generated?.startsWith('by default as identity')) {
1044
- columnType += ` generated ${column.generated}`;
1057
+ const sequenceOptions = this.getSequenceOptionsSQL(column);
1058
+ const generated = sequenceOptions && /^(by default as )?identity$/.test(column.generated ?? '')
1059
+ ? `${column.generated} (${sequenceOptions})`
1060
+ : column.generated;
1061
+ if (generated?.startsWith('by default as identity')) {
1062
+ columnType += ` generated ${generated}`;
1045
1063
  }
1046
- else if (column.generated) {
1047
- columnType += ` generated always as ${column.generated}`;
1064
+ else if (generated) {
1065
+ columnType += ` generated always as ${generated}`;
1048
1066
  }
1049
1067
  col.push(columnType);
1050
1068
  Utils.runIfNotEmpty(() => col.push(this.getCollateSQL(column.collation)), column.collation);
@@ -1201,14 +1219,50 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
1201
1219
  }
1202
1220
  return ret;
1203
1221
  }
1222
+ getAddColumnsSQL(table, columns) {
1223
+ const compositePK = table.getPrimaryKey()?.composite;
1224
+ const before = [];
1225
+ const after = [];
1226
+ const adds = columns.map(column => {
1227
+ const sequenceOptions = this.getSequenceOptionsSQL(column);
1228
+ if (!sequenceOptions || !column.autoincrement || column.generated) {
1229
+ return column;
1230
+ }
1231
+ // a `serial` column numbers the existing rows right away, so expand it to a sequence created with the options upfront
1232
+ const seqName = this.quote(this.getTableName(this.platform.getIndexName(table.name, [column.name], 'sequence'), table.schema));
1233
+ before.push(`create sequence ${seqName} ${sequenceOptions}`);
1234
+ after.push(`alter sequence ${seqName} owned by ${table.getQuotedName()}.${this.quote(column.name)}`);
1235
+ // the expanded column has no inline `primary key`, which `alterTable` expects from an added autoincrement PK
1236
+ if (column.primary && !compositePK && !this.hasNonDefaultPrimaryKeyName(table)) {
1237
+ after.push(`alter table ${table.getQuotedName()} add primary key (${this.quote(column.name)})`);
1238
+ }
1239
+ return {
1240
+ ...column,
1241
+ type: column.mappedType.getColumnType({ autoincrement: false }, this.platform),
1242
+ autoincrement: false,
1243
+ nullable: false,
1244
+ default: `nextval('${seqName}')`,
1245
+ };
1246
+ });
1247
+ return [...before, ...super.getAddColumnsSQL(table, adds), ...after];
1248
+ }
1204
1249
  getAlterColumnAutoincrement(tableName, column, schemaName) {
1205
1250
  const ret = [];
1206
1251
  /* v8 ignore next */
1207
1252
  const name = (schemaName && schemaName !== this.platform.getDefaultSchemaName() ? schemaName + '.' : '') + tableName;
1208
1253
  if (column.autoincrement) {
1209
1254
  const seqName = this.platform.getIndexName(tableName, [column.name], 'sequence');
1210
- ret.push(`create sequence if not exists ${this.quote(seqName)}`);
1211
- ret.push(`select setval('${seqName}', (select max(${this.quote(column.name)}) from ${this.quote(name)}))`);
1255
+ const sequenceOptions = this.getSequenceOptionsSQL(column);
1256
+ const { incrementBy = 1, startWith = incrementBy < 0 ? -1 : 1 } = column.sequence ?? {};
1257
+ const lastValue = `(select ${incrementBy < 0 ? 'min' : 'max'}(${this.quote(column.name)}) from ${this.quote(name)})`;
1258
+ ret.push(`create sequence if not exists ${this.quote(seqName)}${sequenceOptions ? ` ${sequenceOptions}` : ''}`);
1259
+ if (sequenceOptions) {
1260
+ // continue after the existing values, but never before the declared start
1261
+ ret.push(`select setval('${seqName}', ${incrementBy < 0 ? 'least' : 'greatest'}(${lastValue} + ${incrementBy}, ${startWith}), false)`);
1262
+ }
1263
+ else {
1264
+ ret.push(`select setval('${seqName}', ${lastValue})`);
1265
+ }
1212
1266
  ret.push(`alter table ${this.quote(name)} alter column ${this.quote(column.name)} set default nextval('${seqName}')`);
1213
1267
  }
1214
1268
  return ret;
@@ -14,6 +14,7 @@ export declare class SqlitePlatform extends AbstractSqlPlatform {
14
14
  usesReturningStatement(): boolean;
15
15
  usesEnumCheckConstraints(): boolean;
16
16
  supportsComments(): boolean;
17
+ supportsAutoincrementIncrement(): boolean;
17
18
  getCurrentTimestampSQL(length: number): string;
18
19
  getDateTimeTypeDeclarationSQL(column: {
19
20
  length: number;
@@ -26,6 +26,9 @@ export class SqlitePlatform extends AbstractSqlPlatform {
26
26
  supportsComments() {
27
27
  return false;
28
28
  }
29
+ supportsAutoincrementIncrement() {
30
+ return false;
31
+ }
29
32
  getCurrentTimestampSQL(length) {
30
33
  return `(strftime('%s', 'now') * 1000)`;
31
34
  }
@@ -21,6 +21,7 @@ export declare class SqliteSchemaHelper extends SchemaHelper {
21
21
  getDropDatabaseSQL(name: string): string;
22
22
  loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[], schemas?: string[], ctx?: Transaction): Promise<void>;
23
23
  createTable(table: DatabaseTable, alter?: boolean): string[];
24
+ getResetSequenceSQL(tableName: string, schemaName: string | undefined, columnName: string, startWith: number): string;
24
25
  createTableColumn(column: Column, table: DatabaseTable, _changedProperties?: Set<string>): string | undefined;
25
26
  getAddColumnsSQL(table: DatabaseTable, columns: Column[], diff?: TableDifference): string[];
26
27
  dropForeignKey(tableName: string, constraintName: string): string;
@@ -144,6 +144,13 @@ export class SqliteSchemaHelper extends SchemaHelper {
144
144
  }
145
145
  const ret = [];
146
146
  this.append(ret, sql);
147
+ const startWith = columns.find(column => column.autoincrement)?.sequence?.startWith;
148
+ if (startWith != null) {
149
+ // a table rebuild renames the counter row of the temp table over, so only seed it when missing
150
+ const sequenceTable = this.quote(this.getTableName('sqlite_sequence', table.schema));
151
+ const name = this.platform.quoteValue(table.name);
152
+ this.append(ret, `insert into ${sequenceTable} (name, seq) select ${name}, ${startWith - 1} where not exists (select 1 from ${sequenceTable} where name = ${name})`);
153
+ }
147
154
  for (const index of table.getIndexes()) {
148
155
  this.append(ret, this.createIndex(index, table));
149
156
  }
@@ -152,6 +159,12 @@ export class SqliteSchemaHelper extends SchemaHelper {
152
159
  }
153
160
  return ret;
154
161
  }
162
+ getResetSequenceSQL(tableName, schemaName, columnName, startWith) {
163
+ const sequenceTable = this.quote(this.getTableName('sqlite_sequence', schemaName));
164
+ const name = this.platform.quoteValue(tableName);
165
+ // the counter row does not exist before the first insert when the table was created without `sequence`
166
+ return `delete from ${sequenceTable} where name = ${name};\ninsert into ${sequenceTable} (name, seq) values (${name}, ${startWith - 1})`;
167
+ }
155
168
  createTableColumn(column, table, _changedProperties) {
156
169
  const col = [this.quote(column.name)];
157
170
  const checks = table.getChecks();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.3.0-dev.10",
3
+ "version": "7.3.0-dev.11",
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",
@@ -53,7 +53,7 @@
53
53
  "@mikro-orm/core": "^7.2.2"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.3.0-dev.10"
56
+ "@mikro-orm/core": "7.3.0-dev.11"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"
@@ -155,6 +155,7 @@ export class DatabaseTable {
155
155
  comment: prop.comment,
156
156
  collation: prop.collation,
157
157
  extra: prop.extra,
158
+ sequence: prop.sequence,
158
159
  ignoreSchemaChanges: prop.ignoreSchemaChanges,
159
160
  };
160
161
  this.#columns[field].unsigned ??= this.#columns[field].autoincrement;
@@ -796,6 +797,7 @@ export class DatabaseTable {
796
797
  nullable: column.nullable,
797
798
  primary: column.primary && persist,
798
799
  autoincrement: column.autoincrement,
800
+ sequence: column.sequence,
799
801
  fieldName: column.name,
800
802
  unsigned: column.unsigned,
801
803
  length: column.length,
@@ -708,7 +708,9 @@ export class SchemaComparator {
708
708
  log(`'nullable' changed for column ${fromTable.name}.${fromColumn.name}`, { fromColumn, toColumn });
709
709
  changedProperties.add('nullable');
710
710
  }
711
- if (this.diffExpression(fromColumn.generated, toColumn.generated)) {
711
+ // identity options (start/increment) are applied on create only, same as the `sequence` option
712
+ const withoutIdentityOptions = (generated) => generated?.replace(/^((?:by default as )?identity)\s*\(.*\)$/is, '$1');
713
+ if (this.diffExpression(withoutIdentityOptions(fromColumn.generated), withoutIdentityOptions(toColumn.generated))) {
712
714
  log(`'generated' changed for column ${fromTable.name}.${fromColumn.name}`, { fromColumn, toColumn });
713
715
  changedProperties.add('generated');
714
716
  }
@@ -1,4 +1,4 @@
1
- import { type Connection, type Dictionary, type Options, type Transaction, type RawQueryFragment } from '@mikro-orm/core';
1
+ import { type Connection, type Dictionary, type Options, type Transaction, type RawQueryFragment, type SequenceOptions } from '@mikro-orm/core';
2
2
  import type { AbstractSqlConnection } from '../AbstractSqlConnection.js';
3
3
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
4
4
  import type { CheckDef, Column, ForeignKey, IndexDef, Table, TableDifference, SqlTriggerDef, SqlRoutineDef } from '../typings.js';
@@ -45,6 +45,12 @@ export declare abstract class SchemaHelper {
45
45
  resolveMigrationSchema(schema: string | undefined): string | undefined;
46
46
  finalizeTable(table: DatabaseTable, charset: string, collate?: string): string;
47
47
  appendComments(table: DatabaseTable): string[];
48
+ /** Returns SQL that moves the autoincrement counter back to `sequence.startWith` after `clear()` truncated the table. */
49
+ getResetSequenceSQL(tableName: string, schemaName: string | undefined, columnName: string, startWith: number): string;
50
+ /** Maps the introspected start and increment of an autoincrement column to its `sequence` option, omitting defaults. */
51
+ protected getIntrospectedSequence(start: unknown, increment: unknown): SequenceOptions | undefined;
52
+ /** Renders the `start with … increment by …` clause for the `sequence` option of an autoincrement column. */
53
+ protected getSequenceOptionsSQL(column: Column): string;
48
54
  supportsSchemaConstraints(): boolean;
49
55
  getPrimaryKeys(connection: AbstractSqlConnection, indexes: IndexDef[] | undefined, tableName: string, schemaName?: string): Promise<string[]>;
50
56
  inferLengthFromColumnType(type: string): number | undefined;
@@ -91,6 +91,38 @@ export class SchemaHelper {
91
91
  appendComments(table) {
92
92
  return [];
93
93
  }
94
+ /** Returns SQL that moves the autoincrement counter back to `sequence.startWith` after `clear()` truncated the table. */
95
+ /* v8 ignore next */
96
+ getResetSequenceSQL(tableName, schemaName, columnName, startWith) {
97
+ return '';
98
+ }
99
+ /** Maps the introspected start and increment of an autoincrement column to its `sequence` option, omitting defaults. */
100
+ getIntrospectedSequence(start, increment) {
101
+ if (start == null) {
102
+ return undefined;
103
+ }
104
+ const incrementBy = Number(increment ?? 1);
105
+ const startWith = Number(start);
106
+ const sequence = {};
107
+ if (startWith !== (incrementBy < 0 ? -1 : 1)) {
108
+ sequence.startWith = startWith;
109
+ }
110
+ if (incrementBy !== 1) {
111
+ sequence.incrementBy = incrementBy;
112
+ }
113
+ return Utils.hasObjectKeys(sequence) ? sequence : undefined;
114
+ }
115
+ /** Renders the `start with … increment by …` clause for the `sequence` option of an autoincrement column. */
116
+ getSequenceOptionsSQL(column) {
117
+ const { startWith, incrementBy } = column.sequence ?? {};
118
+ const descending = incrementBy != null && incrementBy < 0;
119
+ // a sequence is bounded by 1 (ascending) or -1 (descending) by default, a start beyond that has to move the bound
120
+ const bound = startWith != null &&
121
+ (descending ? startWith > -1 && `maxvalue ${startWith}` : startWith < 1 && `minvalue ${startWith}`);
122
+ return [startWith != null && `start with ${startWith}`, incrementBy != null && `increment by ${incrementBy}`, bound]
123
+ .filter(Boolean)
124
+ .join(' ');
125
+ }
94
126
  supportsSchemaConstraints() {
95
127
  return true;
96
128
  }
@@ -141,6 +141,14 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
141
141
  .withSchema(schema)
142
142
  .truncate()
143
143
  .execute();
144
+ // the counters of a TPT child's inherited columns (PK included) belong to the parent table
145
+ const props = meta.tptParent ? (meta.ownProps ?? []) : meta.props;
146
+ for (const prop of props.filter(prop => prop.autoincrement && prop.sequence?.startWith != null)) {
147
+ const sql = this.helper.getResetSequenceSQL(meta.tableName, this.getSchemaName(meta, { schema }), prop.fieldNames[0], prop.sequence.startWith);
148
+ if (sql) {
149
+ await this.execute(sql, { ctx: this.em?.getTransactionContext() });
150
+ }
151
+ }
144
152
  }
145
153
  catch (e) {
146
154
  if (this.platform.getExceptionConverter().convertException(e) instanceof TableNotFoundException) {
package/typings.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Generated, Kysely } from 'kysely';
2
- import type { CheckCallback, DeferMode, Dictionary, EntityName, EntityMetadata, EntityProperty, EntitySchemaWithMeta, ExtractDefineEntityProperties, FilterQuery, GroupOperator, IndexColumnOptions, InferEntityName, Opt, Primary, PrimaryProperty, QueryFlag, QueryOrderMap, RawQueryFragment, RoutineIgnoreField, Scalar, Type } from '@mikro-orm/core';
2
+ import type { CheckCallback, DeferMode, Dictionary, EntityName, EntityMetadata, EntityProperty, EntitySchemaWithMeta, ExtractDefineEntityProperties, FilterQuery, GroupOperator, IndexColumnOptions, InferEntityName, Opt, Primary, PrimaryProperty, QueryFlag, QueryOrderMap, RawQueryFragment, RoutineIgnoreField, Scalar, SequenceOptions, Type } from '@mikro-orm/core';
3
3
  import type { JoinType, QueryType } from './query/enums.js';
4
4
  import type { DatabaseSchema } from './schema/DatabaseSchema.js';
5
5
  import type { DatabaseTable } from './schema/DatabaseTable.js';
@@ -37,6 +37,8 @@ export interface Column {
37
37
  mappedType: Type<unknown>;
38
38
  unsigned?: boolean;
39
39
  autoincrement?: boolean;
40
+ /** applied only when the column is created, never diffed */
41
+ sequence?: SequenceOptions;
40
42
  nullable?: boolean;
41
43
  length?: number;
42
44
  precision?: number;