@mikro-orm/mariadb 7.0.3 → 7.0.4-dev.1

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.
@@ -1,29 +1,13 @@
1
- import {
2
- type AnyEntity,
3
- type Configuration,
4
- type ConnectionType,
5
- type LoggingOptions,
6
- type Transaction,
7
- type Constructor,
8
- type EntityName,
9
- } from '@mikro-orm/core';
1
+ import { type AnyEntity, type Configuration, type ConnectionType, type LoggingOptions, type Transaction, type Constructor, type EntityName } from '@mikro-orm/core';
10
2
  import { MySqlDriver, type SqlEntityManager } from '@mikro-orm/mysql';
11
3
  import { MariaDbPlatform } from './MariaDbPlatform.js';
12
4
  import { MariaDbQueryBuilder } from './MariaDbQueryBuilder.js';
13
5
  import { MariaDbMikroORM } from './MariaDbMikroORM.js';
14
6
  /** Database driver for MariaDB, extending the MySQL driver with MariaDB-specific behavior. */
15
7
  export declare class MariaDbDriver extends MySqlDriver {
16
- readonly platform: MariaDbPlatform;
17
- constructor(config: Configuration);
18
- createQueryBuilder<T extends AnyEntity<T>>(
19
- entityName: EntityName<T>,
20
- ctx?: Transaction,
21
- preferredConnectionType?: ConnectionType,
22
- convertCustomTypes?: boolean,
23
- loggerContext?: LoggingOptions,
24
- alias?: string,
25
- em?: SqlEntityManager,
26
- ): MariaDbQueryBuilder<T, any, any, any>;
27
- /** @inheritDoc */
28
- getORMClass(): Constructor<MariaDbMikroORM>;
8
+ readonly platform: MariaDbPlatform;
9
+ constructor(config: Configuration);
10
+ createQueryBuilder<T extends AnyEntity<T>>(entityName: EntityName<T>, ctx?: Transaction, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): MariaDbQueryBuilder<T, any, any, any>;
11
+ /** @inheritDoc */
12
+ getORMClass(): Constructor<MariaDbMikroORM>;
29
13
  }
package/MariaDbDriver.js CHANGED
@@ -1,27 +1,27 @@
1
- import { QueryFlag } from '@mikro-orm/core';
1
+ import { QueryFlag, } from '@mikro-orm/core';
2
2
  import { MySqlDriver } from '@mikro-orm/mysql';
3
3
  import { MariaDbPlatform } from './MariaDbPlatform.js';
4
4
  import { MariaDbQueryBuilder } from './MariaDbQueryBuilder.js';
5
5
  import { MariaDbMikroORM } from './MariaDbMikroORM.js';
6
6
  /** Database driver for MariaDB, extending the MySQL driver with MariaDB-specific behavior. */
7
7
  export class MariaDbDriver extends MySqlDriver {
8
- constructor(config) {
9
- super(config);
10
- this.platform = new MariaDbPlatform();
11
- }
12
- createQueryBuilder(entityName, ctx, preferredConnectionType, convertCustomTypes, loggerContext, alias, em) {
13
- // do not compute the connectionType if EM is provided as it will be computed from it in the QB later on
14
- const connectionType = em
15
- ? preferredConnectionType
16
- : this.resolveConnectionType({ ctx, connectionType: preferredConnectionType });
17
- const qb = new MariaDbQueryBuilder(entityName, this.metadata, this, ctx, alias, connectionType, em, loggerContext);
18
- if (!convertCustomTypes) {
19
- qb.unsetFlag(QueryFlag.CONVERT_CUSTOM_TYPES);
8
+ constructor(config) {
9
+ super(config);
10
+ this.platform = new MariaDbPlatform();
11
+ }
12
+ createQueryBuilder(entityName, ctx, preferredConnectionType, convertCustomTypes, loggerContext, alias, em) {
13
+ // do not compute the connectionType if EM is provided as it will be computed from it in the QB later on
14
+ const connectionType = em
15
+ ? preferredConnectionType
16
+ : this.resolveConnectionType({ ctx, connectionType: preferredConnectionType });
17
+ const qb = new MariaDbQueryBuilder(entityName, this.metadata, this, ctx, alias, connectionType, em, loggerContext);
18
+ if (!convertCustomTypes) {
19
+ qb.unsetFlag(QueryFlag.CONVERT_CUSTOM_TYPES);
20
+ }
21
+ return qb;
22
+ }
23
+ /** @inheritDoc */
24
+ getORMClass() {
25
+ return MariaDbMikroORM;
20
26
  }
21
- return qb;
22
- }
23
- /** @inheritDoc */
24
- getORMClass() {
25
- return MariaDbMikroORM;
26
- }
27
27
  }
@@ -1,58 +1,20 @@
1
- import {
2
- type AnyEntity,
3
- type EntityClass,
4
- type EntitySchema,
5
- MikroORM,
6
- type Options,
7
- type IDatabaseDriver,
8
- type EntityManager,
9
- type EntityManagerType,
10
- } from '@mikro-orm/core';
1
+ import { type AnyEntity, type EntityClass, type EntitySchema, MikroORM, type Options, type IDatabaseDriver, type EntityManager, type EntityManagerType } from '@mikro-orm/core';
11
2
  import type { SqlEntityManager } from '@mikro-orm/mysql';
12
3
  import { MariaDbDriver } from './MariaDbDriver.js';
13
4
  /** Configuration options for the MariaDB driver. */
14
- export type MariaDbOptions<
15
- EM extends SqlEntityManager<MariaDbDriver> = SqlEntityManager<MariaDbDriver>,
16
- Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (
17
- | string
18
- | EntityClass<AnyEntity>
19
- | EntitySchema
20
- )[],
21
- > = Partial<Options<MariaDbDriver, EM, Entities>>;
5
+ export type MariaDbOptions<EM extends SqlEntityManager<MariaDbDriver> = SqlEntityManager<MariaDbDriver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> = Partial<Options<MariaDbDriver, EM, Entities>>;
22
6
  /** Creates a type-safe configuration object for the MariaDB driver. */
23
- export declare function defineMariaDbConfig<
24
- EM extends SqlEntityManager<MariaDbDriver> = SqlEntityManager<MariaDbDriver>,
25
- Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (
26
- | string
27
- | EntityClass<AnyEntity>
28
- | EntitySchema
29
- )[],
30
- >(options: Partial<Options<MariaDbDriver, EM, Entities>>): Partial<Options<MariaDbDriver, EM, Entities>>;
7
+ export declare function defineMariaDbConfig<EM extends SqlEntityManager<MariaDbDriver> = SqlEntityManager<MariaDbDriver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Partial<Options<MariaDbDriver, EM, Entities>>): Partial<Options<MariaDbDriver, EM, Entities>>;
31
8
  /**
32
9
  * @inheritDoc
33
10
  */
