objection 3.9.1 → 4.0.0-rc.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.
- package/lib/dbErrors/LICENSE +21 -0
- package/lib/dbErrors/errorCodes/mssql.js +19 -0
- package/lib/dbErrors/errorCodes/mysql.js +805 -0
- package/lib/dbErrors/errorCodes/postgres.js +241 -0
- package/lib/dbErrors/errors/CheckViolationError.js +10 -0
- package/lib/dbErrors/errors/ConstraintViolationError.js +3 -0
- package/lib/dbErrors/errors/DBError.js +9 -0
- package/lib/dbErrors/errors/DataError.js +3 -0
- package/lib/dbErrors/errors/ForeignKeyViolationError.js +11 -0
- package/lib/dbErrors/errors/NotNullViolationError.js +12 -0
- package/lib/dbErrors/errors/UniqueViolationError.js +12 -0
- package/lib/dbErrors/index.js +59 -0
- package/lib/dbErrors/parsers/mssql/DBError/CheckViolationError/parser.js +28 -0
- package/lib/dbErrors/parsers/mssql/DBError/DataError/parser.js +25 -0
- package/lib/dbErrors/parsers/mssql/DBError/ForeignKeyViolationError/parser.js +39 -0
- package/lib/dbErrors/parsers/mssql/DBError/NotNullViolationError/parser.js +30 -0
- package/lib/dbErrors/parsers/mssql/DBError/UniqueViolationError/parser.js +53 -0
- package/lib/dbErrors/parsers/mssql/DBError/parser.js +51 -0
- package/lib/dbErrors/parsers/mssql/DBError/util.js +16 -0
- package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +43 -0
- package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/NotNullViolationError/parser.js +29 -0
- package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/UniqueViolationError/parser.js +27 -0
- package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/parser.js +23 -0
- package/lib/dbErrors/parsers/mysql/DBError/DataError/parser.js +24 -0
- package/lib/dbErrors/parsers/mysql/DBError/parser.js +28 -0
- package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/CheckViolationError/parser.js +18 -0
- package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +18 -0
- package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/NotNullViolationError/parser.js +18 -0
- package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/UniqueViolationError/parser.js +40 -0
- package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/parser.js +25 -0
- package/lib/dbErrors/parsers/postgres/DBError/DataError/parser.js +16 -0
- package/lib/dbErrors/parsers/postgres/DBError/parser.js +27 -0
- package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/CheckViolationError/parser.js +20 -0
- package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +20 -0
- package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/NotNullViolationError/parser.js +27 -0
- package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/UniqueViolationError/parser.js +28 -0
- package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/parser.js +24 -0
- package/lib/dbErrors/parsers/sqlite/DBError/parser.js +23 -0
- package/lib/dbErrors/utils/sqlState.js +3 -0
- package/lib/initialize.js +1 -7
- package/lib/model/AjvValidator.js +51 -117
- package/lib/model/Model.js +84 -59
- package/lib/model/ModifierNotFoundError.js +1 -7
- package/lib/model/NotFoundError.js +1 -7
- package/lib/model/RelationDoesNotExistError.js +1 -7
- package/lib/model/ValidationError.js +3 -10
- package/lib/model/Validator.js +1 -7
- package/lib/model/getModel.js +7 -6
- package/lib/model/inheritModel.js +1 -7
- package/lib/model/modelBindKnex.js +4 -10
- package/lib/model/modelClone.js +5 -11
- package/lib/model/modelColPropMap.js +3 -10
- package/lib/model/modelId.js +3 -10
- package/lib/model/modelJsonAttributes.js +35 -16
- package/lib/model/modelParseRelations.js +2 -8
- package/lib/model/modelQueryProps.js +11 -23
- package/lib/model/modelSet.js +89 -41
- package/lib/model/modelTableMetadata.js +4 -11
- package/lib/model/modelToJson.js +6 -13
- package/lib/model/modelUtils.js +14 -13
- package/lib/model/modelValidate.js +3 -9
- package/lib/model/modelValues.js +5 -14
- package/lib/model/modelVisitor.js +1 -7
- package/lib/objection.js +33 -71
- package/lib/queryBuilder/FunctionBuilder.js +4 -11
- package/lib/queryBuilder/InternalOptions.js +4 -9
- package/lib/queryBuilder/JoinBuilder.js +5 -8
- package/lib/queryBuilder/QueryBuilder.js +126 -95
- package/lib/queryBuilder/QueryBuilderBase.js +41 -123
- package/lib/queryBuilder/QueryBuilderContext.js +2 -8
- package/lib/queryBuilder/QueryBuilderContextBase.js +2 -8
- package/lib/queryBuilder/QueryBuilderOperationSupport.js +7 -21
- package/lib/queryBuilder/QueryBuilderUserContext.js +1 -7
- package/lib/queryBuilder/RawBuilder.js +5 -13
- package/lib/queryBuilder/ReferenceBuilder.js +20 -48
- package/lib/queryBuilder/RelationExpression.js +18 -16
- package/lib/queryBuilder/StaticHookArguments.js +74 -16
- package/lib/queryBuilder/ValueBuilder.js +11 -13
- package/lib/queryBuilder/getJoinBuilder.js +10 -0
- package/lib/queryBuilder/graph/GraphLoader.js +304 -0
- package/lib/queryBuilder/graph/GraphNode.js +235 -0
- package/lib/queryBuilder/graph/GraphOptions.js +55 -248
- package/lib/queryBuilder/graph/GraphPlan.js +395 -0
- package/lib/queryBuilder/graph/GraphUpsert.js +466 -414
- package/lib/queryBuilder/graph/GraphWriter.js +1263 -0
- package/lib/queryBuilder/join/JoinResultColumn.js +1 -7
- package/lib/queryBuilder/join/JoinResultParser.js +6 -11
- package/lib/queryBuilder/join/RelationJoiner.js +66 -84
- package/lib/queryBuilder/join/TableNode.js +2 -8
- package/lib/queryBuilder/join/TableTree.js +3 -9
- package/lib/queryBuilder/join/utils.js +5 -15
- package/lib/queryBuilder/jsonDialects/JsonDialect.js +51 -0
- package/lib/queryBuilder/jsonDialects/MySqlJsonDialect.js +81 -0
- package/lib/queryBuilder/jsonDialects/PostgresJsonDialect.js +45 -0
- package/lib/queryBuilder/jsonDialects/SqliteJsonDialect.js +67 -0
- package/lib/queryBuilder/jsonDialects/index.js +44 -0
- package/lib/queryBuilder/operations/DelegateOperation.js +2 -8
- package/lib/queryBuilder/operations/DeleteOperation.js +10 -39
- package/lib/queryBuilder/operations/FindByIdOperation.js +7 -12
- package/lib/queryBuilder/operations/FindByIdsOperation.js +4 -8
- package/lib/queryBuilder/operations/FindOperation.js +14 -34
- package/lib/queryBuilder/operations/FirstOperation.js +6 -10
- package/lib/queryBuilder/operations/FromOperation.js +3 -9
- package/lib/queryBuilder/operations/InsertAndFetchOperation.js +13 -12
- package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +4 -10
- package/lib/queryBuilder/operations/InsertGraphOperation.js +7 -18
- package/lib/queryBuilder/operations/InsertOperation.js +118 -45
- package/lib/queryBuilder/operations/InstanceDeleteOperation.js +5 -12
- package/lib/queryBuilder/operations/InstanceFindOperation.js +4 -11
- package/lib/queryBuilder/operations/InstanceInsertOperation.js +2 -8
- package/lib/queryBuilder/operations/InstanceUpdateOperation.js +7 -14
- package/lib/queryBuilder/operations/JoinRelatedOperation.js +5 -11
- package/lib/queryBuilder/operations/KnexOperation.js +2 -8
- package/lib/queryBuilder/operations/LimitPerParentOperation.js +7 -69
- package/lib/queryBuilder/operations/MergeOperation.js +5 -11
- package/lib/queryBuilder/operations/NoneOperation.js +2 -8
- package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +20 -49
- package/lib/queryBuilder/operations/OnBuildKnexOperation.js +2 -8
- package/lib/queryBuilder/operations/OnBuildOperation.js +2 -8
- package/lib/queryBuilder/operations/OnErrorOperation.js +2 -8
- package/lib/queryBuilder/operations/QueryBuilderOperation.js +1 -7
- package/lib/queryBuilder/operations/RangeOperation.js +11 -26
- package/lib/queryBuilder/operations/RelateOperation.js +2 -8
- package/lib/queryBuilder/operations/ReturningOperation.js +3 -9
- package/lib/queryBuilder/operations/RunAfterOperation.js +2 -12
- package/lib/queryBuilder/operations/RunBeforeOperation.js +2 -8
- package/lib/queryBuilder/operations/UnrelateOperation.js +2 -8
- package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +14 -17
- package/lib/queryBuilder/operations/UpdateOperation.js +32 -132
- package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +8 -11
- package/lib/queryBuilder/operations/UpsertGraphOperation.js +6 -12
- package/lib/queryBuilder/operations/WhereCompositeOperation.js +3 -9
- package/lib/queryBuilder/operations/WhereGroupOperation.js +2 -8
- package/lib/queryBuilder/operations/eager/EagerOperation.js +3 -9
- package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +72 -10
- package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +2 -8
- package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +23 -44
- package/lib/queryBuilder/operations/fieldExpressions.js +122 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +20 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +44 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonTypeOperation.js +14 -0
- package/lib/queryBuilder/operations/select/SelectOperation.js +11 -21
- package/lib/queryBuilder/operations/select/Selection.js +19 -17
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +4 -10
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +4 -10
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +4 -10
- package/lib/queryBuilder/operations/windowOrder.js +56 -0
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +3 -7
- package/lib/queryBuilder/parsers/relationExpressionParser.js +42 -43
- package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +39 -36
- package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +2 -8
- package/lib/queryBuilder/transformations/QueryTransformation.js +1 -7
- package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +3 -9
- package/lib/queryBuilder/transformations/index.js +3 -11
- package/lib/queryBuilder/whereGroups.js +9 -24
- package/lib/queryBuilder/withoutOrder.js +4 -11
- package/lib/relations/Relation.js +47 -28
- package/lib/relations/RelationDeleteOperation.js +4 -14
- package/lib/relations/RelationFindOperation.js +119 -90
- package/lib/relations/RelationInsertOperation.js +2 -8
- package/lib/relations/RelationOwner.js +5 -11
- package/lib/relations/RelationProperty.js +4 -10
- package/lib/relations/RelationUpdateOperation.js +4 -14
- package/lib/relations/RelationWriteResultOperation.js +15 -0
- package/lib/relations/belongsToMany/BelongsToManyDeleteOperation.js +23 -0
- package/lib/relations/belongsToMany/BelongsToManyFindOperation.js +35 -0
- package/lib/relations/belongsToMany/BelongsToManyInsertOperation.js +28 -0
- package/lib/relations/belongsToMany/BelongsToManyRelateOperation.js +16 -0
- package/lib/relations/belongsToMany/BelongsToManyRelation.js +276 -0
- package/lib/relations/belongsToMany/BelongsToManyUnrelateOperation.js +11 -0
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +2 -8
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +6 -11
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +3 -9
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +8 -19
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +53 -27
- package/lib/relations/hasMany/HasManyInsertOperation.js +5 -10
- package/lib/relations/hasMany/HasManyRelateOperation.js +5 -11
- package/lib/relations/hasMany/HasManyRelation.js +9 -11
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +3 -9
- package/lib/relations/hasOne/HasOneRelation.js +2 -8
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +2 -8
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +10 -15
- package/lib/relations/manyToMany/ManyToManyMySqlModifyMixin.js +2 -8
- package/lib/relations/manyToMany/ManyToManyRelation.js +82 -50
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +2 -8
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +5 -9
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +2 -8
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -9
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +20 -59
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +6 -11
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +4 -10
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateMySqlOperation.js +3 -9
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +5 -9
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +3 -9
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +3 -9
- package/lib/relations/manyToMany/update/ManyToManyUpdateMySqlOperation.js +3 -9
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +5 -9
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +64 -72
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -9
- package/lib/transaction.js +3 -9
- package/lib/utils/assert.js +3 -11
- package/lib/utils/buildUtils.js +2 -8
- package/lib/utils/classUtils.js +1 -7
- package/lib/utils/createModifier.js +2 -8
- package/lib/utils/identifierMapping.js +23 -27
- package/lib/utils/internalPropUtils.js +1 -7
- package/lib/utils/knexUtils.js +84 -40
- package/lib/utils/mixin.js +3 -10
- package/lib/utils/normalizeIds.js +2 -8
- package/lib/utils/objectUtils.js +41 -60
- package/lib/utils/parseFieldExpression.js +16 -16
- package/lib/utils/promiseUtils/after.js +2 -8
- package/lib/utils/promiseUtils/afterReturn.js +2 -8
- package/lib/utils/promiseUtils/index.js +7 -16
- package/lib/utils/promiseUtils/isPromise.js +2 -8
- package/lib/utils/promiseUtils/map.js +2 -8
- package/lib/utils/promiseUtils/mapAfterAllReturn.js +2 -8
- package/lib/utils/promiseUtils/try.js +2 -8
- package/lib/utils/resolveModel.js +10 -17
- package/lib/utils/tmpColumnUtils.js +2 -9
- package/lib/utils/warnings.js +2 -14
- package/package.json +25 -17
- package/typings/objection/index.d.ts +3217 -2179
- package/lib/.eslintrc.json +0 -8
- package/lib/model/graph/ModelGraph.js +0 -80
- package/lib/model/graph/ModelGraphBuilder.js +0 -241
- package/lib/model/graph/ModelGraphEdge.js +0 -52
- package/lib/model/graph/ModelGraphNode.js +0 -238
- package/lib/queryBuilder/graph/GraphAction.js +0 -69
- package/lib/queryBuilder/graph/GraphData.js +0 -53
- package/lib/queryBuilder/graph/GraphFetcher.js +0 -197
- package/lib/queryBuilder/graph/GraphNodeDbExistence.js +0 -184
- package/lib/queryBuilder/graph/GraphOperation.js +0 -27
- package/lib/queryBuilder/graph/delete/GraphDelete.js +0 -73
- package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +0 -88
- package/lib/queryBuilder/graph/insert/DeferredRelationGraphInsertAction.js +0 -58
- package/lib/queryBuilder/graph/insert/GraphInsert.js +0 -296
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +0 -233
- package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +0 -92
- package/lib/queryBuilder/graph/patch/GraphPatch.js +0 -20
- package/lib/queryBuilder/graph/patch/GraphPatchAction.js +0 -289
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +0 -31
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +0 -126
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasPostgresOperation.js +0 -30
- package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectPostgresOperation.js +0 -37
- package/lib/queryBuilder/operations/jsonApi/WhereJsonPostgresOperation.js +0 -62
- package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +0 -192
- package/lib/utils/wrapDbError.js +0 -64
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
1
|
+
import { QueryBuilderOperation } from './QueryBuilderOperation.js';
|
|
4
2
|
|
|
5
3
|
// Operation that simply delegates all calls to the operation passed
|
|
6
4
|
// to to the constructor in `opt.delegate`.
|
|
7
|
-
class DelegateOperation extends QueryBuilderOperation {
|
|
5
|
+
export class DelegateOperation extends QueryBuilderOperation {
|
|
8
6
|
constructor(name, opt) {
|
|
9
7
|
super(name, opt);
|
|
10
8
|
|
|
@@ -157,7 +155,3 @@ class DelegateOperation extends QueryBuilderOperation {
|
|
|
157
155
|
return clone;
|
|
158
156
|
}
|
|
159
157
|
}
|
|
160
|
-
|
|
161
|
-
module.exports = {
|
|
162
|
-
DelegateOperation,
|
|
163
|
-
};
|
|
@@ -1,30 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
import { QueryBuilderOperation } from './QueryBuilderOperation.js';
|
|
2
|
+
import { StaticHookArguments } from '../StaticHookArguments.js';
|
|
3
|
+
import { isMySql } from '../../utils/knexUtils.js';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
const { StaticHookArguments } = require('../StaticHookArguments');
|
|
5
|
-
const { isMySql } = require('../../utils/knexUtils');
|
|
6
|
-
const { warnOnce } = require('../../utils/warnings');
|
|
7
|
-
|
|
8
|
-
class DeleteOperation extends QueryBuilderOperation {
|
|
5
|
+
export class DeleteOperation extends QueryBuilderOperation {
|
|
9
6
|
async onBefore2(builder, result) {
|
|
10
7
|
await callBeforeDelete(builder);
|
|
11
8
|
return result;
|
|
12
9
|
}
|
|
13
10
|
|
|
14
11
|
// knex leaves the offset out of deletes. On MySQL, it leaves out the order as
|
|
15
|
-
// well, but keeps the limit, so the order doesn't pick the deleted rows.
|
|
16
|
-
// when the query is executed.
|
|
12
|
+
// well, but keeps the limit, so the order doesn't pick the deleted rows.
|
|
13
|
+
// Throw when the query is executed.
|
|
17
14
|
onAfterBuild(builder) {
|
|
18
15
|
if (builder.has('offset')) {
|
|
19
|
-
|
|
20
|
-
'offset() has no effect in delete queries, so no rows are skipped. ' +
|
|
21
|
-
'This will throw an error in objection 4.0.',
|
|
22
|
-
);
|
|
16
|
+
throw new Error('offset() is not supported in delete queries, as knex leaves it out.');
|
|
23
17
|
}
|
|
24
18
|
if (isMySql(builder.knex()) && builder.has('limit') && builder.has(/^orderBy/)) {
|
|
25
|
-
|
|
26
|
-
'orderBy()
|
|
27
|
-
'
|
|
19
|
+
throw new Error(
|
|
20
|
+
'orderBy() is not supported in delete queries with limit() on MySQL, ' +
|
|
21
|
+
'as knex leaves out the order.',
|
|
28
22
|
);
|
|
29
23
|
}
|
|
30
24
|
}
|
|
@@ -33,10 +27,6 @@ class DeleteOperation extends QueryBuilderOperation {
|
|
|
33
27
|
return knexBuilder.delete();
|
|
34
28
|
}
|
|
35
29
|
|
|
36
|
-
onAfter2(builder, result) {
|
|
37
|
-
return callAfterDelete(builder, result);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
30
|
toFindOperation() {
|
|
41
31
|
return null;
|
|
42
32
|
}
|
|
@@ -50,22 +40,3 @@ function callStaticBeforeDelete(builder) {
|
|
|
50
40
|
const args = StaticHookArguments.create({ builder });
|
|
51
41
|
return builder.modelClass().beforeDelete(args);
|
|
52
42
|
}
|
|
53
|
-
|
|
54
|
-
function callAfterDelete(builder, result) {
|
|
55
|
-
return callStaticAfterDelete(builder, result);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async function callStaticAfterDelete(builder, result) {
|
|
59
|
-
const args = StaticHookArguments.create({ builder, result });
|
|
60
|
-
const maybeResult = await builder.modelClass().afterDelete(args);
|
|
61
|
-
|
|
62
|
-
if (maybeResult === undefined) {
|
|
63
|
-
return result;
|
|
64
|
-
} else {
|
|
65
|
-
return maybeResult;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
module.exports = {
|
|
70
|
-
DeleteOperation,
|
|
71
|
-
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { QueryBuilderOperation } from './QueryBuilderOperation.js';
|
|
2
|
+
import { assertIdNotUndefined } from '../../utils/assert.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
const { assertIdNotUndefined } = require('../../utils/assert');
|
|
5
|
-
|
|
6
|
-
class FindByIdOperation extends QueryBuilderOperation {
|
|
4
|
+
export class FindByIdOperation extends QueryBuilderOperation {
|
|
7
5
|
constructor(name, opt) {
|
|
8
6
|
super(name, opt);
|
|
9
7
|
this.id = this.opt.id;
|
|
8
|
+
// Keep the id condition in its own where group, so that it applies to
|
|
9
|
+
// whatever the user adds, `orWhere()` included. See `whereGroups.js`.
|
|
10
|
+
this.whereGroup = {};
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
onAdd(builder, args) {
|
|
@@ -18,9 +19,7 @@ class FindByIdOperation extends QueryBuilderOperation {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
onBuild(builder) {
|
|
21
|
-
|
|
22
|
-
assertIdNotUndefined(this.id, `undefined was passed to ${this.name}`);
|
|
23
|
-
}
|
|
22
|
+
assertIdNotUndefined(this.id, `undefined was passed to ${this.name}`);
|
|
24
23
|
|
|
25
24
|
builder.whereComposite(builder.fullIdColumn(), this.id);
|
|
26
25
|
}
|
|
@@ -31,7 +30,3 @@ class FindByIdOperation extends QueryBuilderOperation {
|
|
|
31
30
|
return clone;
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
module.exports = {
|
|
36
|
-
FindByIdOperation,
|
|
37
|
-
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { QueryBuilderOperation } from './QueryBuilderOperation.js';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class FindByIdsOperation extends QueryBuilderOperation {
|
|
3
|
+
export class FindByIdsOperation extends QueryBuilderOperation {
|
|
6
4
|
constructor(name, opt) {
|
|
7
5
|
super(name, opt);
|
|
8
6
|
this.ids = null;
|
|
7
|
+
// Its own where group, like `FindByIdOperation`.
|
|
8
|
+
this.whereGroup = {};
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
onAdd(builder, args) {
|
|
@@ -23,7 +23,3 @@ class FindByIdsOperation extends QueryBuilderOperation {
|
|
|
23
23
|
return clone;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
module.exports = {
|
|
28
|
-
FindByIdsOperation,
|
|
29
|
-
};
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
import { QueryBuilderOperation } from './QueryBuilderOperation.js';
|
|
2
|
+
import { StaticHookArguments, isGraphQuery } from '../StaticHookArguments.js';
|
|
3
|
+
import { isPromise, afterReturn } from '../../utils/promiseUtils/index.js';
|
|
4
|
+
import { isObject } from '../../utils/objectUtils.js';
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
const { StaticHookArguments } = require('../StaticHookArguments');
|
|
5
|
-
const { isPromise, after, afterReturn } = require('../../utils/promiseUtils');
|
|
6
|
-
const { isObject } = require('../../utils/objectUtils');
|
|
7
|
-
|
|
8
|
-
class FindOperation extends QueryBuilderOperation {
|
|
6
|
+
export class FindOperation extends QueryBuilderOperation {
|
|
9
7
|
onBefore2(builder, result) {
|
|
10
|
-
|
|
8
|
+
if (isGraphQuery(builder) || builder.findOptions().dontCallFindHooks) {
|
|
9
|
+
return result;
|
|
10
|
+
} else {
|
|
11
|
+
return afterReturn(callStaticBeforeFind(builder), result);
|
|
12
|
+
}
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
onAfter3(builder, results) {
|
|
14
16
|
const opt = builder.findOptions();
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
// The outer queries of `insertGraph()` and `upsertGraph()` return the
|
|
19
|
+
// input models, unless they read the written rows back with `returning()`:
|
|
20
|
+
if ((isGraphQuery(builder) && !builder.has('returning')) || opt.dontCallFindHooks) {
|
|
17
21
|
return results;
|
|
18
22
|
} else {
|
|
19
|
-
return
|
|
23
|
+
return callInstanceAfterFind(builder.context(), results, opt.callAfterFindDeeply);
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
}
|
|
@@ -26,26 +30,6 @@ function callStaticBeforeFind(builder) {
|
|
|
26
30
|
return builder.modelClass().beforeFind(args);
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
function callAfterFind(builder, result) {
|
|
30
|
-
const opt = builder.findOptions();
|
|
31
|
-
const maybePromise = callInstanceAfterFind(builder.context(), result, opt.callAfterFindDeeply);
|
|
32
|
-
|
|
33
|
-
return after(maybePromise, () => callStaticAfterFind(builder, result));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function callStaticAfterFind(builder, result) {
|
|
37
|
-
const args = StaticHookArguments.create({ builder, result });
|
|
38
|
-
const maybePromise = builder.modelClass().afterFind(args);
|
|
39
|
-
|
|
40
|
-
return after(maybePromise, (maybeResult) => {
|
|
41
|
-
if (maybeResult === undefined) {
|
|
42
|
-
return result;
|
|
43
|
-
} else {
|
|
44
|
-
return maybeResult;
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
33
|
function callInstanceAfterFind(ctx, results, deep) {
|
|
50
34
|
if (Array.isArray(results)) {
|
|
51
35
|
if (results.length === 1) {
|
|
@@ -158,7 +142,3 @@ function getAfterFindHook(model) {
|
|
|
158
142
|
return null;
|
|
159
143
|
}
|
|
160
144
|
}
|
|
161
|
-
|
|
162
|
-
module.exports = {
|
|
163
|
-
FindOperation,
|
|
164
|
-
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { QueryBuilderOperation } from './QueryBuilderOperation.js';
|
|
2
|
+
import { LimitPerParentOperation } from './LimitPerParentOperation.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class FirstOperation extends QueryBuilderOperation {
|
|
4
|
+
export class FirstOperation extends QueryBuilderOperation {
|
|
6
5
|
shouldLimit(builder) {
|
|
7
6
|
return builder.isFind() && builder.modelClass().useLimitInFirst;
|
|
8
7
|
}
|
|
@@ -15,15 +14,12 @@ class FirstOperation extends QueryBuilderOperation {
|
|
|
15
14
|
return knexBuilder;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
onAfter3(
|
|
19
|
-
|
|
17
|
+
onAfter3(builder, result) {
|
|
18
|
+
// Limited per parent, the query still returns the models of all parents:
|
|
19
|
+
if (Array.isArray(result) && !builder.has(LimitPerParentOperation)) {
|
|
20
20
|
return result[0];
|
|
21
21
|
} else {
|
|
22
22
|
return result;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
module.exports = {
|
|
28
|
-
FirstOperation,
|
|
29
|
-
};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { ObjectionToKnexConvertingOperation } = require('./ObjectionToKnexConvertingOperation');
|
|
4
|
-
const { isPlainObject, isString } = require('../../utils/objectUtils');
|
|
1
|
+
import { ObjectionToKnexConvertingOperation } from './ObjectionToKnexConvertingOperation.js';
|
|
2
|
+
import { isPlainObject, isString } from '../../utils/objectUtils.js';
|
|
5
3
|
|
|
6
4
|
const ALIAS_REGEX = /\s+as\s+/i;
|
|
7
5
|
|
|
@@ -9,7 +7,7 @@ const ALIAS_REGEX = /\s+as\s+/i;
|
|
|
9
7
|
// knex, but we first try to parse the arguments so that we can determine which
|
|
10
8
|
// tables have been mentioned in a query's from clause. We only parse string
|
|
11
9
|
// references and not `raw` or `ref` etc. references at this point thouhg.
|
|
12
|
-
class FromOperation extends ObjectionToKnexConvertingOperation {
|
|
10
|
+
export class FromOperation extends ObjectionToKnexConvertingOperation {
|
|
13
11
|
constructor(name, opt) {
|
|
14
12
|
super(name, opt);
|
|
15
13
|
|
|
@@ -95,7 +93,3 @@ function parseTableAndAliasFromObject(arg, builder) {
|
|
|
95
93
|
`one of the tables in ${JSON.stringify(arg)} must be the query's model class's table.`,
|
|
96
94
|
);
|
|
97
95
|
}
|
|
98
|
-
|
|
99
|
-
module.exports = {
|
|
100
|
-
FromOperation,
|
|
101
|
-
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { InsertOperation } from './InsertOperation.js';
|
|
2
|
+
import { DelegateOperation } from './DelegateOperation.js';
|
|
3
|
+
import { keyByProps } from '../../model/modelUtils.js';
|
|
4
|
+
import { asArray } from '../../utils/objectUtils.js';
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
const { DelegateOperation } = require('./DelegateOperation');
|
|
5
|
-
const { keyByProps } = require('../../model/modelUtils');
|
|
6
|
-
const { asArray } = require('../../utils/objectUtils');
|
|
7
|
-
|
|
8
|
-
class InsertAndFetchOperation extends DelegateOperation {
|
|
6
|
+
export class InsertAndFetchOperation extends DelegateOperation {
|
|
9
7
|
constructor(name, opt) {
|
|
10
8
|
super(name, opt);
|
|
11
9
|
|
|
@@ -24,7 +22,7 @@ class InsertAndFetchOperation extends DelegateOperation {
|
|
|
24
22
|
|
|
25
23
|
// Models without identifiers can't be fetched. This happens when a row
|
|
26
24
|
// with a database generated identifier is ignored by `onConflict()`.
|
|
27
|
-
const insertedModelArray = asArray(insertedModels).filter((model) => model
|
|
25
|
+
const insertedModelArray = asArray(insertedModels).filter((model) => model.$hasId());
|
|
28
26
|
const idProps = modelClass.getIdPropertyArray();
|
|
29
27
|
const ids = insertedModelArray.map((model) => model.$id());
|
|
30
28
|
|
|
@@ -38,6 +36,13 @@ class InsertAndFetchOperation extends DelegateOperation {
|
|
|
38
36
|
.findByIds(ids)
|
|
39
37
|
.castTo(builder.resultModelClass());
|
|
40
38
|
|
|
39
|
+
if (!Array.isArray(fetchedModels) || !fetchedModels.every((model) => model.$isObjectionModel)) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Unable to merge the result of ${modelClass.name}.afterFind() in ` +
|
|
42
|
+
`${this.name}(): expected an array of models.`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
const modelsById = keyByProps(fetchedModels, idProps);
|
|
42
47
|
|
|
43
48
|
// Instead of returning the freshly fetched models, update the input
|
|
@@ -49,7 +54,3 @@ class InsertAndFetchOperation extends DelegateOperation {
|
|
|
49
54
|
return insertedModels;
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
|
-
|
|
53
|
-
module.exports = {
|
|
54
|
-
InsertAndFetchOperation,
|
|
55
|
-
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { DelegateOperation } from './DelegateOperation.js';
|
|
2
|
+
import { InsertGraphOperation } from './InsertGraphOperation.js';
|
|
3
|
+
import { RelationExpression } from '../RelationExpression.js';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
const { InsertGraphOperation } = require('./InsertGraphOperation');
|
|
5
|
-
const { RelationExpression } = require('../RelationExpression');
|
|
6
|
-
|
|
7
|
-
class InsertGraphAndFetchOperation extends DelegateOperation {
|
|
5
|
+
export class InsertGraphAndFetchOperation extends DelegateOperation {
|
|
8
6
|
constructor(name, opt) {
|
|
9
7
|
super(name, opt);
|
|
10
8
|
|
|
@@ -39,7 +37,3 @@ class InsertGraphAndFetchOperation extends DelegateOperation {
|
|
|
39
37
|
return this.isArray ? models : models[0] || null;
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
|
-
|
|
43
|
-
module.exports = {
|
|
44
|
-
InsertGraphAndFetchOperation,
|
|
45
|
-
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { DelegateOperation } from './DelegateOperation.js';
|
|
2
|
+
import { InsertOperation } from './InsertOperation.js';
|
|
3
|
+
import { GraphUpsert } from '../graph/GraphUpsert.js';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
const { InsertOperation } = require('./InsertOperation');
|
|
5
|
-
const { GraphUpsert } = require('../graph/GraphUpsert');
|
|
6
|
-
|
|
7
|
-
class InsertGraphOperation extends DelegateOperation {
|
|
5
|
+
export class InsertGraphOperation extends DelegateOperation {
|
|
8
6
|
constructor(name, opt = null) {
|
|
9
7
|
super(name, opt);
|
|
10
8
|
|
|
@@ -33,15 +31,10 @@ class InsertGraphOperation extends DelegateOperation {
|
|
|
33
31
|
const retVal = super.onAdd(builder, args);
|
|
34
32
|
|
|
35
33
|
this.upsert = new GraphUpsert({
|
|
36
|
-
objects: this.models,
|
|
34
|
+
objects: this.isArray ? this.models : this.models[0],
|
|
37
35
|
rootModelClass: builder.modelClass(),
|
|
38
36
|
|
|
39
|
-
upsertOptions:
|
|
40
|
-
noUpdate: true,
|
|
41
|
-
noDelete: true,
|
|
42
|
-
noUnrelate: true,
|
|
43
|
-
insertMissing: true,
|
|
44
|
-
}),
|
|
37
|
+
upsertOptions: this.upsertOptions,
|
|
45
38
|
insertOnly: true,
|
|
46
39
|
});
|
|
47
40
|
|
|
@@ -53,7 +46,7 @@ class InsertGraphOperation extends DelegateOperation {
|
|
|
53
46
|
}
|
|
54
47
|
|
|
55
48
|
onBefore1(builder, result) {
|
|
56
|
-
GraphUpsert.
|
|
49
|
+
GraphUpsert.checkForOnConflict(builder, this.name);
|
|
57
50
|
return result;
|
|
58
51
|
}
|
|
59
52
|
|
|
@@ -108,7 +101,3 @@ class InsertGraphOperation extends DelegateOperation {
|
|
|
108
101
|
return clone;
|
|
109
102
|
}
|
|
110
103
|
}
|
|
111
|
-
|
|
112
|
-
module.exports = {
|
|
113
|
-
InsertGraphOperation,
|
|
114
|
-
};
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { QueryBuilderOperation } from './QueryBuilderOperation.js';
|
|
2
|
+
import { StaticHookArguments } from '../StaticHookArguments.js';
|
|
3
|
+
import { after, mapAfterAllReturn } from '../../utils/promiseUtils/index.js';
|
|
4
|
+
import {
|
|
5
|
+
isSqlite,
|
|
6
|
+
isMySql,
|
|
7
|
+
hasBatchInsert,
|
|
8
|
+
hasBatchInsertDefaults,
|
|
9
|
+
getMaxInsertRows,
|
|
10
|
+
} from '../../utils/knexUtils.js';
|
|
11
|
+
import { chunk, groupBy, isObject, isPlainObject, isString } from '../../utils/objectUtils.js';
|
|
12
|
+
import { removeOverriddenValues } from '../../model/modelQueryProps.js';
|
|
13
|
+
import { checkFieldExpressions } from './fieldExpressions.js';
|
|
9
14
|
|
|
10
15
|
// Base class for all insert operations.
|
|
11
|
-
class InsertOperation extends QueryBuilderOperation {
|
|
16
|
+
export class InsertOperation extends QueryBuilderOperation {
|
|
12
17
|
constructor(name, opt) {
|
|
13
18
|
super(name, opt);
|
|
14
19
|
|
|
15
20
|
this.models = null;
|
|
21
|
+
this.batches = null;
|
|
16
22
|
this.isArray = false;
|
|
17
23
|
this.modelOptions = Object.assign({}, this.opt.modelOptions || {});
|
|
18
24
|
}
|
|
@@ -28,13 +34,58 @@ class InsertOperation extends QueryBuilderOperation {
|
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
async onBefore2(builder, result) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
await callBeforeInsert(builder, this.models);
|
|
38
|
+
|
|
39
|
+
// Without ids to return, rows can be inserted in batches on all databases.
|
|
40
|
+
// The hooks may give the models their ids, or cancel the query.
|
|
41
|
+
if (
|
|
42
|
+
this.models.length > 1 &&
|
|
43
|
+
!hasBatchInsert(builder.knex()) &&
|
|
44
|
+
!builder.isExplicitlyResolvedOrRejected() &&
|
|
45
|
+
this._hasIdsToReturn(builder)
|
|
46
|
+
) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
'batch insert only works with Postgresql, SQL Server and SQLite, or with models that have their ids or no idColumn',
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.models.forEach(removeOverriddenValues);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Insert the models in several queries if they don't fit into one: Models
|
|
57
|
+
// without any column can't be inserted in batches (#1694), where the database
|
|
58
|
+
// doesn't fill in defaults (SQLite) the rows of a batch need the same columns,
|
|
59
|
+
// and a query can only bind so many values. The queries run in the caller's
|
|
60
|
+
// transaction, if there is one. Without it they are not atomic.
|
|
61
|
+
queryBatches(builder) {
|
|
62
|
+
const models = this.models;
|
|
63
|
+
this.batches = null;
|
|
64
|
+
|
|
65
|
+
if (models.length < 2) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const knex = builder.knex();
|
|
70
|
+
const columnsByModel = new Map(
|
|
71
|
+
models.map((model) => [model, Object.keys(model.$toDatabaseJson(builder))]),
|
|
72
|
+
);
|
|
73
|
+
const batches = [];
|
|
74
|
+
|
|
75
|
+
for (const group of groupBy(models, (model) =>
|
|
76
|
+
getColumnsKey(knex, columnsByModel.get(model)),
|
|
77
|
+
).values()) {
|
|
78
|
+
const columnCount = Math.max(...group.map((model) => columnsByModel.get(model).length));
|
|
79
|
+
|
|
80
|
+
if (columnCount === 0) {
|
|
81
|
+
batches.push(...group.map((model) => [model]));
|
|
82
|
+
} else {
|
|
83
|
+
batches.push(...chunk(group, getMaxInsertRows(knex, columnCount)));
|
|
84
|
+
}
|
|
37
85
|
}
|
|
86
|
+
|
|
87
|
+
this.batches = batches.length > 1 ? batches : null;
|
|
88
|
+
return this.batches;
|
|
38
89
|
}
|
|
39
90
|
|
|
40
91
|
onBuildKnex(knexBuilder, builder) {
|
|
@@ -49,15 +100,37 @@ class InsertOperation extends QueryBuilderOperation {
|
|
|
49
100
|
// conflict columns are returned too, so that the returned rows can
|
|
50
101
|
// be matched to the models when some of the rows are ignored.
|
|
51
102
|
knexBuilder = knexBuilder.returning(defaultReturning);
|
|
52
|
-
} else if (
|
|
103
|
+
} else if (
|
|
104
|
+
isSqlite(knex) &&
|
|
105
|
+
(builder.has('onConflict') || (this.models.length > 1 && this._hasIdsToReturn(builder)))
|
|
106
|
+
) {
|
|
53
107
|
// Without a `returning` clause, SQLite returns the id of the last
|
|
54
108
|
// inserted row, which belongs to a previous insert if the row was
|
|
55
|
-
// ignored. Use `returning` to find
|
|
109
|
+
// ignored, and only one id for batch inserts. Use `returning` to find
|
|
110
|
+
// out what was actually inserted.
|
|
56
111
|
knexBuilder = knexBuilder.returning(defaultReturning);
|
|
57
112
|
}
|
|
58
113
|
}
|
|
59
114
|
|
|
60
|
-
|
|
115
|
+
const modelClass = builder.modelClass();
|
|
116
|
+
// knex leaves arrays unserialized in SQLite inserts, and also objects when
|
|
117
|
+
// it inserts several rows with `select ... union all`.
|
|
118
|
+
const shouldSerialize = isSqlite(knex);
|
|
119
|
+
|
|
120
|
+
return knexBuilder.insert(
|
|
121
|
+
(builder._queryBatch || this.models).map((model) => {
|
|
122
|
+
checkFieldExpressions(modelClass, model, 'insert');
|
|
123
|
+
const json = model.$toDatabaseJson(builder);
|
|
124
|
+
return shouldSerialize ? serializeObjects(json) : json;
|
|
125
|
+
}),
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
_hasIdsToReturn(builder) {
|
|
130
|
+
return (
|
|
131
|
+
builder.modelClass().getIdColumnArray().length > 0 &&
|
|
132
|
+
!this.models.every((model) => model.$hasId())
|
|
133
|
+
);
|
|
61
134
|
}
|
|
62
135
|
|
|
63
136
|
onAfter1(builder, ret) {
|
|
@@ -67,6 +140,8 @@ class InsertOperation extends QueryBuilderOperation {
|
|
|
67
140
|
}
|
|
68
141
|
|
|
69
142
|
const isOnConflict = builder.has('onConflict');
|
|
143
|
+
// The results of the batches are in the order of the batches.
|
|
144
|
+
const models = this.batches ? this.batches.flat() : this.models;
|
|
70
145
|
|
|
71
146
|
if (isObject(ret[0])) {
|
|
72
147
|
if (isOnConflict && ret.length !== this.models.length) {
|
|
@@ -77,14 +152,15 @@ class InsertOperation extends QueryBuilderOperation {
|
|
|
77
152
|
} else {
|
|
78
153
|
// If the user specified a `returning` clause the result may be an array of objects.
|
|
79
154
|
// Merge all values of the objects to our models.
|
|
80
|
-
|
|
81
|
-
|
|
155
|
+
const options = { knex: builder.knex() };
|
|
156
|
+
for (let i = 0, l = models.length; i < l; ++i) {
|
|
157
|
+
models[i].$setDatabaseJson(ret[i], options);
|
|
82
158
|
}
|
|
83
159
|
}
|
|
84
160
|
} else if (builder.modelClass().getIdColumnArray().length > 0) {
|
|
85
161
|
// If the return value is not an array of objects, we assume it is an array of identifiers.
|
|
86
|
-
for (let i = 0, l =
|
|
87
|
-
const model =
|
|
162
|
+
for (let i = 0, l = models.length; i < l; ++i) {
|
|
163
|
+
const model = models[i];
|
|
88
164
|
|
|
89
165
|
// Don't set the id if the model already has one. MySQL and Sqlite don't return the correct
|
|
90
166
|
// primary key value if the id is not generated in db, but given explicitly. With
|
|
@@ -98,9 +174,9 @@ class InsertOperation extends QueryBuilderOperation {
|
|
|
98
174
|
return this.models;
|
|
99
175
|
}
|
|
100
176
|
|
|
101
|
-
onAfter2(builder, models) {
|
|
102
|
-
|
|
103
|
-
return
|
|
177
|
+
async onAfter2(builder, models) {
|
|
178
|
+
await callInstanceAfterInsert(builder, this.models);
|
|
179
|
+
return this.isArray ? models : models[0] || null;
|
|
104
180
|
}
|
|
105
181
|
|
|
106
182
|
toFindOperation() {
|
|
@@ -111,12 +187,19 @@ class InsertOperation extends QueryBuilderOperation {
|
|
|
111
187
|
const clone = super.clone();
|
|
112
188
|
|
|
113
189
|
clone.models = this.models;
|
|
190
|
+
clone.batches = this.batches;
|
|
114
191
|
clone.isArray = this.isArray;
|
|
115
192
|
|
|
116
193
|
return clone;
|
|
117
194
|
}
|
|
118
195
|
}
|
|
119
196
|
|
|
197
|
+
// Rows are only grouped where the database doesn't fill in the defaults of the
|
|
198
|
+
// columns that a row leaves out.
|
|
199
|
+
function getColumnsKey(knex, columns) {
|
|
200
|
+
return hasBatchInsertDefaults(knex) ? '' : JSON.stringify([...columns].sort());
|
|
201
|
+
}
|
|
202
|
+
|
|
120
203
|
// Returns `null` if there's nothing to return, e.g. for models without an `idColumn`.
|
|
121
204
|
function getDefaultReturning(builder) {
|
|
122
205
|
const idColumns = builder.modelClass().getIdColumnArray();
|
|
@@ -180,6 +263,8 @@ function mergeMatchingRows(builder, models, rows) {
|
|
|
180
263
|
}
|
|
181
264
|
});
|
|
182
265
|
|
|
266
|
+
const options = { knex: builder.knex() };
|
|
267
|
+
|
|
183
268
|
for (const row of rows) {
|
|
184
269
|
const indices = indicesByKey.get(createKey(row));
|
|
185
270
|
const index = indices ? indices.shift() : undefined;
|
|
@@ -188,7 +273,7 @@ function mergeMatchingRows(builder, models, rows) {
|
|
|
188
273
|
throw createMatchError();
|
|
189
274
|
}
|
|
190
275
|
|
|
191
|
-
models[index].$setDatabaseJson(row);
|
|
276
|
+
models[index].$setDatabaseJson(row, options);
|
|
192
277
|
}
|
|
193
278
|
}
|
|
194
279
|
|
|
@@ -224,28 +309,16 @@ function callStaticBeforeInsert(builder) {
|
|
|
224
309
|
return builder.modelClass().beforeInsert(args);
|
|
225
310
|
}
|
|
226
311
|
|
|
227
|
-
function callAfterInsert(builder, models, result) {
|
|
228
|
-
const maybePromise = callInstanceAfterInsert(builder, models);
|
|
229
|
-
return after(maybePromise, () => callStaticAfterInsert(builder, result));
|
|
230
|
-
}
|
|
231
|
-
|
|
232
312
|
function callInstanceAfterInsert(builder, models) {
|
|
233
313
|
return mapAfterAllReturn(models, (model) => model.$afterInsert(builder.context()), models);
|
|
234
314
|
}
|
|
235
315
|
|
|
236
|
-
function
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
return after(maybePromise, (maybeResult) => {
|
|
241
|
-
if (maybeResult === undefined) {
|
|
242
|
-
return result;
|
|
243
|
-
} else {
|
|
244
|
-
return maybeResult;
|
|
316
|
+
function serializeObjects(json) {
|
|
317
|
+
for (const [key, value] of Object.entries(json)) {
|
|
318
|
+
if (isPlainObject(value) || Array.isArray(value)) {
|
|
319
|
+
json[key] = JSON.stringify(value);
|
|
245
320
|
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
321
|
+
}
|
|
248
322
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
};
|
|
323
|
+
return json;
|
|
324
|
+
}
|