objection 3.9.0 → 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 +43 -27
- package/lib/model/modelSet.js +89 -41
- package/lib/model/modelTableMetadata.js +4 -11
- package/lib/model/modelToJson.js +8 -23
- 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 -410
- 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 +13 -35
- 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 -43
- 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 +39 -125
- 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 +8 -9
- 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 +79 -64
- 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 +29 -14
- 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 +25 -14
- 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 -253
- package/lib/queryBuilder/graph/GraphAction.js +0 -69
- package/lib/queryBuilder/graph/GraphData.js +0 -53
- package/lib/queryBuilder/graph/GraphFetcher.js +0 -199
- 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 -57
- package/lib/queryBuilder/graph/insert/GraphInsert.js +0 -257
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +0 -238
- 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 -277
- 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 -50
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { asArray, asSingle, isNumber, isObject, isString } from '../../utils/objectUtils.js';
|
|
2
|
+
import { ValidationErrorType } from '../../model/ValidationError.js';
|
|
3
|
+
|
|
4
|
+
// A model in a graph that is inserted or upserted, or in the current graph that
|
|
5
|
+
// is fetched from the database for it.
|
|
6
|
+
export class GraphNode {
|
|
7
|
+
constructor(modelClass, obj, { parent = null, relation = null, index = null, relationPath }) {
|
|
8
|
+
this.modelClass = modelClass;
|
|
9
|
+
this.obj = obj;
|
|
10
|
+
this.parent = parent;
|
|
11
|
+
this.relation = relation;
|
|
12
|
+
// The index in the array of a to-many relation, or of array input:
|
|
13
|
+
this.index = index;
|
|
14
|
+
this.children = [];
|
|
15
|
+
this.relationPath = parent ? [...parent.relationPath, relation.name] : relationPath;
|
|
16
|
+
this.relationPathKey = this.relationPath.join('.');
|
|
17
|
+
// The id state of the input, before the writes complete ids with keys:
|
|
18
|
+
this.hasId = obj.$hasId();
|
|
19
|
+
|
|
20
|
+
// Read the markers of the graph, which `removeMarkers()` removes from the
|
|
21
|
+
// models once all places of a model are read:
|
|
22
|
+
const { uidProp, uidRefProp, dbRefProp, graphUnrelateProp, graphDeleteProp } = modelClass;
|
|
23
|
+
this.uid = obj[uidProp];
|
|
24
|
+
this.reference = obj[uidRefProp];
|
|
25
|
+
this.dbReference = obj[dbRefProp];
|
|
26
|
+
this.toBeUnrelated = obj[graphUnrelateProp] === true;
|
|
27
|
+
this.toBeDeleted = obj[graphDeleteProp] === true;
|
|
28
|
+
|
|
29
|
+
// The node of a `#ref` model, and the `#ref{}` properties of this model:
|
|
30
|
+
this.referencedNode = null;
|
|
31
|
+
this.propertyReferences = [];
|
|
32
|
+
// The nodes whose `#ref` or `#ref{}` point to this node:
|
|
33
|
+
this.referencingNodes = [];
|
|
34
|
+
this.propertyReferencingNodes = [];
|
|
35
|
+
|
|
36
|
+
// How the graph and the current graph pair up, see `GraphLoader`: The
|
|
37
|
+
// current node at the place of an input node and the other way around, and
|
|
38
|
+
// the current node of a related model's row fetched from elsewhere.
|
|
39
|
+
this.current = null;
|
|
40
|
+
this.node = null;
|
|
41
|
+
this.row = null;
|
|
42
|
+
this.isMissing = false;
|
|
43
|
+
|
|
44
|
+
// Set by `GraphPlan`:
|
|
45
|
+
this.isPruned = false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get isReference() {
|
|
49
|
+
return this.reference !== undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get isDbReference() {
|
|
53
|
+
return this.dbReference !== undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get toBeUnrelatedOrDeleted() {
|
|
57
|
+
return this.toBeUnrelated || this.toBeDeleted;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get isRoot() {
|
|
61
|
+
return !this.parent;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// The current node of the row of this node, at its place or where a relate
|
|
65
|
+
// moves it from.
|
|
66
|
+
get existing() {
|
|
67
|
+
return this.current || this.row;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get dataPath() {
|
|
71
|
+
return this.parent
|
|
72
|
+
? [
|
|
73
|
+
...this.parent.dataPath,
|
|
74
|
+
this.relation.name,
|
|
75
|
+
...(this.relation.isOneToOne() ? [] : [this.index]),
|
|
76
|
+
]
|
|
77
|
+
: this.index !== null
|
|
78
|
+
? [this.index]
|
|
79
|
+
: [];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// The data path in the form of validation errors, like `.pets[0].owner` or
|
|
83
|
+
// `[1].pets[0].owner` for array input.
|
|
84
|
+
get dataPathKey() {
|
|
85
|
+
return this.dataPath.map((key) => (isNumber(key) ? `[${key}]` : `.${key}`)).join('');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
get descendants() {
|
|
89
|
+
return this.children.flatMap((child) => [child, ...child.descendants]);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get activeChildren() {
|
|
93
|
+
return this.children.filter((child) => !child.isPruned);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get rowKey() {
|
|
97
|
+
return `${this.modelClass.getTableName()}:${this.obj.$idKey()}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Build the nodes of `roots` and their related models in depth-first order.
|
|
101
|
+
// `relationPath` is the place of the roots in the graph that a current graph
|
|
102
|
+
// is fetched for. The roots of array input know their index in it.
|
|
103
|
+
static buildGraph(modelClass, roots, relationPath = []) {
|
|
104
|
+
const nodes = [];
|
|
105
|
+
|
|
106
|
+
const addNode = (modelClass, obj, place) => {
|
|
107
|
+
if (!isObject(obj) || !obj.$isObjectionModel) {
|
|
108
|
+
throw createNotModelError(modelClass, obj);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const node = new GraphNode(modelClass, obj, place);
|
|
112
|
+
nodes.push(node);
|
|
113
|
+
place.parent?.children.push(node);
|
|
114
|
+
|
|
115
|
+
for (const name of modelClass.getRelationNames()) {
|
|
116
|
+
const related = obj[name];
|
|
117
|
+
|
|
118
|
+
if (related) {
|
|
119
|
+
const relation = modelClass.getRelation(name);
|
|
120
|
+
const items = relation.isOneToOne() ? [asSingle(related)] : asArray(related);
|
|
121
|
+
|
|
122
|
+
items.forEach((item, index) => {
|
|
123
|
+
addNode(relation.relatedModelClass, item, { parent: node, relation, index });
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
asArray(roots).forEach((root, index) => {
|
|
130
|
+
addNode(modelClass, root, { relationPath, index: Array.isArray(roots) ? index : null });
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return nodes;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Remove the markers from the models, as they're neither written nor
|
|
137
|
+
// returned, and return a function that puts them back if the writes fail.
|
|
138
|
+
static removeMarkers(nodes) {
|
|
139
|
+
const markers = [];
|
|
140
|
+
|
|
141
|
+
for (const { modelClass, obj } of nodes) {
|
|
142
|
+
for (const prop of [
|
|
143
|
+
modelClass.uidProp,
|
|
144
|
+
modelClass.uidRefProp,
|
|
145
|
+
modelClass.dbRefProp,
|
|
146
|
+
modelClass.graphUnrelateProp,
|
|
147
|
+
modelClass.graphDeleteProp,
|
|
148
|
+
]) {
|
|
149
|
+
if (Object.hasOwn(obj, prop)) {
|
|
150
|
+
markers.push([obj, prop, obj[prop]]);
|
|
151
|
+
delete obj[prop];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return () => {
|
|
157
|
+
for (const [obj, prop, value] of markers) {
|
|
158
|
+
obj[prop] = value;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Link the `#ref` and `#ref{}` references of the nodes to the nodes with the
|
|
164
|
+
// `#id` that they refer to.
|
|
165
|
+
static linkReferences(nodes) {
|
|
166
|
+
const nodesByUid = new Map();
|
|
167
|
+
|
|
168
|
+
for (const node of nodes) {
|
|
169
|
+
if (node.uid !== undefined) {
|
|
170
|
+
nodesByUid.set(node.uid, node);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const getNode = (uid) => {
|
|
175
|
+
const node = nodesByUid.get(uid);
|
|
176
|
+
|
|
177
|
+
if (!node) {
|
|
178
|
+
throw new Error(`could not resolve reference ${uid} in a graph.`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return node;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
for (const node of nodes) {
|
|
185
|
+
if (node.isReference) {
|
|
186
|
+
node.referencedNode = getNode(node.reference);
|
|
187
|
+
node.referencedNode.referencingNodes.push(node);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
forEachPropertyReference(node.obj, ({ path, match, uid, refPath, isWholeValue }) => {
|
|
191
|
+
const referencedNode = getNode(uid);
|
|
192
|
+
node.propertyReferences.push({ path, match, refPath, isWholeValue, referencedNode });
|
|
193
|
+
referencedNode.propertyReferencingNodes.push(node);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function forEachPropertyReference(obj, callback) {
|
|
200
|
+
const modelClass = obj.constructor;
|
|
201
|
+
const relationNames = modelClass.getRelationNames();
|
|
202
|
+
|
|
203
|
+
const visit = (value, path) => {
|
|
204
|
+
if (Array.isArray(value)) {
|
|
205
|
+
value.forEach((item, index) => visit(item, [...path, index]));
|
|
206
|
+
} else if (isObject(value) && !Buffer.isBuffer(value)) {
|
|
207
|
+
for (const key of Object.keys(value)) {
|
|
208
|
+
visit(value[key], [...path, key]);
|
|
209
|
+
}
|
|
210
|
+
} else if (isString(value)) {
|
|
211
|
+
for (const [match, uid, refPath] of value.matchAll(modelClass.propRefRegex)) {
|
|
212
|
+
callback({
|
|
213
|
+
path,
|
|
214
|
+
match,
|
|
215
|
+
uid,
|
|
216
|
+
refPath: refPath.trim().split('.'),
|
|
217
|
+
isWholeValue: match === value,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
for (const key of Object.keys(obj)) {
|
|
224
|
+
if (!relationNames.includes(key)) {
|
|
225
|
+
visit(obj[key], [key]);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function createNotModelError(modelClass, value) {
|
|
231
|
+
return modelClass.createValidationError({
|
|
232
|
+
type: ValidationErrorType.InvalidGraph,
|
|
233
|
+
message: `expected value "${value}" to be an instance of ${modelClass.name}`,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { RelationExpression } = require('../RelationExpression');
|
|
4
|
-
const { isString } = require('../../utils/objectUtils');
|
|
1
|
+
import { RelationExpression } from '../RelationExpression.js';
|
|
2
|
+
import { isString } from '../../utils/objectUtils.js';
|
|
5
3
|
|
|
6
4
|
const NO_RELATE = 'noRelate';
|
|
7
5
|
const NO_UNRELATE = 'noUnrelate';
|
|
@@ -18,7 +16,7 @@ const ALLOW_REFS = 'allowRefs';
|
|
|
18
16
|
const ALLOW_MARKERS = 'allowMarkers';
|
|
19
17
|
|
|
20
18
|
// The options that are matched against the relation path of each node, see
|
|
21
|
-
// `
|
|
19
|
+
// `has()`.
|
|
22
20
|
const NODE_OPTION_NAMES = [
|
|
23
21
|
NO_RELATE,
|
|
24
22
|
NO_UNRELATE,
|
|
@@ -33,27 +31,31 @@ const NODE_OPTION_NAMES = [
|
|
|
33
31
|
|
|
34
32
|
const OPTION_NAMES = [...NODE_OPTION_NAMES, FETCH_STRATEGY, ALLOW_REFS, ALLOW_MARKERS];
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
// `insertGraph` never fetches, updates or removes existing rows, so only the
|
|
35
|
+
// options about inserting and relating apply to it, and the others are set:
|
|
36
|
+
const INSERT_OPTION_NAMES = [RELATE, NO_RELATE, NO_INSERT, ALLOW_REFS];
|
|
37
|
+
const INSERT_ONLY_OPTIONS = {
|
|
38
|
+
[NO_UPDATE]: true,
|
|
39
|
+
[NO_DELETE]: true,
|
|
40
|
+
[NO_UNRELATE]: true,
|
|
41
|
+
[INSERT_MISSING]: true,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const FetchStrategy = {
|
|
37
45
|
OnlyIdentifiers: 'OnlyIdentifiers',
|
|
38
46
|
Everything: 'Everything',
|
|
39
47
|
OnlyNeeded: 'OnlyNeeded',
|
|
40
48
|
};
|
|
41
49
|
|
|
42
|
-
class GraphOptions {
|
|
43
|
-
// `
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.insertOnly = options.insertOnly;
|
|
52
|
-
} else {
|
|
53
|
-
this.options = parseRelationExpressions(options);
|
|
54
|
-
this.rootRelationPath = rootRelationPath;
|
|
55
|
-
this.insertOnly = insertOnly;
|
|
56
|
-
}
|
|
50
|
+
export class GraphOptions {
|
|
51
|
+
// `insertOnly` is only set by `insertGraph`, which never fetches, updates or
|
|
52
|
+
// removes existing rows.
|
|
53
|
+
constructor(options, insertOnly = false) {
|
|
54
|
+
checkForUnknownOptions(options, insertOnly);
|
|
55
|
+
this.options = parseRelationExpressions(
|
|
56
|
+
insertOnly ? { ...options, ...INSERT_ONLY_OPTIONS } : options,
|
|
57
|
+
);
|
|
58
|
+
this.insertOnly = insertOnly;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
isFetchStrategy(strategy) {
|
|
@@ -72,136 +74,15 @@ class GraphOptions {
|
|
|
72
74
|
return this.insertOnly;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (node.isReference || node.isDbReference) {
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
this._hasOption(node, RELATE) &&
|
|
87
|
-
!getCurrentNode(node, graphData) &&
|
|
88
|
-
!!node.parentEdge &&
|
|
89
|
-
!!node.parentEdge.relation &&
|
|
90
|
-
hasRelateProp(node) &&
|
|
91
|
-
graphData.nodeDbExistence.doesNodeExistInDb(node)
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
shouldRelate(node, graphData) {
|
|
96
|
-
return !this._hasOption(node, NO_RELATE) && this.shouldRelateIgnoreDisable(node, graphData);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Like `shouldInsert` but ignores settings that explicitly disable insert operations.
|
|
100
|
-
shouldInsertIgnoreDisable(node, graphData) {
|
|
101
|
-
if (node.toBeUnrelatedOrDeleted) {
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return (
|
|
106
|
-
!getCurrentNode(node, graphData) &&
|
|
107
|
-
!this.shouldRelateIgnoreDisable(node, graphData) &&
|
|
108
|
-
(!node.hasId || this.shouldInsertMissing(node))
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
shouldInsert(node, graphData) {
|
|
113
|
-
return !this._hasOption(node, NO_INSERT) && this.shouldInsertIgnoreDisable(node, graphData);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
shouldInsertMissing(node) {
|
|
117
|
-
return this._hasOption(node, INSERT_MISSING);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Like `shouldPatch() || shouldUpdate()` but ignores settings that explicitly disable
|
|
121
|
-
// update or patch operations.
|
|
122
|
-
shouldPatchOrUpdateIgnoreDisable(node, graphData) {
|
|
123
|
-
if (node.toBeUnrelatedOrDeleted) {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (this.shouldRelate(node, graphData)) {
|
|
128
|
-
// We should update all nodes that are going to be related. Note that
|
|
129
|
-
// we don't actually update anything unless there is something to update
|
|
130
|
-
// so this is just a preliminary test.
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return !!getCurrentNode(node, graphData);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
shouldPatch(node, graphData) {
|
|
138
|
-
return (
|
|
139
|
-
this.shouldPatchOrUpdateIgnoreDisable(node, graphData) &&
|
|
140
|
-
!this._hasOption(node, NO_UPDATE) &&
|
|
141
|
-
!this._hasOption(node, UPDATE)
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
shouldUpdate(node, graphData) {
|
|
146
|
-
return (
|
|
147
|
-
this.shouldPatchOrUpdateIgnoreDisable(node, graphData) &&
|
|
148
|
-
!this._hasOption(node, NO_UPDATE) &&
|
|
149
|
-
this._hasOption(node, UPDATE)
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Like `shouldUnrelate` but ignores settings that explicitly disable unrelate operations.
|
|
154
|
-
shouldUnrelateIgnoreDisable(currentNode) {
|
|
155
|
-
return this._hasOption(currentNode, UNRELATE);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
shouldUnrelate(currentNode, graphData) {
|
|
159
|
-
const node = getNode(currentNode, graphData.graph);
|
|
160
|
-
if (node && node.toBeUnrelated) return true;
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
!node &&
|
|
164
|
-
!hasIgnoredOtherModel(currentNode, graphData) &&
|
|
165
|
-
!this._hasOption(currentNode, NO_UNRELATE) &&
|
|
166
|
-
(this.shouldUnrelateIgnoreDisable(currentNode) ||
|
|
167
|
-
// The unrelate replaces a delete, so `noDelete` disables it too.
|
|
168
|
-
(!this._hasOption(currentNode, NO_DELETE) && shouldUnrelateKeptRow(currentNode, graphData)))
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
shouldDelete(currentNode, graphData) {
|
|
173
|
-
const node = getNode(currentNode, graphData.graph);
|
|
174
|
-
// `#unrelate` takes precedence over `#delete` if both are set.
|
|
175
|
-
if (node && node.toBeDeleted && !node.toBeUnrelated) return true;
|
|
176
|
-
|
|
177
|
-
return (
|
|
178
|
-
!node &&
|
|
179
|
-
!hasIgnoredOtherModel(currentNode, graphData) &&
|
|
180
|
-
!this._hasOption(currentNode, NO_DELETE) &&
|
|
181
|
-
!this.shouldUnrelateIgnoreDisable(currentNode) &&
|
|
182
|
-
// Rows that the graph keeps in another place must not be deleted (#214).
|
|
183
|
-
!graphData.keptNodeForRow(currentNode)
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
shouldInsertOrRelate(node, graphData) {
|
|
188
|
-
return this.shouldInsert(node, graphData) || this.shouldRelate(node, graphData);
|
|
77
|
+
// Whether a node that the graph relates or patches is written with `patch()`
|
|
78
|
+
// or `update()`. With `noUpdate`, it's neither, and only the foreign keys of
|
|
79
|
+
// its relates and BelongsToOneRelations are patched.
|
|
80
|
+
shouldPatch(node) {
|
|
81
|
+
return !this.has(node, NO_UPDATE) && !this.has(node, UPDATE);
|
|
189
82
|
}
|
|
190
83
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
// or `noRelate`. Inserted models have ids and can look like models to relate
|
|
194
|
-
// afterwards, so we check that they were inserted too.
|
|
195
|
-
shouldIgnore(node, graphData) {
|
|
196
|
-
return (
|
|
197
|
-
!node.userData.inserted &&
|
|
198
|
-
!this.shouldInsertOrRelate(node, graphData) &&
|
|
199
|
-
!this.shouldPatchOrUpdateIgnoreDisable(node, graphData)
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
shouldDeleteOrUnrelate(currentNode, graphData) {
|
|
204
|
-
return this.shouldDelete(currentNode, graphData) || this.shouldUnrelate(currentNode, graphData);
|
|
84
|
+
shouldUpdate(node) {
|
|
85
|
+
return !this.has(node, NO_UPDATE) && this.has(node, UPDATE);
|
|
205
86
|
}
|
|
206
87
|
|
|
207
88
|
allowRefs() {
|
|
@@ -212,38 +93,37 @@ class GraphOptions {
|
|
|
212
93
|
return !!this.options[ALLOW_MARKERS];
|
|
213
94
|
}
|
|
214
95
|
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
96
|
+
// Whether the option applies to the relation path of `node`.
|
|
97
|
+
has(node, optionName) {
|
|
98
|
+
const option = this.options[optionName];
|
|
99
|
+
|
|
100
|
+
return isRelationExpression(option)
|
|
101
|
+
? matchesRelationExpression(option, node.relationPath)
|
|
102
|
+
: Array.isArray(option)
|
|
103
|
+
? option.includes(node.relationPathKey)
|
|
104
|
+
: !!option;
|
|
219
105
|
}
|
|
106
|
+
}
|
|
220
107
|
|
|
221
|
-
|
|
222
|
-
|
|
108
|
+
// Reject misspelled options and options of `upsertGraph` passed to
|
|
109
|
+
// `insertGraph`, which would otherwise be ignored silently (#84). Options set
|
|
110
|
+
// to `undefined` count as not set.
|
|
111
|
+
function checkForUnknownOptions(options, insertOnly) {
|
|
112
|
+
const [method, optionNames] = insertOnly
|
|
113
|
+
? ['insertGraph', INSERT_OPTION_NAMES]
|
|
114
|
+
: ['upsertGraph', OPTION_NAMES];
|
|
223
115
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
} else if (Array.isArray(option)) {
|
|
227
|
-
return option.includes(this._relationPath(node).join('.'));
|
|
228
|
-
} else if (typeof option === 'boolean') {
|
|
229
|
-
return option;
|
|
230
|
-
} else if (option === undefined) {
|
|
231
|
-
return false;
|
|
232
|
-
} else {
|
|
116
|
+
for (const [name, value] of Object.entries(options)) {
|
|
117
|
+
if (value !== undefined && !optionNames.includes(name)) {
|
|
233
118
|
throw new Error(
|
|
234
|
-
`
|
|
119
|
+
`"${name}" is not an option of ${method}(). Valid options are: ${optionNames.join(', ')}.`,
|
|
235
120
|
);
|
|
236
121
|
}
|
|
237
122
|
}
|
|
238
|
-
|
|
239
|
-
// The relation path of the node in the original graph, see `rebasedOptions()`.
|
|
240
|
-
_relationPath(node) {
|
|
241
|
-
return [...this.rootRelationPath, ...node.relationPath];
|
|
242
|
-
}
|
|
243
123
|
}
|
|
244
124
|
|
|
245
125
|
// Parses the string values of the node options into relation expressions,
|
|
246
|
-
// once per operation.
|
|
126
|
+
// once per operation, and checks the types of the other values.
|
|
247
127
|
function parseRelationExpressions(options) {
|
|
248
128
|
let parsedOptions = options;
|
|
249
129
|
|
|
@@ -256,6 +136,10 @@ function parseRelationExpressions(options) {
|
|
|
256
136
|
}
|
|
257
137
|
|
|
258
138
|
parsedOptions[optionName] = parseRelationExpression(optionName, option);
|
|
139
|
+
} else if (!(option === undefined || typeof option === 'boolean' || Array.isArray(option))) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`expected ${optionName} option value "${option}" to be a boolean, an array of relation paths or a relation expression`,
|
|
142
|
+
);
|
|
259
143
|
}
|
|
260
144
|
}
|
|
261
145
|
|
|
@@ -288,14 +172,6 @@ function parseRelationExpression(optionName, expression) {
|
|
|
288
172
|
throw createError(`aliases like "${alias.$relation} as ${alias.$name}" are not supported`);
|
|
289
173
|
}
|
|
290
174
|
|
|
291
|
-
// `*` and `^` only have a meaning at the end of a relation path. Anywhere else
|
|
292
|
-
// they are parsed as relation names that would never match.
|
|
293
|
-
const token = findNode(parsedExpression.node, (node) => /^(\*|\^\d*)$/.test(node.$relation));
|
|
294
|
-
|
|
295
|
-
if (token) {
|
|
296
|
-
throw createError(`"${token.$relation}" is only supported at the end of a relation path`);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
175
|
return parsedExpression;
|
|
300
176
|
}
|
|
301
177
|
|
|
@@ -342,72 +218,3 @@ function matchesRelationExpression(expression, relationPath) {
|
|
|
342
218
|
function isRelationExpression(value) {
|
|
343
219
|
return !!value && value.isObjectionRelationExpression === true;
|
|
344
220
|
}
|
|
345
|
-
|
|
346
|
-
function getCurrentNode(node, graphData) {
|
|
347
|
-
if (!graphData || !node) {
|
|
348
|
-
return null;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return graphData.currentGraph.nodeForNode(node);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// For `HasMany` and `HasOne` relations, the relate prop is the id of the
|
|
355
|
-
// related model. Use the id state of the input graph, since the parent's
|
|
356
|
-
// insert copies the foreign key into the related model, which can complete
|
|
357
|
-
// a composite id that contains it and would turn an insert into a relate (#2544).
|
|
358
|
-
function hasRelateProp(node) {
|
|
359
|
-
const relation = node.parentEdge.relation;
|
|
360
|
-
|
|
361
|
-
if (relation.isObjectionHasManyRelation) {
|
|
362
|
-
return node.hasId;
|
|
363
|
-
} else {
|
|
364
|
-
return relation.hasRelateProp(node.obj);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// An ignored model that isn't the current model of a BelongsToOneRelation
|
|
369
|
-
// doesn't replace it, so we keep the current one instead of removing it as
|
|
370
|
-
// missing.
|
|
371
|
-
function hasIgnoredOtherModel(currentNode, graphData) {
|
|
372
|
-
const { relation } = currentNode.parentEdge;
|
|
373
|
-
const parentNode = getNode(currentNode.parentNode, graphData.graph);
|
|
374
|
-
|
|
375
|
-
return (
|
|
376
|
-
relation.isObjectionBelongsToOneRelation &&
|
|
377
|
-
!!parentNode &&
|
|
378
|
-
parentNode.edges.some(
|
|
379
|
-
(edge) =>
|
|
380
|
-
edge.relation === relation &&
|
|
381
|
-
edge.isOwnerNode(parentNode) &&
|
|
382
|
-
graphData.graphOptions.shouldIgnore(edge.relatedNode, graphData),
|
|
383
|
-
)
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// A row that the graph keeps in another place is unrelated here instead of
|
|
388
|
-
// being deleted, unless it's a has-many row that the graph relates through the
|
|
389
|
-
// same relation: That relate moves it by overwriting the foreign key, which
|
|
390
|
-
// may not be nullable.
|
|
391
|
-
function shouldUnrelateKeptRow(currentNode, graphData) {
|
|
392
|
-
const keptNode = graphData.keptNodeForRow(currentNode);
|
|
393
|
-
const { relation } = currentNode.parentEdge;
|
|
394
|
-
|
|
395
|
-
return (
|
|
396
|
-
!!keptNode &&
|
|
397
|
-
!(relation.isObjectionHasManyRelation && keptNode.parentEdge?.relation === relation)
|
|
398
|
-
);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
function getNode(currentNode, graph) {
|
|
402
|
-
if (!graph || !currentNode) {
|
|
403
|
-
return null;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
return graph.nodeForNode(currentNode);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
module.exports = {
|
|
410
|
-
GraphOptions,
|
|
411
|
-
OPTION_NAMES,
|
|
412
|
-
FetchStrategy,
|
|
413
|
-
};
|