@mikro-orm/knex 6.3.14-dev.9 → 6.4.0
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/AbstractSqlConnection.d.ts +4 -2
- package/AbstractSqlConnection.js +1 -0
- package/AbstractSqlDriver.js +1 -1
- package/index.mjs +1 -0
- package/package.json +3 -3
- package/query/QueryBuilder.d.ts +3 -1
- package/query/QueryBuilder.js +19 -5
- package/query/QueryBuilderHelper.d.ts +1 -0
- package/query/QueryBuilderHelper.js +14 -3
- package/schema/DatabaseSchema.d.ts +3 -1
- package/schema/DatabaseSchema.js +11 -2
- package/schema/SchemaComparator.js +3 -0
|
@@ -22,8 +22,10 @@ export declare abstract class AbstractSqlConnection extends Connection {
|
|
|
22
22
|
* @inheritDoc
|
|
23
23
|
*/
|
|
24
24
|
checkConnection(): Promise<{
|
|
25
|
-
ok:
|
|
26
|
-
|
|
25
|
+
ok: true;
|
|
26
|
+
} | {
|
|
27
|
+
ok: false;
|
|
28
|
+
reason: string;
|
|
27
29
|
error?: Error;
|
|
28
30
|
}>;
|
|
29
31
|
transactional<T>(cb: (trx: Transaction<Knex.Transaction>) => Promise<T>, options?: {
|
package/AbstractSqlConnection.js
CHANGED
|
@@ -109,6 +109,7 @@ class AbstractSqlConnection extends core_1.Connection {
|
|
|
109
109
|
queryOrKnex = q.sql;
|
|
110
110
|
params = q.bindings;
|
|
111
111
|
}
|
|
112
|
+
queryOrKnex = this.config.get('onQuery')(queryOrKnex, params);
|
|
112
113
|
const formatted = this.platform.formatQuery(queryOrKnex, params);
|
|
113
114
|
const sql = this.getSql(queryOrKnex, formatted, loggerContext);
|
|
114
115
|
return this.executeQuery(sql, async () => {
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -570,7 +570,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
570
570
|
for (const key of keys) {
|
|
571
571
|
const prop = meta.properties[key] ?? meta.root.properties[key];
|
|
572
572
|
prop.fieldNames.forEach((fieldName, fieldNameIdx) => {
|
|
573
|
-
if (fields.has(fieldName)) {
|
|
573
|
+
if (fields.has(fieldName) || (prop.ownColumns && !prop.ownColumns.includes(fieldName))) {
|
|
574
574
|
return;
|
|
575
575
|
}
|
|
576
576
|
fields.add(fieldName);
|
package/index.mjs
CHANGED
|
@@ -199,6 +199,7 @@ export const TimeType = mod.TimeType;
|
|
|
199
199
|
export const TinyIntType = mod.TinyIntType;
|
|
200
200
|
export const TransactionContext = mod.TransactionContext;
|
|
201
201
|
export const TransactionEventBroadcaster = mod.TransactionEventBroadcaster;
|
|
202
|
+
export const Transactional = mod.Transactional;
|
|
202
203
|
export const Type = mod.Type;
|
|
203
204
|
export const Uint8ArrayType = mod.Uint8ArrayType;
|
|
204
205
|
export const UnderscoreNamingStrategy = mod.UnderscoreNamingStrategy;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
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
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
"sqlstring": "2.3.3"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@mikro-orm/core": "^6.
|
|
66
|
+
"@mikro-orm/core": "^6.4.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.
|
|
69
|
+
"@mikro-orm/core": "^6.0.0",
|
|
70
70
|
"better-sqlite3": "*",
|
|
71
71
|
"libsql": "*",
|
|
72
72
|
"mariadb": "*"
|
package/query/QueryBuilder.d.ts
CHANGED
|
@@ -156,7 +156,9 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
|
|
|
156
156
|
orWhere(cond: string, params?: any[]): this;
|
|
157
157
|
orderBy(orderBy: QBQueryOrderMap<Entity> | QBQueryOrderMap<Entity>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
|
|
158
158
|
groupBy(fields: EntityKeyOrString<Entity> | readonly EntityKeyOrString<Entity>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
|
|
159
|
-
having(cond?: QBFilterQuery | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
|
|
159
|
+
having(cond?: QBFilterQuery | string, params?: any[], operator?: keyof typeof GroupOperator): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
|
|
160
|
+
andHaving(cond?: QBFilterQuery | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
|
|
161
|
+
orHaving(cond?: QBFilterQuery | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
|
|
160
162
|
onConflict(fields?: Field<Entity> | Field<Entity>[]): InsertQueryBuilder<Entity>;
|
|
161
163
|
ignore(): this;
|
|
162
164
|
merge(data?: EntityData<Entity> | Field<Entity>[]): this;
|
package/query/QueryBuilder.js
CHANGED
|
@@ -314,7 +314,7 @@ class QueryBuilder {
|
|
|
314
314
|
this._cond = { [op]: cond1 };
|
|
315
315
|
}
|
|
316
316
|
if (this._onConflict) {
|
|
317
|
-
this._onConflict[this._onConflict.length - 1].where = this._cond;
|
|
317
|
+
this._onConflict[this._onConflict.length - 1].where = this.helper.processOnConflictCondition(this._cond, this._schema);
|
|
318
318
|
this._cond = {};
|
|
319
319
|
}
|
|
320
320
|
return this;
|
|
@@ -348,14 +348,27 @@ class QueryBuilder {
|
|
|
348
348
|
this._groupBy = core_1.Utils.asArray(fields);
|
|
349
349
|
return this;
|
|
350
350
|
}
|
|
351
|
-
having(cond = {}, params) {
|
|
351
|
+
having(cond = {}, params, operator) {
|
|
352
352
|
this.ensureNotFinalized();
|
|
353
353
|
if (core_1.Utils.isString(cond)) {
|
|
354
354
|
cond = { [(0, core_1.raw)(`(${cond})`, params)]: [] };
|
|
355
355
|
}
|
|
356
|
-
|
|
356
|
+
cond = CriteriaNodeFactory_1.CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, cond).process(this);
|
|
357
|
+
if (!this._having || !operator) {
|
|
358
|
+
this._having = cond;
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
const cond1 = [this._having, cond];
|
|
362
|
+
this._having = { [operator]: cond1 };
|
|
363
|
+
}
|
|
357
364
|
return this;
|
|
358
365
|
}
|
|
366
|
+
andHaving(cond, params) {
|
|
367
|
+
return this.having(cond, params, '$and');
|
|
368
|
+
}
|
|
369
|
+
orHaving(cond, params) {
|
|
370
|
+
return this.having(cond, params, '$or');
|
|
371
|
+
}
|
|
359
372
|
onConflict(fields = []) {
|
|
360
373
|
const meta = this.mainAlias.metadata;
|
|
361
374
|
this.ensureNotFinalized();
|
|
@@ -691,7 +704,6 @@ class QueryBuilder {
|
|
|
691
704
|
const [propName] = hint.field.split(':', 2);
|
|
692
705
|
const value = core_1.Reference.unwrapReference(entity[propName]);
|
|
693
706
|
if (core_1.Utils.isEntity(value)) {
|
|
694
|
-
(0, core_1.helper)(value).populated();
|
|
695
707
|
propagatePopulateHint(value, hint.children ?? []);
|
|
696
708
|
}
|
|
697
709
|
else if (core_1.Utils.isCollection(value)) {
|
|
@@ -1051,7 +1063,7 @@ class QueryBuilder {
|
|
|
1051
1063
|
case enums_1.QueryType.SELECT:
|
|
1052
1064
|
qb.select(this.prepareFields(this._fields));
|
|
1053
1065
|
if (this._distinctOn) {
|
|
1054
|
-
qb.distinctOn(this._distinctOn);
|
|
1066
|
+
qb.distinctOn(this.prepareFields(this._distinctOn));
|
|
1055
1067
|
}
|
|
1056
1068
|
else if (this.flags.has(core_1.QueryFlag.DISTINCT)) {
|
|
1057
1069
|
qb.distinct();
|
|
@@ -1069,6 +1081,7 @@ class QueryBuilder {
|
|
|
1069
1081
|
break;
|
|
1070
1082
|
case enums_1.QueryType.UPDATE:
|
|
1071
1083
|
qb.update(this._data);
|
|
1084
|
+
this.helper.processJoins(qb, this._joins, joinSchema);
|
|
1072
1085
|
this.helper.updateVersionProperty(qb, this._data);
|
|
1073
1086
|
break;
|
|
1074
1087
|
case enums_1.QueryType.DELETE:
|
|
@@ -1337,6 +1350,7 @@ class QueryBuilder {
|
|
|
1337
1350
|
subSubQuery.__raw = true; // tag it as there is now way to check via `instanceof`
|
|
1338
1351
|
const method = this.flags.has(core_1.QueryFlag.UPDATE_SUB_QUERY) ? 'update' : 'delete';
|
|
1339
1352
|
this._cond = {}; // otherwise we would trigger validation error
|
|
1353
|
+
this._joins = {}; // included in the subquery
|
|
1340
1354
|
this[method](this._data).where({
|
|
1341
1355
|
[core_1.Utils.getPrimaryKeyHash(meta.primaryKeys)]: { $in: subSubQuery },
|
|
1342
1356
|
});
|
|
@@ -59,6 +59,7 @@ export declare class QueryBuilderHelper {
|
|
|
59
59
|
private fieldName;
|
|
60
60
|
getProperty(field: string, alias?: string): EntityProperty | undefined;
|
|
61
61
|
isTableNameAliasRequired(type?: QueryType): boolean;
|
|
62
|
+
processOnConflictCondition(cond: QBFilterQuery, schema?: string): QBFilterQuery;
|
|
62
63
|
}
|
|
63
64
|
export interface Alias<T> {
|
|
64
65
|
aliasName: string;
|
|
@@ -471,13 +471,14 @@ class QueryBuilderHelper {
|
|
|
471
471
|
if (fields.length > 1 && Array.isArray(value[op])) {
|
|
472
472
|
const singleTuple = !value[op].every((v) => Array.isArray(v));
|
|
473
473
|
if (!this.platform.allowsComparingTuples()) {
|
|
474
|
+
const mapped = fields.map(f => this.mapper(f, type));
|
|
474
475
|
if (op === '$in') {
|
|
475
476
|
const conds = value[op].map(() => {
|
|
476
|
-
return `(${
|
|
477
|
+
return `(${mapped.map(field => `${this.platform.quoteIdentifier(field)} = ?`).join(' and ')})`;
|
|
477
478
|
});
|
|
478
479
|
return void qb[m](this.knex.raw(`(${conds.join(' or ')})`, core_1.Utils.flatten(value[op])));
|
|
479
480
|
}
|
|
480
|
-
return void qb[m](this.knex.raw(`${
|
|
481
|
+
return void qb[m](this.knex.raw(`${mapped.map(field => `${this.platform.quoteIdentifier(field)} = ?`).join(' and ')}`, core_1.Utils.flatten(value[op])));
|
|
481
482
|
}
|
|
482
483
|
if (singleTuple) {
|
|
483
484
|
const tmp = value[op].length === 1 && core_1.Utils.isPlainObject(value[op][0]) ? fields.map(f => value[op][0][f]) : value[op];
|
|
@@ -583,7 +584,7 @@ class QueryBuilderHelper {
|
|
|
583
584
|
return;
|
|
584
585
|
}
|
|
585
586
|
if (type === enums_1.QueryType.UPDATE) {
|
|
586
|
-
const returningProps = meta.hydrateProps.filter(prop => core_1.Utils.isRawSql(data[prop.
|
|
587
|
+
const returningProps = meta.hydrateProps.filter(prop => prop.fieldNames && core_1.Utils.isRawSql(data[prop.fieldNames[0]]));
|
|
587
588
|
if (returningProps.length > 0) {
|
|
588
589
|
qb.returning(returningProps.flatMap(prop => {
|
|
589
590
|
if (prop.hasConvertToJSValueSQL) {
|
|
@@ -730,5 +731,15 @@ class QueryBuilderHelper {
|
|
|
730
731
|
isTableNameAliasRequired(type) {
|
|
731
732
|
return [enums_1.QueryType.SELECT, enums_1.QueryType.COUNT].includes(type ?? enums_1.QueryType.SELECT);
|
|
732
733
|
}
|
|
734
|
+
// workaround for https://github.com/knex/knex/issues/5257
|
|
735
|
+
processOnConflictCondition(cond, schema) {
|
|
736
|
+
const meta = this.metadata.get(this.entityName);
|
|
737
|
+
const tableName = this.driver.getTableName(meta, { schema }, false);
|
|
738
|
+
for (const key of Object.keys(cond)) {
|
|
739
|
+
const mapped = this.mapper(key, enums_1.QueryType.INSERT);
|
|
740
|
+
core_1.Utils.renameKey(cond, key, tableName + '.' + mapped);
|
|
741
|
+
}
|
|
742
|
+
return cond;
|
|
743
|
+
}
|
|
733
744
|
}
|
|
734
745
|
exports.QueryBuilderHelper = QueryBuilderHelper;
|
|
@@ -34,9 +34,11 @@ export declare class DatabaseSchema {
|
|
|
34
34
|
hasNamespace(namespace: string): boolean;
|
|
35
35
|
hasNativeEnum(name: string): boolean;
|
|
36
36
|
getNamespaces(): string[];
|
|
37
|
-
static create(connection: AbstractSqlConnection, platform: AbstractSqlPlatform, config: Configuration, schemaName?: string, schemas?: string[]): Promise<DatabaseSchema>;
|
|
37
|
+
static create(connection: AbstractSqlConnection, platform: AbstractSqlPlatform, config: Configuration, schemaName?: string, schemas?: string[], takeTables?: (string | RegExp)[], skipTables?: (string | RegExp)[]): Promise<DatabaseSchema>;
|
|
38
38
|
static fromMetadata(metadata: EntityMetadata[], platform: AbstractSqlPlatform, config: Configuration, schemaName?: string): DatabaseSchema;
|
|
39
39
|
private static getSchemaName;
|
|
40
|
+
private static matchName;
|
|
41
|
+
private static isTableNameAllowed;
|
|
40
42
|
private static shouldHaveColumn;
|
|
41
43
|
toJSON(): Dictionary;
|
|
42
44
|
prune(schema: string | undefined, wildcardSchemaTables: string[]): void;
|
package/schema/DatabaseSchema.js
CHANGED
|
@@ -59,13 +59,13 @@ class DatabaseSchema {
|
|
|
59
59
|
getNamespaces() {
|
|
60
60
|
return [...this.namespaces];
|
|
61
61
|
}
|
|
62
|
-
static async create(connection, platform, config, schemaName, schemas) {
|
|
62
|
+
static async create(connection, platform, config, schemaName, schemas, takeTables, skipTables) {
|
|
63
63
|
const schema = new DatabaseSchema(platform, schemaName ?? config.get('schema') ?? platform.getDefaultSchemaName());
|
|
64
64
|
const allTables = await connection.execute(platform.getSchemaHelper().getListTablesSQL());
|
|
65
65
|
const parts = config.get('migrations').tableName.split('.');
|
|
66
66
|
const migrationsTableName = parts[1] ?? parts[0];
|
|
67
67
|
const migrationsSchemaName = parts.length > 1 ? parts[0] : config.get('schema', platform.getDefaultSchemaName());
|
|
68
|
-
const tables = allTables.filter(t => t.table_name !== migrationsTableName || (t.schema_name && t.schema_name !== migrationsSchemaName));
|
|
68
|
+
const tables = allTables.filter(t => this.isTableNameAllowed(t.table_name, takeTables, skipTables) && (t.table_name !== migrationsTableName || (t.schema_name && t.schema_name !== migrationsSchemaName)));
|
|
69
69
|
await platform.getSchemaHelper().loadInformationSchema(schema, connection, tables, schemas && schemas.length > 0 ? schemas : undefined);
|
|
70
70
|
return schema;
|
|
71
71
|
}
|
|
@@ -120,6 +120,15 @@ class DatabaseSchema {
|
|
|
120
120
|
static getSchemaName(meta, config, schema) {
|
|
121
121
|
return (meta.schema === '*' ? schema : meta.schema) ?? config.get('schema');
|
|
122
122
|
}
|
|
123
|
+
static matchName(name, nameToMatch) {
|
|
124
|
+
return typeof nameToMatch === 'string'
|
|
125
|
+
? name.toLocaleLowerCase() === nameToMatch.toLocaleLowerCase()
|
|
126
|
+
: nameToMatch.test(name);
|
|
127
|
+
}
|
|
128
|
+
static isTableNameAllowed(tableName, takeTables, skipTables) {
|
|
129
|
+
return ((takeTables?.some(tableNameToMatch => this.matchName(tableName, tableNameToMatch)) ?? true) &&
|
|
130
|
+
!(skipTables?.some(tableNameToMatch => this.matchName(tableName, tableNameToMatch)) ?? false));
|
|
131
|
+
}
|
|
123
132
|
static shouldHaveColumn(meta, prop) {
|
|
124
133
|
if (prop.persist === false || (prop.columnTypes?.length ?? 0) === 0) {
|
|
125
134
|
return false;
|
|
@@ -358,6 +358,9 @@ class SchemaComparator {
|
|
|
358
358
|
if (key1.referencedColumnNames.join('~').toLowerCase() !== key2.referencedColumnNames.join('~').toLowerCase()) {
|
|
359
359
|
return true;
|
|
360
360
|
}
|
|
361
|
+
if (key1.constraintName !== key2.constraintName) {
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
361
364
|
if (key1.referencedTableName !== key2.referencedTableName) {
|
|
362
365
|
return true;
|
|
363
366
|
}
|