34
- export declare class MariaDbMikroORM<
35
- EM extends SqlEntityManager<MariaDbDriver> = SqlEntityManager<MariaDbDriver>,
36
- Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (
37
- | string
38
- | EntityClass<AnyEntity>
39
- | EntitySchema
40
- )[],
41
- > extends MikroORM<MariaDbDriver, EM, Entities> {
42
- /**
43
- * @inheritDoc
44
- */
45
- static init<
46
- D extends IDatabaseDriver = MariaDbDriver,
47
- EM extends EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>,
48
- Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (
49
- | string
50
- | EntityClass<AnyEntity>
51
- | EntitySchema
52
- )[],
53
- >(options: Partial<Options<D, EM, Entities>>): Promise<MikroORM<D, EM, Entities>>;
54
- /**
55
- * @inheritDoc
56
- */
57
- constructor(options: Partial<Options<MariaDbDriver, EM, Entities>>);
11
+ export declare class MariaDbMikroORM<EM extends SqlEntityManager<MariaDbDriver> = SqlEntityManager<MariaDbDriver>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> extends MikroORM<MariaDbDriver, EM, Entities> {
12
+ /**
13
+ * @inheritDoc
14
+ */
15
+ static init<D extends IDatabaseDriver = MariaDbDriver, EM extends EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>, Entities extends (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Partial<Options<D, EM, Entities>>): Promise<MikroORM<D, EM, Entities>>;
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ constructor(options: Partial<Options<MariaDbDriver, EM, Entities>>);
58
20
  }
@@ -1,23 +1,23 @@
1
- import { defineConfig, MikroORM } from '@mikro-orm/core';
1
+ import { defineConfig, MikroORM, } from '@mikro-orm/core';
2
2
  import { MariaDbDriver } from './MariaDbDriver.js';
3
3
  /** Creates a type-safe configuration object for the MariaDB driver. */
4
4
  export function defineMariaDbConfig(options) {
5
- return defineConfig({ driver: MariaDbDriver, ...options });
5
+ return defineConfig({ driver: MariaDbDriver, ...options });
6
6
  }
7
7
  /**
8
8
  * @inheritDoc
9
9
  */
10
10
  export class MariaDbMikroORM extends MikroORM {
11
- /**
12
- * @inheritDoc
13
- */
14
- static async init(options) {
15
- return super.init(defineMariaDbConfig(options));
16
- }
17
- /**
18
- * @inheritDoc
19
- */
20
- constructor(options) {
21
- super(defineMariaDbConfig(options));
22
- }
11
+ /**
12
+ * @inheritDoc
13
+ */
14
+ static async init(options) {
15
+ return super.init(defineMariaDbConfig(options));
16
+ }
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ constructor(options) {
21
+ super(defineMariaDbConfig(options));
22
+ }
23
23
  }
@@ -2,7 +2,7 @@ import { MySqlPlatform, type TransformContext } from '@mikro-orm/mysql';
2
2
  import { MariaDbSchemaHelper } from './MariaDbSchemaHelper.js';
3
3
  /** Platform implementation for MariaDB. */
4
4
  export declare class MariaDbPlatform extends MySqlPlatform {
5
- protected readonly schemaHelper: MariaDbSchemaHelper;
6
- convertJsonToDatabaseValue(value: unknown, context?: TransformContext): unknown;
7
- convertsJsonAutomatically(): boolean;
5
+ protected readonly schemaHelper: MariaDbSchemaHelper;
6
+ convertJsonToDatabaseValue(value: unknown, context?: TransformContext): unknown;
7
+ convertsJsonAutomatically(): boolean;
8
8
  }
@@ -2,14 +2,14 @@ import { MySqlPlatform } from '@mikro-orm/mysql';
2
2
  import { MariaDbSchemaHelper } from './MariaDbSchemaHelper.js';
3
3
  /** Platform implementation for MariaDB. */
4
4
  export class MariaDbPlatform extends MySqlPlatform {
5
- schemaHelper = new MariaDbSchemaHelper(this);
6
- convertJsonToDatabaseValue(value, context) {
7
- if (context?.mode === 'hydration') {
8
- return value;
5
+ schemaHelper = new MariaDbSchemaHelper(this);
6
+ convertJsonToDatabaseValue(value, context) {
7
+ if (context?.mode === 'hydration') {
8
+ return value;
9
+ }
10
+ return JSON.stringify(value);
11
+ }
12
+ convertsJsonAutomatically() {
13
+ return false;
9
14
  }
10
- return JSON.stringify(value);
11
- }
12
- convertsJsonAutomatically() {
13
- return false;
14
- }
15
15
  }
@@ -3,11 +3,6 @@ import { QueryBuilder } from '@mikro-orm/mysql';
3
3
  /**
4
4
  * @inheritDoc
5
5
  */
6
- export declare class MariaDbQueryBuilder<
7
- Entity extends object = AnyEntity,
8
- RootAlias extends string = never,
9
- Hint extends string = never,
10
- Context extends object = never,
11
- > extends QueryBuilder<Entity, RootAlias, Hint, Context> {
12
- protected wrapPaginateSubQuery(meta: EntityMetadata): void;
6
+ export declare class MariaDbQueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never> extends QueryBuilder<Entity, RootAlias, Hint, Context> {
7
+ protected wrapPaginateSubQuery(meta: EntityMetadata): void;
13
8
  }
@@ -4,80 +4,83 @@ import { QueryBuilder } from '@mikro-orm/mysql';
4
4
  * @inheritDoc
5
5
  */
6
6
  export class MariaDbQueryBuilder extends QueryBuilder {
7
- wrapPaginateSubQuery(meta) {
8
- const pks = this.prepareFields(meta.primaryKeys, 'sub-query');
9
- const quotedPKs = pks.map(pk => this.platform.quoteIdentifier(pk));
10
- const subQuery = this.clone(['orderBy', 'fields']).select(pks).groupBy(pks).limit(this.state.limit);
11
- // revert the on conditions added via populateWhere, we want to apply those only once
12
- Object.values(subQuery.state.joins).forEach(join => (join.cond = join.cond_ ?? {}));
13
- if (this.state.offset) {
14
- subQuery.offset(this.state.offset);
15
- }
16
- const addToSelect = [];
17
- if (this.state.orderBy.length > 0) {
18
- const orderBy = [];
19
- for (const orderMap of this.state.orderBy) {
20
- for (const field of Utils.getObjectQueryKeys(orderMap)) {
21
- const direction = orderMap[field];
22
- if (RawQueryFragment.isKnownFragmentSymbol(field)) {
23
- orderBy.push({ [field]: direction });
24
- continue;
25
- }
26
- const [a, f] = this.helper.splitField(field);
27
- const prop = this.helper.getProperty(f, a);
28
- const type = this.platform.castColumn(prop);
29
- const fieldName = this.helper.mapper(field, this.type, undefined, null);
30
- if (!prop?.persist && !prop?.formula && !pks.includes(fieldName)) {
31
- addToSelect.push(fieldName);
32
- }
33
- const key = raw(`min(${this.platform.quoteIdentifier(fieldName)}${type})`);
34
- orderBy.push({ [key]: direction });
7
+ wrapPaginateSubQuery(meta) {
8
+ const pks = this.prepareFields(meta.primaryKeys, 'sub-query');
9
+ const quotedPKs = pks.map(pk => this.platform.quoteIdentifier(pk));
10
+ const subQuery = this.clone(['orderBy', 'fields'])
11
+ .select(pks)
12
+ .groupBy(pks)
13
+ .limit(this.state.limit);
14
+ // revert the on conditions added via populateWhere, we want to apply those only once
15
+ Object.values(subQuery.state.joins).forEach(join => (join.cond = join.cond_ ?? {}));
16
+ if (this.state.offset) {
17
+ subQuery.offset(this.state.offset);
35
18
  }
36
- }
37
- subQuery.orderBy(orderBy);
38
- }
39
- subQuery.state.finalized = true;
40
- const innerQuery = subQuery.as(this.mainAlias.aliasName).clear('select').select(pks);
41
- /* v8 ignore next */
42
- if (addToSelect.length > 0) {
43
- addToSelect.forEach(prop => {
44
- const field = this.state.fields.find(field => {
45
- if (typeof field === 'object' && field && '__as' in field) {
46
- return field.__as === prop;
47
- }
48
- if (field instanceof RawQueryFragment) {
49
- // not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
50
- return field.sql.includes(prop);
51
- }
52
- return false;
53
- });
54
- if (field instanceof RawQueryFragment) {
55
- innerQuery.select(this.platform.formatQuery(field.sql, field.params));
56
- } else if (field) {
57
- innerQuery.select(field);
19
+ const addToSelect = [];
20
+ if (this.state.orderBy.length > 0) {
21
+ const orderBy = [];
22
+ for (const orderMap of this.state.orderBy) {
23
+ for (const field of Utils.getObjectQueryKeys(orderMap)) {
24
+ const direction = orderMap[field];
25
+ if (RawQueryFragment.isKnownFragmentSymbol(field)) {
26
+ orderBy.push({ [field]: direction });
27
+ continue;
28
+ }
29
+ const [a, f] = this.helper.splitField(field);
30
+ const prop = this.helper.getProperty(f, a);
31
+ const type = this.platform.castColumn(prop);
32
+ const fieldName = this.helper.mapper(field, this.type, undefined, null);
33
+ if (!prop?.persist && !prop?.formula && !pks.includes(fieldName)) {
34
+ addToSelect.push(fieldName);
35
+ }
36
+ const key = raw(`min(${this.platform.quoteIdentifier(fieldName)}${type})`);
37
+ orderBy.push({ [key]: direction });
38
+ }
39
+ }
40
+ subQuery.orderBy(orderBy);
41
+ }
42
+ subQuery.state.finalized = true;
43
+ const innerQuery = subQuery.as(this.mainAlias.aliasName).clear('select').select(pks);
44
+ /* v8 ignore next */
45
+ if (addToSelect.length > 0) {
46
+ addToSelect.forEach(prop => {
47
+ const field = this.state.fields.find(field => {
48
+ if (typeof field === 'object' && field && '__as' in field) {
49
+ return field.__as === prop;
50
+ }
51
+ if (field instanceof RawQueryFragment) {
52
+ // not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
53
+ return field.sql.includes(prop);
54
+ }
55
+ return false;
56
+ });
57
+ if (field instanceof RawQueryFragment) {
58
+ innerQuery.select(this.platform.formatQuery(field.sql, field.params));
59
+ }
60
+ else if (field) {
61
+ innerQuery.select(field);
62
+ }
63
+ });
58
64
  }
59
- });
65
+ // multiple sub-queries are needed to get around mysql limitations with order by + limit + where in + group by (o.O)
66
+ // https://stackoverflow.com/questions/17892762/mysql-this-version-of-mysql-doesnt-yet-support-limit-in-all-any-some-subqu
67
+ const subSubQuery = this.platform.createNativeQueryBuilder();
68
+ subSubQuery.select(raw(`json_arrayagg(${quotedPKs.join(', ')})`)).from(innerQuery);
69
+ this.state.limit = undefined;
70
+ this.state.offset = undefined;
71
+ // Save the original WHERE conditions before pruning joins
72
+ const originalCond = this.state.cond;
73
+ const populatePaths = this.getPopulatePaths();
74
+ // Remove joins that are not used for population or ordering
75
+ this.pruneJoinsForPagination(meta, populatePaths);
76
+ // Transfer WHERE conditions to ORDER BY joins (GH #6160)
77
+ this.transferConditionsForOrderByJoins(meta, originalCond, populatePaths);
78
+ const subquerySql = subSubQuery.toString();
79
+ const key = meta.getPrimaryProps()[0].runtimeType === 'string'
80
+ ? `concat('"', ${quotedPKs.join(', ')}, '"')`
81
+ : quotedPKs.join(', ');
82
+ const sql = `json_contains((${subquerySql}), ${key})`;
83
+ this.state.cond = {};
84
+ this.select(this.state.fields).where(sql);
60
85
  }
61
- // multiple sub-queries are needed to get around mysql limitations with order by + limit + where in + group by (o.O)
62
- // https://stackoverflow.com/questions/17892762/mysql-this-version-of-mysql-doesnt-yet-support-limit-in-all-any-some-subqu
63
- const subSubQuery = this.platform.createNativeQueryBuilder();
64
- subSubQuery.select(raw(`json_arrayagg(${quotedPKs.join(', ')})`)).from(innerQuery);
65
- this.state.limit = undefined;
66
- this.state.offset = undefined;
67
- // Save the original WHERE conditions before pruning joins
68
- const originalCond = this.state.cond;
69
- const populatePaths = this.getPopulatePaths();
70
- // Remove joins that are not used for population or ordering
71
- this.pruneJoinsForPagination(meta, populatePaths);
72
- // Transfer WHERE conditions to ORDER BY joins (GH #6160)
73
- this.transferConditionsForOrderByJoins(meta, originalCond, populatePaths);
74
- const subquerySql = subSubQuery.toString();
75
- const key =
76
- meta.getPrimaryProps()[0].runtimeType === 'string'
77
- ? `concat('"', ${quotedPKs.join(', ')}, '"')`
78
- : quotedPKs.join(', ');
79
- const sql = `json_contains((${subquerySql}), ${key})`;
80
- this.state.cond = {};
81
- this.select(this.state.fields).where(sql);
82
- }
83
86
  }
@@ -1,24 +1,12 @@
1
- import {
2
- type AbstractSqlConnection,
3
- type CheckDef,
4
- type Column,
5
- type IndexDef,
6
- type DatabaseSchema,
7
- type Table,
8
- MySqlSchemaHelper,
9
- } from '@mikro-orm/mysql';
1
+ import { type AbstractSqlConnection, type CheckDef, type Column, type IndexDef, type DatabaseSchema, type Table, MySqlSchemaHelper } from '@mikro-orm/mysql';
10
2
  import { type Dictionary, type Type } from '@mikro-orm/core';
11
3
  /** Schema introspection helper for MariaDB. */
12
4
  export declare class MariaDbSchemaHelper extends MySqlSchemaHelper {
13
- protected appendMySqlIndexSuffix(sql: string, index: IndexDef): string;
14
- loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[]): Promise<void>;
15
- getAllIndexes(connection: AbstractSqlConnection, tables: Table[]): Promise<Dictionary<IndexDef[]>>;
16
- getAllColumns(connection: AbstractSqlConnection, tables: Table[]): Promise<Dictionary<Column[]>>;
17
- getAllChecks(
18
- connection: AbstractSqlConnection,
19
- tables: Table[],
20
- columns?: Dictionary<Column[]>,
21
- ): Promise<Dictionary<CheckDef[]>>;
22
- protected getChecksSQL(tables: Table[]): string;
23
- protected wrap(val: string | undefined | null, type: Type<unknown>): string | undefined | null;
5
+ protected appendMySqlIndexSuffix(sql: string, index: IndexDef): string;
6
+ loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[]): Promise<void>;
7
+ getAllIndexes(connection: AbstractSqlConnection, tables: Table[]): Promise<Dictionary<IndexDef[]>>;
8
+ getAllColumns(connection: AbstractSqlConnection, tables: Table[]): Promise<Dictionary<Column[]>>;
9
+ getAllChecks(connection: AbstractSqlConnection, tables: Table[], columns?: Dictionary<Column[]>): Promise<Dictionary<CheckDef[]>>;
10
+ protected getChecksSQL(tables: Table[]): string;
11
+ protected wrap(val: string | undefined | null, type: Type<unknown>): string | undefined | null;
24
12
  }
@@ -1,84 +1,85 @@
1
- import { MySqlSchemaHelper } from '@mikro-orm/mysql';
1
+ import { MySqlSchemaHelper, } from '@mikro-orm/mysql';
2
2
  /** Schema introspection helper for MariaDB. */
3
3
  export class MariaDbSchemaHelper extends MySqlSchemaHelper {
4
- appendMySqlIndexSuffix(sql, index) {
5
- // MariaDB uses IGNORED instead of MySQL's INVISIBLE keyword
6
- if (index.invisible) {
7
- sql += ' ignored';
4
+ appendMySqlIndexSuffix(sql, index) {
5
+ // MariaDB uses IGNORED instead of MySQL's INVISIBLE keyword
6
+ if (index.invisible) {
7
+ sql += ' ignored';
8
+ }
9
+ // MariaDB supports CLUSTERING=YES only with the Aria storage engine.
10
+ // Using this option with InnoDB tables will have no effect (silently ignored).
11
+ // See: https://mariadb.com/kb/en/create-index/#clustering-yes
12
+ if (index.clustered) {
13
+ sql += ' clustering=yes';
14
+ }
15
+ return sql;
8
16
  }
9
- // MariaDB supports CLUSTERING=YES only with the Aria storage engine.
10
- // Using this option with InnoDB tables will have no effect (silently ignored).
11
- // See: https://mariadb.com/kb/en/create-index/#clustering-yes
12
- if (index.clustered) {
13
- sql += ' clustering=yes';
14
- }
15
- return sql;
16
- }
17
- async loadInformationSchema(schema, connection, tables) {
18
- /* v8 ignore next */
19
- if (tables.length === 0) {
20
- return;
21
- }
22
- const columns = await this.getAllColumns(connection, tables);
23
- const indexes = await this.getAllIndexes(connection, tables);
24
- const checks = await this.getAllChecks(connection, tables, columns);
25
- const fks = await this.getAllForeignKeys(connection, tables);
26
- const enums = await this.getAllEnumDefinitions(connection, tables);
27
- for (const t of tables) {
28
- const key = this.getTableKey(t);
29
- const table = schema.addTable(t.table_name, t.schema_name, t.table_comment);
30
- const pks = await this.getPrimaryKeys(connection, indexes[key], table.name, table.schema);
31
- table.init(columns[key], indexes[key], checks[key], pks, fks[key], enums[key]);
17
+ async loadInformationSchema(schema, connection, tables) {
18
+ /* v8 ignore next */
19
+ if (tables.length === 0) {
20
+ return;
21
+ }
22
+ const columns = await this.getAllColumns(connection, tables);
23
+ const indexes = await this.getAllIndexes(connection, tables);
24
+ const checks = await this.getAllChecks(connection, tables, columns);
25
+ const fks = await this.getAllForeignKeys(connection, tables);
26
+ const enums = await this.getAllEnumDefinitions(connection, tables);
27
+ for (const t of tables) {
28
+ const key = this.getTableKey(t);
29
+ const table = schema.addTable(t.table_name, t.schema_name, t.table_comment);
30
+ const pks = await this.getPrimaryKeys(connection, indexes[key], table.name, table.schema);
31
+ table.init(columns[key], indexes[key], checks[key], pks, fks[key], enums[key]);
32
+ }
32
33
  }
33
- }
34
- async getAllIndexes(connection, tables) {
35
- const sql = `select table_name as table_name, nullif(table_schema, schema()) as schema_name, index_name as index_name, non_unique as non_unique, column_name as column_name, index_type as index_type, sub_part as sub_part, collation as sort_order /*M!100600 , ignored as ignored */
34
+ async getAllIndexes(connection, tables) {
35
+ const sql = `select table_name as table_name, nullif(table_schema, schema()) as schema_name, index_name as index_name, non_unique as non_unique, column_name as column_name, index_type as index_type, sub_part as sub_part, collation as sort_order /*M!100600 , ignored as ignored */
36
36
  from information_schema.statistics where table_schema = database()
37
37
  and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')})
38
38
  order by schema_name, table_name, index_name, seq_in_index`;
39
- const allIndexes = await connection.execute(sql);
40
- const ret = {};
41
- for (const index of allIndexes) {
42
- const key = this.getTableKey(index);
43
- const indexDef = {
44
- columnNames: [index.column_name],
45
- keyName: index.index_name,
46
- unique: !index.non_unique,
47
- primary: index.index_name === 'PRIMARY',
48
- constraint: !index.non_unique,
49
- };
50
- // Capture column options (prefix length, sort order)
51
- if (index.sub_part != null || index.sort_order === 'D') {
52
- indexDef.columns = [
53
- {
54
- name: index.column_name,
55
- ...(index.sub_part != null && { length: index.sub_part }),
56
- ...(index.sort_order === 'D' && { sort: 'DESC' }),
57
- },
58
- ];
59
- }
60
- // Capture index type for fulltext and spatial indexes
61
- if (index.index_type === 'FULLTEXT') {
62
- indexDef.type = 'fulltext';
63
- } else if (index.index_type === 'SPATIAL') {
64
- /* v8 ignore next */
65
- indexDef.type = 'spatial';
66
- }
67
- // Capture ignored flag (MariaDB 10.6+, equivalent to MySQL's INVISIBLE)
68
- /* v8 ignore next */
69
- if (index.ignored === 'YES') {
70
- indexDef.invisible = true;
71
- }
72
- ret[key] ??= [];
73
- ret[key].push(indexDef);
39
+ const allIndexes = await connection.execute(sql);
40
+ const ret = {};
41
+ for (const index of allIndexes) {
42
+ const key = this.getTableKey(index);
43
+ const indexDef = {
44
+ columnNames: [index.column_name],
45
+ keyName: index.index_name,
46
+ unique: !index.non_unique,
47
+ primary: index.index_name === 'PRIMARY',
48
+ constraint: !index.non_unique,
49
+ };
50
+ // Capture column options (prefix length, sort order)
51
+ if (index.sub_part != null || index.sort_order === 'D') {
52
+ indexDef.columns = [
53
+ {
54
+ name: index.column_name,
55
+ ...(index.sub_part != null && { length: index.sub_part }),
56
+ ...(index.sort_order === 'D' && { sort: 'DESC' }),
57
+ },
58
+ ];
59
+ }
60
+ // Capture index type for fulltext and spatial indexes
61
+ if (index.index_type === 'FULLTEXT') {
62
+ indexDef.type = 'fulltext';
63
+ }
64
+ else if (index.index_type === 'SPATIAL') {
65
+ /* v8 ignore next */
66
+ indexDef.type = 'spatial';
67
+ }
68
+ // Capture ignored flag (MariaDB 10.6+, equivalent to MySQL's INVISIBLE)
69
+ /* v8 ignore next */
70
+ if (index.ignored === 'YES') {
71
+ indexDef.invisible = true;
72
+ }
73
+ ret[key] ??= [];
74
+ ret[key].push(indexDef);
75
+ }
76
+ for (const key of Object.keys(ret)) {
77
+ ret[key] = await this.mapIndexes(ret[key]);
78
+ }
79
+ return ret;
74
80
  }
75
- for (const key of Object.keys(ret)) {
76
- ret[key] = await this.mapIndexes(ret[key]);
77
- }
78
- return ret;
79
- }
80
- async getAllColumns(connection, tables) {
81
- const sql = `select table_name as table_name,
81
+ async getAllColumns(connection, tables) {
82
+ const sql = `select table_name as table_name,
82
83
  nullif(table_schema, schema()) as schema_name,
83
84
  column_name as column_name,
84
85
  column_default as column_default,
@@ -94,73 +95,69 @@ export class MariaDbSchemaHelper extends MySqlSchemaHelper {
94
95
  ifnull(datetime_precision, character_maximum_length) length
95
96
  from information_schema.columns where table_schema = database() and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')})
96
97
  order by ordinal_position`;
97
- const allColumns = await connection.execute(sql);
98
- const str = val => (val != null ? '' + val : val);
99
- const extra = val =>
100
- val.replace(/auto_increment|default_generated|(stored|virtual) generated/i, '').trim() || undefined;
101
- const ret = {};
102
- for (const col of allColumns) {
103
- const mappedType = this.platform.getMappedType(col.column_type);
104
- const tmp = this.normalizeDefaultValue(
105
- mappedType.compareAsType() === 'boolean' && ['0', '1'].includes(col.column_default)
106
- ? ['false', 'true'][+col.column_default]
107
- : col.column_default,
108
- col.length,
109
- );
110
- const defaultValue = str(tmp === 'NULL' && col.is_nullable === 'YES' ? null : tmp);
111
- const key = this.getTableKey(col);
112
- const generated = col.generation_expression
113
- ? `${col.generation_expression.replaceAll(`\\'`, `'`)} ${col.extra.match(/stored generated/i) ? 'stored' : 'virtual'}`
114
- : undefined;
115
- ret[key] ??= [];
116
- ret[key].push({
117
- name: col.column_name,
118
- type: this.platform.isNumericColumn(mappedType)
119
- ? col.column_type.replace(/ unsigned$/, '').replace(/\(\d+\)$/, '')
120
- : col.column_type,
121
- mappedType,
122
- unsigned: col.column_type.endsWith(' unsigned'),
123
- length: col.length,
124
- default: this.wrap(defaultValue, mappedType),
125
- nullable: col.is_nullable === 'YES',
126
- primary: col.column_key === 'PRI',
127
- unique: col.column_key === 'UNI',
128
- autoincrement: col.extra === 'auto_increment',
129
- precision: col.numeric_precision,
130
- scale: col.numeric_scale,
131
- comment: col.column_comment,
132
- extra: extra(col.extra),
133
- generated,
134
- });
98
+ const allColumns = await connection.execute(sql);
99
+ const str = (val) => (val != null ? '' + val : val);
100
+ const extra = (val) => val.replace(/auto_increment|default_generated|(stored|virtual) generated/i, '').trim() || undefined;
101
+ const ret = {};
102
+ for (const col of allColumns) {
103
+ const mappedType = this.platform.getMappedType(col.column_type);
104
+ const tmp = this.normalizeDefaultValue(mappedType.compareAsType() === 'boolean' && ['0', '1'].includes(col.column_default)
105
+ ? ['false', 'true'][+col.column_default]
106
+ : col.column_default, col.length);
107
+ const defaultValue = str(tmp === 'NULL' && col.is_nullable === 'YES' ? null : tmp);
108
+ const key = this.getTableKey(col);
109
+ const generated = col.generation_expression
110
+ ? `${col.generation_expression.replaceAll(`\\'`, `'`)} ${col.extra.match(/stored generated/i) ? 'stored' : 'virtual'}`
111
+ : undefined;
112
+ ret[key] ??= [];
113
+ ret[key].push({
114
+ name: col.column_name,
115
+ type: this.platform.isNumericColumn(mappedType)
116
+ ? col.column_type.replace(/ unsigned$/, '').replace(/\(\d+\)$/, '')
117
+ : col.column_type,
118
+ mappedType,
119
+ unsigned: col.column_type.endsWith(' unsigned'),
120
+ length: col.length,
121
+ default: this.wrap(defaultValue, mappedType),
122
+ nullable: col.is_nullable === 'YES',
123
+ primary: col.column_key === 'PRI',
124
+ unique: col.column_key === 'UNI',
125
+ autoincrement: col.extra === 'auto_increment',
126
+ precision: col.numeric_precision,
127
+ scale: col.numeric_scale,
128
+ comment: col.column_comment,
129
+ extra: extra(col.extra),
130
+ generated,
131
+ });
132
+ }
133
+ return ret;
135
134
  }
136
- return ret;
137
- }
138
- async getAllChecks(connection, tables, columns) {
139
- const sql = this.getChecksSQL(tables);
140
- const allChecks = await connection.execute(sql);
141
- const ret = {};
142
- for (const check of allChecks) {
143
- const key = this.getTableKey(check);
144
- const match = /^json_valid\(`(.*)`\)$/i.exec(check.expression);
145
- const col = columns?.[key]?.find(col => col.name === match?.[1]);
146
- if (col && match) {
147
- col.type = 'json';
148
- col.mappedType = this.platform.getMappedType('json');
149
- delete col.length;
150
- continue;
151
- }
152
- ret[key] ??= [];
153
- ret[key].push({
154
- name: check.name,
155
- columnName: check.column_name,
156
- definition: `check ${check.expression}`,
157
- expression: check.expression.replace(/^\((.*)\)$/, '$1'),
158
- });
135
+ async getAllChecks(connection, tables, columns) {
136
+ const sql = this.getChecksSQL(tables);
137
+ const allChecks = await connection.execute(sql);
138
+ const ret = {};
139
+ for (const check of allChecks) {
140
+ const key = this.getTableKey(check);
141
+ const match = /^json_valid\(`(.*)`\)$/i.exec(check.expression);
142
+ const col = columns?.[key]?.find(col => col.name === match?.[1]);
143
+ if (col && match) {
144
+ col.type = 'json';
145
+ col.mappedType = this.platform.getMappedType('json');
146
+ delete col.length;
147
+ continue;
148
+ }
149
+ ret[key] ??= [];
150
+ ret[key].push({
151
+ name: check.name,
152
+ columnName: check.column_name,
153
+ definition: `check ${check.expression}`,
154
+ expression: check.expression.replace(/^\((.*)\)$/, '$1'),
155
+ });
156
+ }
157
+ return ret;
159
158
  }
160
- return ret;
161
- }
162
- getChecksSQL(tables) {
163
- return `select
159
+ getChecksSQL(tables) {
160
+ return `select
164
161
  tc.constraint_schema as table_schema,
165
162
  tc.table_name as table_name,
166
163
  tc.constraint_name as name,
@@ -169,8 +166,8 @@ export class MariaDbSchemaHelper extends MySqlSchemaHelper {
169
166
  from information_schema.check_constraints tc
170
167
  where tc.table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')}) and tc.constraint_schema = database()
171
168
  order by tc.constraint_name`;
172
- }
173
- wrap(val, type) {
174
- return val;
175
- }
169
+ }
170
+ wrap(val, type) {
171
+ return val;
172
+ }
176
173
  }
package/README.md CHANGED
@@ -133,7 +133,7 @@ const author = await em.findOneOrFail(Author, 1, {
133
133
  populate: ['books'],
134
134
  });
135
135
  author.name = 'Jon Snow II';
136
- author.books.getItems().forEach(book => (book.title += ' (2nd ed.)'));
136
+ author.books.getItems().forEach(book => book.title += ' (2nd ed.)');
137
137
  author.books.add(orm.em.create(Book, { title: 'New Book', author }));
138
138
 
139
139
  // Flush computes change sets and executes them in a single transaction
package/index.d.ts CHANGED
@@ -2,8 +2,4 @@ export * from '@mikro-orm/mysql';
2
2
  export * from './MariaDbSchemaHelper.js';
3
3
  export * from './MariaDbPlatform.js';
4
4
  export * from './MariaDbDriver.js';
5
- export {
6
- MariaDbMikroORM as MikroORM,
7
- type MariaDbOptions as Options,
8
- defineMariaDbConfig as defineConfig,
9
- } from './MariaDbMikroORM.js';
5
+ export { MariaDbMikroORM as MikroORM, type MariaDbOptions as Options, defineMariaDbConfig as defineConfig, } from './MariaDbMikroORM.js';
package/index.js CHANGED
@@ -2,4 +2,4 @@ export * from '@mikro-orm/mysql';
2
2
  export * from './MariaDbSchemaHelper.js';
3
3
  export * from './MariaDbPlatform.js';
4
4
  export * from './MariaDbDriver.js';
5
- export { MariaDbMikroORM as MikroORM, defineMariaDbConfig as defineConfig } from './MariaDbMikroORM.js';
5
+ export { MariaDbMikroORM as MikroORM, defineMariaDbConfig as defineConfig, } from './MariaDbMikroORM.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/mariadb",
3
- "version": "7.0.3",
3
+ "version": "7.0.4-dev.1",
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",
@@ -42,19 +42,19 @@
42
42
  },
43
43
  "scripts": {
44
44
  "build": "yarn compile && yarn copy",
45
- "clean": "yarn run -T rimraf ./dist",
45
+ "clean": "yarn run -T rimraf ./dist ./tsconfig.build.tsbuildinfo",
46
46
  "compile": "yarn run -T tsc -p tsconfig.build.json",
47
47
  "copy": "node ../../scripts/copy.mjs"
48
48
  },
49
49
  "dependencies": {
50
- "@mikro-orm/mysql": "7.0.3",
50
+ "@mikro-orm/mysql": "7.0.4-dev.1",
51
51
  "kysely": "0.28.12"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@mikro-orm/core": "^7.0.3"
55
55
  },
56
56
  "peerDependencies": {
57
- "@mikro-orm/core": "7.0.3"
57
+ "@mikro-orm/core": "7.0.4-dev.1"
58
58
  },
59
59
  "engines": {
60
60
  "node": ">= 22.17.0"