@mikro-orm/knex 7.0.0-dev.9 → 7.0.0-dev.91
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 +11 -5
- package/AbstractSqlConnection.js +78 -32
- package/AbstractSqlDriver.d.ts +9 -5
- package/AbstractSqlDriver.js +267 -227
- package/AbstractSqlPlatform.js +5 -5
- package/PivotCollectionPersister.d.ts +8 -4
- package/PivotCollectionPersister.js +55 -31
- package/README.md +3 -2
- package/SqlEntityManager.d.ts +10 -2
- package/SqlEntityManager.js +11 -2
- package/dialects/mssql/MsSqlNativeQueryBuilder.d.ts +2 -0
- package/dialects/mssql/MsSqlNativeQueryBuilder.js +42 -3
- package/dialects/mysql/MySqlExceptionConverter.d.ts +3 -3
- package/dialects/mysql/MySqlExceptionConverter.js +4 -5
- package/dialects/mysql/MySqlSchemaHelper.js +2 -2
- package/dialects/postgresql/PostgreSqlTableCompiler.d.ts +1 -0
- package/dialects/postgresql/PostgreSqlTableCompiler.js +1 -0
- package/dialects/sqlite/BaseSqliteConnection.d.ts +3 -2
- package/dialects/sqlite/BaseSqliteConnection.js +2 -14
- package/dialects/sqlite/BaseSqlitePlatform.js +1 -2
- package/dialects/sqlite/SqliteExceptionConverter.d.ts +2 -2
- package/dialects/sqlite/SqliteExceptionConverter.js +6 -4
- package/dialects/sqlite/SqliteSchemaHelper.js +5 -6
- package/index.d.ts +2 -1
- package/index.js +2 -1
- package/package.json +5 -5
- package/plugin/index.d.ts +53 -0
- package/plugin/index.js +42 -0
- package/plugin/transformer.d.ts +115 -0
- package/plugin/transformer.js +883 -0
- package/query/ArrayCriteriaNode.d.ts +1 -0
- package/query/ArrayCriteriaNode.js +3 -0
- package/query/CriteriaNode.d.ts +4 -5
- package/query/CriteriaNode.js +13 -9
- package/query/CriteriaNodeFactory.js +12 -7
- package/query/NativeQueryBuilder.js +1 -1
- package/query/ObjectCriteriaNode.d.ts +1 -0
- package/query/ObjectCriteriaNode.js +35 -8
- package/query/QueryBuilder.d.ts +59 -10
- package/query/QueryBuilder.js +166 -50
- package/query/QueryBuilderHelper.d.ts +1 -1
- package/query/QueryBuilderHelper.js +20 -14
- package/query/ScalarCriteriaNode.d.ts +3 -3
- package/query/ScalarCriteriaNode.js +9 -7
- package/query/index.d.ts +1 -0
- package/query/index.js +1 -0
- package/query/raw.d.ts +59 -0
- package/query/raw.js +68 -0
- package/query/rawKnex.d.ts +58 -0
- package/query/rawKnex.js +72 -0
- package/schema/DatabaseSchema.js +25 -4
- package/schema/DatabaseTable.d.ts +5 -4
- package/schema/DatabaseTable.js +65 -34
- package/schema/SchemaComparator.js +5 -6
- package/schema/SchemaHelper.d.ts +2 -0
- package/schema/SchemaHelper.js +14 -10
- package/schema/SqlSchemaGenerator.d.ts +13 -6
- package/schema/SqlSchemaGenerator.js +41 -20
- package/typings.d.ts +85 -3
package/AbstractSqlPlatform.js
CHANGED
|
@@ -21,12 +21,12 @@ export class AbstractSqlPlatform extends Platform {
|
|
|
21
21
|
lookupExtensions(orm) {
|
|
22
22
|
SqlSchemaGenerator.register(orm);
|
|
23
23
|
}
|
|
24
|
-
/* v8 ignore next
|
|
24
|
+
/* v8 ignore next: kept for type inference only */
|
|
25
25
|
getSchemaGenerator(driver, em) {
|
|
26
26
|
return new SqlSchemaGenerator(em ?? driver);
|
|
27
27
|
}
|
|
28
|
-
/* v8 ignore next 4 */
|
|
29
28
|
/** @internal */
|
|
29
|
+
/* v8 ignore next */
|
|
30
30
|
createNativeQueryBuilder() {
|
|
31
31
|
return new NativeQueryBuilder(this);
|
|
32
32
|
}
|
|
@@ -43,13 +43,13 @@ export class AbstractSqlPlatform extends Platform {
|
|
|
43
43
|
return 'rollback';
|
|
44
44
|
}
|
|
45
45
|
getSavepointSQL(savepointName) {
|
|
46
|
-
return `savepoint ${savepointName}`;
|
|
46
|
+
return `savepoint ${this.quoteIdentifier(savepointName)}`;
|
|
47
47
|
}
|
|
48
48
|
getRollbackToSavepointSQL(savepointName) {
|
|
49
|
-
return `rollback to savepoint ${savepointName}`;
|
|
49
|
+
return `rollback to savepoint ${this.quoteIdentifier(savepointName)}`;
|
|
50
50
|
}
|
|
51
51
|
getReleaseSavepointSQL(savepointName) {
|
|
52
|
-
return `release savepoint ${savepointName}`;
|
|
52
|
+
return `release savepoint ${this.quoteIdentifier(savepointName)}`;
|
|
53
53
|
}
|
|
54
54
|
quoteValue(value) {
|
|
55
55
|
if (isRaw(value)) {
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import { type EntityMetadata, type EntityProperty, type Primary, type Transaction } from '@mikro-orm/core';
|
|
1
|
+
import { type Dictionary, type EntityMetadata, type EntityProperty, type Primary, type Transaction } from '@mikro-orm/core';
|
|
2
2
|
import { type AbstractSqlDriver } from './AbstractSqlDriver.js';
|
|
3
3
|
export declare class PivotCollectionPersister<Entity extends object> {
|
|
4
4
|
private readonly meta;
|
|
5
5
|
private readonly driver;
|
|
6
6
|
private readonly ctx?;
|
|
7
7
|
private readonly schema?;
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly loggerContext?;
|
|
9
9
|
private readonly inserts;
|
|
10
|
+
private readonly upserts;
|
|
10
11
|
private readonly deletes;
|
|
11
12
|
private readonly batchSize;
|
|
12
13
|
private order;
|
|
13
|
-
constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: Transaction | undefined, schema?: string | undefined);
|
|
14
|
-
enqueueUpdate(prop: EntityProperty<Entity>, insertDiff: Primary<Entity>[][], deleteDiff: Primary<Entity>[][] | boolean, pks: Primary<Entity>[]): void;
|
|
14
|
+
constructor(meta: EntityMetadata<Entity>, driver: AbstractSqlDriver, ctx?: Transaction | undefined, schema?: string | undefined, loggerContext?: Dictionary | undefined);
|
|
15
|
+
enqueueUpdate(prop: EntityProperty<Entity>, insertDiff: Primary<Entity>[][], deleteDiff: Primary<Entity>[][] | boolean, pks: Primary<Entity>[], isInitialized?: boolean): void;
|
|
15
16
|
private enqueueInsert;
|
|
17
|
+
private enqueueUpsert;
|
|
18
|
+
private createInsertStatement;
|
|
16
19
|
private enqueueDelete;
|
|
20
|
+
private collectStatements;
|
|
17
21
|
execute(): Promise<void>;
|
|
18
22
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Utils, } from '@mikro-orm/core';
|
|
2
1
|
class InsertStatement {
|
|
3
2
|
keys;
|
|
4
3
|
data;
|
|
@@ -38,22 +37,28 @@ export class PivotCollectionPersister {
|
|
|
38
37
|
driver;
|
|
39
38
|
ctx;
|
|
40
39
|
schema;
|
|
41
|
-
|
|
40
|
+
loggerContext;
|
|
42
41
|
inserts = new Map();
|
|
42
|
+
upserts = new Map();
|
|
43
43
|
deletes = new Map();
|
|
44
44
|
batchSize;
|
|
45
45
|
order = 0;
|
|
46
|
-
constructor(meta, driver, ctx, schema) {
|
|
46
|
+
constructor(meta, driver, ctx, schema, loggerContext) {
|
|
47
47
|
this.meta = meta;
|
|
48
48
|
this.driver = driver;
|
|
49
49
|
this.ctx = ctx;
|
|
50
50
|
this.schema = schema;
|
|
51
|
-
this.
|
|
51
|
+
this.loggerContext = loggerContext;
|
|
52
52
|
this.batchSize = this.driver.config.get('batchSize');
|
|
53
53
|
}
|
|
54
|
-
enqueueUpdate(prop, insertDiff, deleteDiff, pks) {
|
|
54
|
+
enqueueUpdate(prop, insertDiff, deleteDiff, pks, isInitialized = true) {
|
|
55
55
|
if (insertDiff.length) {
|
|
56
|
-
|
|
56
|
+
if (isInitialized) {
|
|
57
|
+
this.enqueueInsert(prop, insertDiff, pks);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
this.enqueueUpsert(prop, insertDiff, pks);
|
|
61
|
+
}
|
|
57
62
|
}
|
|
58
63
|
if (deleteDiff === true || (Array.isArray(deleteDiff) && deleteDiff.length)) {
|
|
59
64
|
this.enqueueDelete(prop, deleteDiff, pks);
|
|
@@ -61,17 +66,29 @@ export class PivotCollectionPersister {
|
|
|
61
66
|
}
|
|
62
67
|
enqueueInsert(prop, insertDiff, pks) {
|
|
63
68
|
for (const fks of insertDiff) {
|
|
64
|
-
const
|
|
65
|
-
const keys = prop.owner
|
|
66
|
-
? [...prop.inverseJoinColumns, ...prop.joinColumns]
|
|
67
|
-
: [...prop.joinColumns, ...prop.inverseJoinColumns];
|
|
68
|
-
const statement = new InsertStatement(keys, data, this.order++);
|
|
69
|
+
const statement = this.createInsertStatement(prop, fks, pks);
|
|
69
70
|
const hash = statement.getHash();
|
|
70
71
|
if (prop.owner || !this.inserts.has(hash)) {
|
|
71
72
|
this.inserts.set(hash, statement);
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
}
|
|
76
|
+
enqueueUpsert(prop, insertDiff, pks) {
|
|
77
|
+
for (const fks of insertDiff) {
|
|
78
|
+
const statement = this.createInsertStatement(prop, fks, pks);
|
|
79
|
+
const hash = statement.getHash();
|
|
80
|
+
if (prop.owner || !this.upserts.has(hash)) {
|
|
81
|
+
this.upserts.set(hash, statement);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
createInsertStatement(prop, fks, pks) {
|
|
86
|
+
const data = prop.owner ? [...fks, ...pks] : [...pks, ...fks];
|
|
87
|
+
const keys = prop.owner
|
|
88
|
+
? [...prop.inverseJoinColumns, ...prop.joinColumns]
|
|
89
|
+
: [...prop.joinColumns, ...prop.inverseJoinColumns];
|
|
90
|
+
return new InsertStatement(keys, data, this.order++);
|
|
91
|
+
}
|
|
75
92
|
enqueueDelete(prop, deleteDiff, pks) {
|
|
76
93
|
if (deleteDiff === true) {
|
|
77
94
|
const statement = new DeleteStatement(prop.joinColumns, pks);
|
|
@@ -87,6 +104,13 @@ export class PivotCollectionPersister {
|
|
|
87
104
|
this.deletes.set(statement.getHash(), statement);
|
|
88
105
|
}
|
|
89
106
|
}
|
|
107
|
+
collectStatements(statements) {
|
|
108
|
+
const items = [];
|
|
109
|
+
for (const statement of statements.values()) {
|
|
110
|
+
items[statement.order] = statement.getData();
|
|
111
|
+
}
|
|
112
|
+
return items.filter(Boolean);
|
|
113
|
+
}
|
|
90
114
|
async execute() {
|
|
91
115
|
if (this.deletes.size > 0) {
|
|
92
116
|
const deletes = [...this.deletes.values()];
|
|
@@ -99,37 +123,37 @@ export class PivotCollectionPersister {
|
|
|
99
123
|
await this.driver.nativeDelete(this.meta.className, cond, {
|
|
100
124
|
ctx: this.ctx,
|
|
101
125
|
schema: this.schema,
|
|
126
|
+
loggerContext: this.loggerContext,
|
|
102
127
|
});
|
|
103
128
|
}
|
|
104
129
|
}
|
|
105
|
-
if (this.inserts.size
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
for (const insert of this.inserts.values()) {
|
|
110
|
-
items[insert.order] = insert.getData();
|
|
111
|
-
}
|
|
112
|
-
items = items.filter(i => i);
|
|
113
|
-
if (this.platform.allowsMultiInsert()) {
|
|
114
|
-
for (let i = 0; i < items.length; i += this.batchSize) {
|
|
115
|
-
const chunk = items.slice(i, i + this.batchSize);
|
|
130
|
+
if (this.inserts.size > 0) {
|
|
131
|
+
const filtered = this.collectStatements(this.inserts);
|
|
132
|
+
for (let i = 0; i < filtered.length; i += this.batchSize) {
|
|
133
|
+
const chunk = filtered.slice(i, i + this.batchSize);
|
|
116
134
|
await this.driver.nativeInsertMany(this.meta.className, chunk, {
|
|
117
135
|
ctx: this.ctx,
|
|
118
136
|
schema: this.schema,
|
|
119
137
|
convertCustomTypes: false,
|
|
120
138
|
processCollections: false,
|
|
139
|
+
loggerContext: this.loggerContext,
|
|
121
140
|
});
|
|
122
141
|
}
|
|
123
|
-
/* v8 ignore start */
|
|
124
142
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
.
|
|
131
|
-
|
|
143
|
+
if (this.upserts.size > 0) {
|
|
144
|
+
const filtered = this.collectStatements(this.upserts);
|
|
145
|
+
for (let i = 0; i < filtered.length; i += this.batchSize) {
|
|
146
|
+
const chunk = filtered.slice(i, i + this.batchSize);
|
|
147
|
+
await this.driver.nativeUpdateMany(this.meta.className, [], chunk, {
|
|
148
|
+
ctx: this.ctx,
|
|
149
|
+
schema: this.schema,
|
|
150
|
+
convertCustomTypes: false,
|
|
151
|
+
processCollections: false,
|
|
152
|
+
upsert: true,
|
|
153
|
+
onConflictAction: 'ignore',
|
|
154
|
+
loggerContext: this.loggerContext,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
132
157
|
}
|
|
133
|
-
/* v8 ignore stop */
|
|
134
158
|
}
|
|
135
159
|
}
|
package/README.md
CHANGED
|
@@ -11,7 +11,6 @@ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-or
|
|
|
11
11
|
[](https://discord.gg/w8bjxFHS7X)
|
|
12
12
|
[](https://www.npmjs.com/package/@mikro-orm/core)
|
|
13
13
|
[](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
|
|
14
|
-
[](https://codeclimate.com/github/mikro-orm/mikro-orm/maintainability)
|
|
15
14
|
[](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
|
|
16
15
|
|
|
17
16
|
## 🤔 Unit of What?
|
|
@@ -141,7 +140,7 @@ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit m
|
|
|
141
140
|
- [Composite and Foreign Keys as Primary Key](https://mikro-orm.io/docs/composite-keys)
|
|
142
141
|
- [Filters](https://mikro-orm.io/docs/filters)
|
|
143
142
|
- [Using `QueryBuilder`](https://mikro-orm.io/docs/query-builder)
|
|
144
|
-
- [
|
|
143
|
+
- [Populating relations](https://mikro-orm.io/docs/populating-relations)
|
|
145
144
|
- [Property Validation](https://mikro-orm.io/docs/property-validation)
|
|
146
145
|
- [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
|
|
147
146
|
- [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
|
|
@@ -382,6 +381,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
|
|
|
382
381
|
|
|
383
382
|
Please ⭐️ this repository if this project helped you!
|
|
384
383
|
|
|
384
|
+
> If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
|
|
385
|
+
|
|
385
386
|
## 📝 License
|
|
386
387
|
|
|
387
388
|
Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
|
package/SqlEntityManager.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { EntityManager, type AnyEntity, type ConnectionType, type EntityData, type EntityName, type EntityRepository, type GetRepository, type QueryResult, type FilterQuery, type LoggingOptions, type RawQueryFragment } from '@mikro-orm/core';
|
|
1
|
+
import { type EntitySchemaWithMeta, EntityManager, type AnyEntity, type ConnectionType, type EntityData, type EntityName, type EntityRepository, type GetRepository, type QueryResult, type FilterQuery, type LoggingOptions, type RawQueryFragment } from '@mikro-orm/core';
|
|
2
2
|
import type { AbstractSqlDriver } from './AbstractSqlDriver.js';
|
|
3
3
|
import type { NativeQueryBuilder } from './query/NativeQueryBuilder.js';
|
|
4
4
|
import type { QueryBuilder } from './query/QueryBuilder.js';
|
|
5
5
|
import type { SqlEntityRepository } from './SqlEntityRepository.js';
|
|
6
|
+
import type { Kysely } from 'kysely';
|
|
7
|
+
import type { InferKyselyDB } from './typings.js';
|
|
8
|
+
import { type MikroKyselyPluginOptions } from './plugin/index.js';
|
|
9
|
+
export interface GetKyselyOptions extends MikroKyselyPluginOptions {
|
|
10
|
+
type?: ConnectionType;
|
|
11
|
+
}
|
|
6
12
|
/**
|
|
7
13
|
* @inheritDoc
|
|
8
14
|
*/
|
|
@@ -18,8 +24,10 @@ export declare class SqlEntityManager<Driver extends AbstractSqlDriver = Abstrac
|
|
|
18
24
|
/**
|
|
19
25
|
* Returns configured Kysely instance.
|
|
20
26
|
*/
|
|
21
|
-
getKysely(
|
|
27
|
+
getKysely<TDB = undefined, TOptions extends GetKyselyOptions = GetKyselyOptions>(options?: TOptions): Kysely<TDB extends undefined ? InferKyselyDB<EntitiesFromManager<this>, TOptions> : TDB>;
|
|
22
28
|
execute<T extends QueryResult | EntityData<AnyEntity> | EntityData<AnyEntity>[] = EntityData<AnyEntity>[]>(query: string | NativeQueryBuilder | RawQueryFragment, params?: any[], method?: 'all' | 'get' | 'run', loggerContext?: LoggingOptions): Promise<T>;
|
|
23
29
|
getRepository<T extends object, U extends EntityRepository<T> = SqlEntityRepository<T>>(entityName: EntityName<T>): GetRepository<T, U>;
|
|
24
30
|
protected applyDiscriminatorCondition<Entity extends object>(entityName: string, where: FilterQuery<Entity>): FilterQuery<Entity>;
|
|
25
31
|
}
|
|
32
|
+
type EntitiesFromManager<TEntityManager extends EntityManager<any>> = NonNullable<TEntityManager['~entities']> extends any[] ? (Extract<NonNullable<TEntityManager['~entities']>[number], EntitySchemaWithMeta>) : never;
|
|
33
|
+
export {};
|
package/SqlEntityManager.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EntityManager, } from '@mikro-orm/core';
|
|
2
|
+
import { MikroKyselyPlugin } from './plugin/index.js';
|
|
2
3
|
/**
|
|
3
4
|
* @inheritDoc
|
|
4
5
|
*/
|
|
@@ -19,8 +20,16 @@ export class SqlEntityManager extends EntityManager {
|
|
|
19
20
|
/**
|
|
20
21
|
* Returns configured Kysely instance.
|
|
21
22
|
*/
|
|
22
|
-
getKysely(
|
|
23
|
-
|
|
23
|
+
getKysely(options = {}) {
|
|
24
|
+
let kysely = this.getConnection(options.type).getClient();
|
|
25
|
+
if (options.columnNamingStrategy != null
|
|
26
|
+
|| options.tableNamingStrategy != null
|
|
27
|
+
|| options.processOnCreateHooks != null
|
|
28
|
+
|| options.processOnUpdateHooks != null
|
|
29
|
+
|| options.convertValues != null) {
|
|
30
|
+
kysely = kysely.withPlugin(new MikroKyselyPlugin(this, options));
|
|
31
|
+
}
|
|
32
|
+
return kysely;
|
|
24
33
|
}
|
|
25
34
|
async execute(query, params = [], method = 'all', loggerContext) {
|
|
26
35
|
return this.getDriver().execute(query, params, method, this.getContext(false).getTransactionContext(), loggerContext);
|
|
@@ -5,6 +5,8 @@ export declare class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
5
5
|
sql: string;
|
|
6
6
|
params: unknown[];
|
|
7
7
|
};
|
|
8
|
+
protected compileInsert(): void;
|
|
9
|
+
private appendOutputTable;
|
|
8
10
|
private compileUpsert;
|
|
9
11
|
protected compileSelect(): void;
|
|
10
12
|
protected addLockClause(): void;
|
|
@@ -12,6 +12,10 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
12
12
|
if (this.options.flags?.has(QueryFlag.IDENTITY_INSERT)) {
|
|
13
13
|
this.parts.push(`set identity_insert ${this.getTableName()} on;`);
|
|
14
14
|
}
|
|
15
|
+
const { prefix, suffix } = this.appendOutputTable();
|
|
16
|
+
if (prefix) {
|
|
17
|
+
this.parts.push(prefix);
|
|
18
|
+
}
|
|
15
19
|
if (this.options.comment) {
|
|
16
20
|
this.parts.push(...this.options.comment.map(comment => `/* ${comment} */`));
|
|
17
21
|
}
|
|
@@ -37,7 +41,11 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
37
41
|
this.compileTruncate();
|
|
38
42
|
break;
|
|
39
43
|
}
|
|
40
|
-
if (
|
|
44
|
+
if (suffix) {
|
|
45
|
+
this.parts[this.parts.length - 1] += ';';
|
|
46
|
+
this.parts.push(suffix);
|
|
47
|
+
}
|
|
48
|
+
else if ([QueryType.INSERT, QueryType.UPDATE, QueryType.DELETE].includes(this.type)) {
|
|
41
49
|
this.parts[this.parts.length - 1] += '; select @@rowcount;';
|
|
42
50
|
}
|
|
43
51
|
}
|
|
@@ -46,6 +54,37 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
46
54
|
}
|
|
47
55
|
return this.combineParts();
|
|
48
56
|
}
|
|
57
|
+
compileInsert() {
|
|
58
|
+
if (!this.options.data) {
|
|
59
|
+
throw new Error('No data provided');
|
|
60
|
+
}
|
|
61
|
+
this.parts.push('insert');
|
|
62
|
+
this.addHintComment();
|
|
63
|
+
this.parts.push(`into ${this.getTableName()}`);
|
|
64
|
+
if (Object.keys(this.options.data).length === 0) {
|
|
65
|
+
this.addOutputClause('inserted');
|
|
66
|
+
this.parts.push('default values');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const parts = this.processInsertData();
|
|
70
|
+
if (this.options.flags?.has(QueryFlag.OUTPUT_TABLE)) {
|
|
71
|
+
this.parts[this.parts.length - 2] += ' into #out ';
|
|
72
|
+
}
|
|
73
|
+
this.parts.push(parts.join(', '));
|
|
74
|
+
}
|
|
75
|
+
appendOutputTable() {
|
|
76
|
+
if (!this.options.flags?.has(QueryFlag.OUTPUT_TABLE)) {
|
|
77
|
+
return { prefix: '', suffix: '' };
|
|
78
|
+
}
|
|
79
|
+
const returningFields = this.options.returning;
|
|
80
|
+
const selections = returningFields
|
|
81
|
+
.map(field => `[t].${this.platform.quoteIdentifier(field)}`)
|
|
82
|
+
.join(',');
|
|
83
|
+
return {
|
|
84
|
+
prefix: `select top(0) ${selections} into #out from ${this.getTableName()} as t left join ${this.getTableName()} on 0 = 1;`,
|
|
85
|
+
suffix: `select ${selections} from #out as t; drop table #out`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
49
88
|
compileUpsert() {
|
|
50
89
|
const clause = this.options.onConflict;
|
|
51
90
|
const dataAsArray = Utils.asArray(this.options.data);
|
|
@@ -82,7 +121,7 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
82
121
|
}
|
|
83
122
|
this.parts.push('then update set');
|
|
84
123
|
if (!clause.merge || Array.isArray(clause.merge)) {
|
|
85
|
-
const parts = keys
|
|
124
|
+
const parts = (clause.merge || keys)
|
|
86
125
|
.filter(field => !Array.isArray(clause.fields) || !clause.fields.includes(field))
|
|
87
126
|
.map((column) => `${this.quote(column)} = tsource.${this.quote(column)}`);
|
|
88
127
|
this.parts.push(parts.join(', '));
|
|
@@ -129,7 +168,7 @@ export class MsSqlNativeQueryBuilder extends NativeQueryBuilder {
|
|
|
129
168
|
this.parts.push(`order by ${this.options.orderBy}`);
|
|
130
169
|
}
|
|
131
170
|
if (this.options.offset != null) {
|
|
132
|
-
/* v8 ignore next
|
|
171
|
+
/* v8 ignore next */
|
|
133
172
|
if (!this.options.orderBy) {
|
|
134
173
|
throw new Error('Order by clause is required for pagination');
|
|
135
174
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ExceptionConverter, type Dictionary, type DriverException } from '@mikro-orm/core';
|
|
2
2
|
export declare class MySqlExceptionConverter extends ExceptionConverter {
|
|
3
3
|
/**
|
|
4
|
-
* @
|
|
5
|
-
* @
|
|
6
|
-
* @
|
|
4
|
+
* @see http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html
|
|
5
|
+
* @see http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
|
|
6
|
+
* @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractMySQLDriver.php
|
|
7
7
|
*/
|
|
8
8
|
convertException(exception: Error & Dictionary): DriverException;
|
|
9
9
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { DeadlockException, LockWaitTimeoutException, TableExistsException, TableNotFoundException, ForeignKeyConstraintViolationException, UniqueConstraintViolationException, InvalidFieldNameException, NonUniqueFieldNameException, SyntaxErrorException, ConnectionException, NotNullConstraintViolationException, ExceptionConverter, CheckConstraintViolationException, } from '@mikro-orm/core';
|
|
2
2
|
export class MySqlExceptionConverter extends ExceptionConverter {
|
|
3
3
|
/**
|
|
4
|
-
* @
|
|
5
|
-
* @
|
|
6
|
-
* @
|
|
4
|
+
* @see http://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html
|
|
5
|
+
* @see http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
|
|
6
|
+
* @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractMySQLDriver.php
|
|
7
7
|
*/
|
|
8
8
|
convertException(exception) {
|
|
9
|
-
/* v8 ignore
|
|
9
|
+
/* v8 ignore next */
|
|
10
10
|
switch (exception.errno) {
|
|
11
11
|
case 1213:
|
|
12
12
|
return new DeadlockException(exception);
|
|
@@ -75,7 +75,6 @@ export class MySqlExceptionConverter extends ExceptionConverter {
|
|
|
75
75
|
case 1566:
|
|
76
76
|
return new NotNullConstraintViolationException(exception);
|
|
77
77
|
}
|
|
78
|
-
/* v8 ignore stop */
|
|
79
78
|
return super.convertException(exception);
|
|
80
79
|
}
|
|
81
80
|
}
|
|
@@ -78,7 +78,7 @@ export class MySqlSchemaHelper extends SchemaHelper {
|
|
|
78
78
|
return ret;
|
|
79
79
|
}
|
|
80
80
|
getCreateIndexSQL(tableName, index, partialExpression = false) {
|
|
81
|
-
/* v8 ignore next
|
|
81
|
+
/* v8 ignore next */
|
|
82
82
|
if (index.expression && !partialExpression) {
|
|
83
83
|
return index.expression;
|
|
84
84
|
}
|
|
@@ -146,7 +146,7 @@ export class MySqlSchemaHelper extends SchemaHelper {
|
|
|
146
146
|
return ret;
|
|
147
147
|
}
|
|
148
148
|
async getAllChecks(connection, tables) {
|
|
149
|
-
/* v8 ignore next
|
|
149
|
+
/* v8 ignore next */
|
|
150
150
|
if (!(await this.supportsCheckConstraints(connection))) {
|
|
151
151
|
return {};
|
|
152
152
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
|
|
2
2
|
export declare abstract class BaseSqliteConnection extends AbstractSqlConnection {
|
|
3
|
-
connect(
|
|
4
|
-
|
|
3
|
+
connect(options?: {
|
|
4
|
+
skipOnConnect?: boolean;
|
|
5
|
+
}): Promise<void>;
|
|
5
6
|
}
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import { dirname } from 'node:path';
|
|
2
1
|
import { CompiledQuery } from 'kysely';
|
|
3
|
-
import { Utils } from '@mikro-orm/core';
|
|
4
2
|
import { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
|
|
5
3
|
export class BaseSqliteConnection extends AbstractSqlConnection {
|
|
6
|
-
async connect(
|
|
7
|
-
await super.connect();
|
|
8
|
-
if (simple) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
const dbName = this.config.get('dbName');
|
|
12
|
-
if (dbName && dbName !== ':memory:') {
|
|
13
|
-
Utils.ensureDir(dirname(this.config.get('dbName')));
|
|
14
|
-
}
|
|
4
|
+
async connect(options) {
|
|
5
|
+
await super.connect(options);
|
|
15
6
|
await this.client.executeQuery(CompiledQuery.raw('pragma foreign_keys = on'));
|
|
16
7
|
}
|
|
17
|
-
getClientUrl() {
|
|
18
|
-
return '';
|
|
19
|
-
}
|
|
20
8
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Utils } from '@mikro-orm/core';
|
|
2
1
|
import { AbstractSqlPlatform } from '../../AbstractSqlPlatform.js';
|
|
3
2
|
import { SqliteNativeQueryBuilder } from './SqliteNativeQueryBuilder.js';
|
|
4
3
|
import { SqliteSchemaHelper } from './SqliteSchemaHelper.js';
|
|
@@ -29,7 +28,7 @@ export class BaseSqlitePlatform extends AbstractSqlPlatform {
|
|
|
29
28
|
return ['begin'];
|
|
30
29
|
}
|
|
31
30
|
getEnumTypeDeclarationSQL(column) {
|
|
32
|
-
if (column.items?.every(item =>
|
|
31
|
+
if (column.items?.every(item => typeof item === 'string')) {
|
|
33
32
|
return 'text';
|
|
34
33
|
}
|
|
35
34
|
/* v8 ignore next */
|
|
@@ -2,8 +2,8 @@ import { ExceptionConverter, type Dictionary, type DriverException } from '@mikr
|
|
|
2
2
|
export declare class SqliteExceptionConverter extends ExceptionConverter {
|
|
3
3
|
/**
|
|
4
4
|
* @inheritDoc
|
|
5
|
-
* @
|
|
6
|
-
* @
|
|
5
|
+
* @see http://www.sqlite.org/c3ref/c_abort.html
|
|
6
|
+
* @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractSQLiteDriver.php
|
|
7
7
|
*/
|
|
8
8
|
convertException(exception: Error & Dictionary): DriverException;
|
|
9
9
|
}
|
|
@@ -2,11 +2,11 @@ import { ConnectionException, ExceptionConverter, InvalidFieldNameException, Loc
|
|
|
2
2
|
export class SqliteExceptionConverter extends ExceptionConverter {
|
|
3
3
|
/**
|
|
4
4
|
* @inheritDoc
|
|
5
|
-
* @
|
|
6
|
-
* @
|
|
5
|
+
* @see http://www.sqlite.org/c3ref/c_abort.html
|
|
6
|
+
* @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractSQLiteDriver.php
|
|
7
7
|
*/
|
|
8
8
|
convertException(exception) {
|
|
9
|
-
/* v8 ignore
|
|
9
|
+
/* v8 ignore next */
|
|
10
10
|
if (exception.message.includes('database is locked')) {
|
|
11
11
|
return new LockWaitTimeoutException(exception);
|
|
12
12
|
}
|
|
@@ -19,6 +19,7 @@ export class SqliteExceptionConverter extends ExceptionConverter {
|
|
|
19
19
|
if (exception.message.includes('may not be NULL') || exception.message.includes('NOT NULL constraint failed')) {
|
|
20
20
|
return new NotNullConstraintViolationException(exception);
|
|
21
21
|
}
|
|
22
|
+
/* v8 ignore next */
|
|
22
23
|
if (exception.message.includes('CHECK constraint failed')) {
|
|
23
24
|
return new CheckConstraintViolationException(exception);
|
|
24
25
|
}
|
|
@@ -37,16 +38,17 @@ export class SqliteExceptionConverter extends ExceptionConverter {
|
|
|
37
38
|
if (exception.message.includes('syntax error')) {
|
|
38
39
|
return new SyntaxErrorException(exception);
|
|
39
40
|
}
|
|
41
|
+
/* v8 ignore next */
|
|
40
42
|
if (exception.message.includes('attempt to write a readonly database')) {
|
|
41
43
|
return new ReadOnlyException(exception);
|
|
42
44
|
}
|
|
45
|
+
/* v8 ignore next */
|
|
43
46
|
if (exception.message.includes('unable to open database file')) {
|
|
44
47
|
return new ConnectionException(exception);
|
|
45
48
|
}
|
|
46
49
|
if (exception.message.includes('FOREIGN KEY constraint failed')) {
|
|
47
50
|
return new ForeignKeyConstraintViolationException(exception);
|
|
48
51
|
}
|
|
49
|
-
/* v8 ignore stop */
|
|
50
52
|
return super.convertException(exception);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
@@ -114,7 +114,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
114
114
|
}).join(';\n');
|
|
115
115
|
}
|
|
116
116
|
getCreateIndexSQL(tableName, index) {
|
|
117
|
-
/* v8 ignore next
|
|
117
|
+
/* v8 ignore next */
|
|
118
118
|
if (index.expression) {
|
|
119
119
|
return index.expression;
|
|
120
120
|
}
|
|
@@ -134,7 +134,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
134
134
|
const constraints = [];
|
|
135
135
|
// extract all columns definitions
|
|
136
136
|
let columnsDef = sql.replaceAll('\n', '').match(new RegExp(`create table [\`"']?.*?[\`"']? \\((.*)\\)`, 'i'))?.[1];
|
|
137
|
-
/* v8 ignore
|
|
137
|
+
/* v8 ignore next */
|
|
138
138
|
if (columnsDef) {
|
|
139
139
|
if (columnsDef.includes(', constraint ')) {
|
|
140
140
|
constraints.push(...columnsDef.substring(columnsDef.indexOf(', constraint') + 2).split(', '));
|
|
@@ -150,7 +150,6 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
/* v8 ignore stop */
|
|
154
153
|
return { columns, constraints };
|
|
155
154
|
}
|
|
156
155
|
async getColumns(connection, tableName, schemaName) {
|
|
@@ -167,7 +166,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
167
166
|
if (col.hidden > 1) {
|
|
168
167
|
/* v8 ignore next */
|
|
169
168
|
const storage = col.hidden === 2 ? 'virtual' : 'stored';
|
|
170
|
-
const re = `(generated always)? as \\((.*)\\)( ${storage})
|
|
169
|
+
const re = new RegExp(`(generated always)? as \\((.*)\\)( ${storage})?$`, 'i');
|
|
171
170
|
const match = columnDefinitions[col.name].definition.match(re);
|
|
172
171
|
if (match) {
|
|
173
172
|
generated = `${match[2]} ${storage}`;
|
|
@@ -194,7 +193,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
194
193
|
// check constraints are defined as (note that last closing paren is missing):
|
|
195
194
|
// `type` text check (`type` in ('local', 'global')
|
|
196
195
|
const match = item.match(/[`["']([^`\]"']+)[`\]"'] text check \(.* \((.*)\)/i);
|
|
197
|
-
/* v8 ignore next
|
|
196
|
+
/* v8 ignore next */
|
|
198
197
|
if (match) {
|
|
199
198
|
o[match[1]] = match[2].split(',').map((item) => item.trim().match(/^\(?'(.*)'/)[1]);
|
|
200
199
|
}
|
|
@@ -321,7 +320,7 @@ export class SqliteSchemaHelper extends SchemaHelper {
|
|
|
321
320
|
for (const index of Object.values(diff.changedIndexes)) {
|
|
322
321
|
this.append(ret, this.dropIndex(diff.name, index));
|
|
323
322
|
}
|
|
324
|
-
/* v8 ignore next
|
|
323
|
+
/* v8 ignore next */
|
|
325
324
|
if (!safe && Object.values(diff.removedColumns).length > 0) {
|
|
326
325
|
this.append(ret, this.getDropColumnsSQL(tableName, Object.values(diff.removedColumns), schemaName));
|
|
327
326
|
}
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module knex
|
|
4
4
|
*/
|
|
5
|
-
/** @ignore */
|
|
6
5
|
export { Kysely } from 'kysely';
|
|
7
6
|
export * from '@mikro-orm/core';
|
|
8
7
|
export * from './AbstractSqlConnection.js';
|
|
@@ -11,8 +10,10 @@ export * from './AbstractSqlPlatform.js';
|
|
|
11
10
|
export * from './SqlEntityManager.js';
|
|
12
11
|
export * from './SqlEntityRepository.js';
|
|
13
12
|
export * from './query/index.js';
|
|
13
|
+
export { raw } from './query/index.js';
|
|
14
14
|
export * from './schema/index.js';
|
|
15
15
|
export * from './dialects/index.js';
|
|
16
16
|
export * from './typings.js';
|
|
17
|
+
export * from './plugin/index.js';
|
|
17
18
|
export { SqlEntityManager as EntityManager } from './SqlEntityManager.js';
|
|
18
19
|
export { SqlEntityRepository as EntityRepository } from './SqlEntityRepository.js';
|
package/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module knex
|
|
4
4
|
*/
|
|
5
|
-
/** @ignore */
|
|
6
5
|
export { Kysely } from 'kysely';
|
|
7
6
|
export * from '@mikro-orm/core';
|
|
8
7
|
export * from './AbstractSqlConnection.js';
|
|
@@ -11,8 +10,10 @@ export * from './AbstractSqlPlatform.js';
|
|
|
11
10
|
export * from './SqlEntityManager.js';
|
|
12
11
|
export * from './SqlEntityRepository.js';
|
|
13
12
|
export * from './query/index.js';
|
|
13
|
+
export { raw } from './query/index.js';
|
|
14
14
|
export * from './schema/index.js';
|
|
15
15
|
export * from './dialects/index.js';
|
|
16
16
|
export * from './typings.js';
|
|
17
|
+
export * from './plugin/index.js';
|
|
17
18
|
export { SqlEntityManager as EntityManager } from './SqlEntityManager.js';
|
|
18
19
|
export { SqlEntityRepository as EntityRepository } from './SqlEntityRepository.js';
|