@snowtop/ent 0.1.0-alpha160-test7 → 0.1.0-alpha160
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/core/query/shared_assoc_test.d.ts +2 -0
- package/core/query/shared_assoc_test.js +804 -0
- package/core/query/shared_test.d.ts +21 -0
- package/core/query/shared_test.js +736 -0
- package/graphql/query/shared_assoc_test.d.ts +1 -0
- package/graphql/query/shared_assoc_test.js +203 -0
- package/package.json +8 -53
- package/dist/package.json +0 -64
- package/src/action/action.ts +0 -330
- package/src/action/executor.ts +0 -453
- package/src/action/experimental_action.ts +0 -277
- package/src/action/index.ts +0 -31
- package/src/action/operations.ts +0 -967
- package/src/action/orchestrator.ts +0 -1527
- package/src/action/privacy.ts +0 -37
- package/src/action/relative_value.ts +0 -242
- package/src/action/transaction.ts +0 -38
- package/src/auth/auth.ts +0 -77
- package/src/auth/index.ts +0 -8
- package/src/core/base.ts +0 -367
- package/src/core/clause.ts +0 -1065
- package/src/core/config.ts +0 -219
- package/src/core/const.ts +0 -5
- package/src/core/context.ts +0 -135
- package/src/core/convert.ts +0 -106
- package/src/core/date.ts +0 -23
- package/src/core/db.ts +0 -498
- package/src/core/ent.ts +0 -1740
- package/src/core/global_schema.ts +0 -49
- package/src/core/loaders/assoc_count_loader.ts +0 -99
- package/src/core/loaders/assoc_edge_loader.ts +0 -250
- package/src/core/loaders/index.ts +0 -12
- package/src/core/loaders/loader.ts +0 -66
- package/src/core/loaders/object_loader.ts +0 -489
- package/src/core/loaders/query_loader.ts +0 -314
- package/src/core/loaders/raw_count_loader.ts +0 -175
- package/src/core/logger.ts +0 -49
- package/src/core/privacy.ts +0 -660
- package/src/core/query/assoc_query.ts +0 -240
- package/src/core/query/custom_clause_query.ts +0 -174
- package/src/core/query/custom_query.ts +0 -302
- package/src/core/query/index.ts +0 -9
- package/src/core/query/query.ts +0 -674
- package/src/core/query_impl.ts +0 -32
- package/src/core/viewer.ts +0 -52
- package/src/ent.code-workspace +0 -73
- package/src/graphql/builtins/connection.ts +0 -25
- package/src/graphql/builtins/edge.ts +0 -16
- package/src/graphql/builtins/node.ts +0 -12
- package/src/graphql/graphql.ts +0 -891
- package/src/graphql/graphql_field_helpers.ts +0 -221
- package/src/graphql/index.ts +0 -42
- package/src/graphql/mutations/union.ts +0 -39
- package/src/graphql/node_resolver.ts +0 -122
- package/src/graphql/query/connection_type.ts +0 -113
- package/src/graphql/query/edge_connection.ts +0 -171
- package/src/graphql/query/page_info.ts +0 -34
- package/src/graphql/query/shared_edge_connection.ts +0 -287
- package/src/graphql/scalars/orderby_direction.ts +0 -13
- package/src/graphql/scalars/time.ts +0 -38
- package/src/imports/dataz/example1/_auth.ts +0 -51
- package/src/imports/dataz/example1/_viewer.ts +0 -35
- package/src/imports/index.ts +0 -213
- package/src/index.ts +0 -145
- package/src/parse_schema/parse.ts +0 -585
- package/src/schema/base_schema.ts +0 -224
- package/src/schema/field.ts +0 -1087
- package/src/schema/index.ts +0 -53
- package/src/schema/json_field.ts +0 -94
- package/src/schema/schema.ts +0 -1028
- package/src/schema/struct_field.ts +0 -234
- package/src/schema/union_field.ts +0 -105
- package/src/scripts/custom_compiler.ts +0 -331
- package/src/scripts/custom_graphql.ts +0 -550
- package/src/scripts/migrate_v0.1.ts +0 -41
- package/src/scripts/move_types.ts +0 -131
- package/src/scripts/read_schema.ts +0 -67
- package/src/setupPackage.js +0 -42
- package/src/testutils/action/complex_schemas.ts +0 -517
- package/src/testutils/builder.ts +0 -422
- package/src/testutils/context/test_context.ts +0 -25
- package/src/testutils/db/fixture.ts +0 -32
- package/src/testutils/db/temp_db.ts +0 -941
- package/src/testutils/db/value.ts +0 -294
- package/src/testutils/db_mock.ts +0 -351
- package/src/testutils/db_time_zone.ts +0 -40
- package/src/testutils/ent-graphql-tests/index.ts +0 -653
- package/src/testutils/fake_comms.ts +0 -50
- package/src/testutils/fake_data/const.ts +0 -64
- package/src/testutils/fake_data/events_query.ts +0 -145
- package/src/testutils/fake_data/fake_contact.ts +0 -150
- package/src/testutils/fake_data/fake_event.ts +0 -150
- package/src/testutils/fake_data/fake_tag.ts +0 -139
- package/src/testutils/fake_data/fake_user.ts +0 -232
- package/src/testutils/fake_data/index.ts +0 -1
- package/src/testutils/fake_data/internal.ts +0 -8
- package/src/testutils/fake_data/tag_query.ts +0 -56
- package/src/testutils/fake_data/test_helpers.ts +0 -388
- package/src/testutils/fake_data/user_query.ts +0 -524
- package/src/testutils/fake_log.ts +0 -52
- package/src/testutils/mock_date.ts +0 -10
- package/src/testutils/mock_log.ts +0 -39
- package/src/testutils/parse_sql.ts +0 -685
- package/src/testutils/test_edge_global_schema.ts +0 -49
- package/src/testutils/write.ts +0 -70
- package/src/tsc/ast.ts +0 -351
- package/src/tsc/compilerOptions.ts +0 -85
- package/src/tsc/move_generated.ts +0 -191
- package/src/tsc/transform.ts +0 -226
- package/src/tsc/transform_action.ts +0 -224
- package/src/tsc/transform_ent.ts +0 -66
- package/src/tsc/transform_schema.ts +0 -546
- package/tsconfig.json +0 -20
- /package/{dist/action → action}/action.d.ts +0 -0
- /package/{dist/action → action}/action.js +0 -0
- /package/{dist/action → action}/executor.d.ts +0 -0
- /package/{dist/action → action}/executor.js +0 -0
- /package/{dist/action → action}/experimental_action.d.ts +0 -0
- /package/{dist/action → action}/experimental_action.js +0 -0
- /package/{dist/action → action}/index.d.ts +0 -0
- /package/{dist/action → action}/index.js +0 -0
- /package/{dist/action → action}/operations.d.ts +0 -0
- /package/{dist/action → action}/operations.js +0 -0
- /package/{dist/action → action}/orchestrator.d.ts +0 -0
- /package/{dist/action → action}/orchestrator.js +0 -0
- /package/{dist/action → action}/privacy.d.ts +0 -0
- /package/{dist/action → action}/privacy.js +0 -0
- /package/{dist/action → action}/relative_value.d.ts +0 -0
- /package/{dist/action → action}/relative_value.js +0 -0
- /package/{dist/action → action}/transaction.d.ts +0 -0
- /package/{dist/action → action}/transaction.js +0 -0
- /package/{dist/auth → auth}/auth.d.ts +0 -0
- /package/{dist/auth → auth}/auth.js +0 -0
- /package/{dist/auth → auth}/index.d.ts +0 -0
- /package/{dist/auth → auth}/index.js +0 -0
- /package/{dist/core → core}/base.d.ts +0 -0
- /package/{dist/core → core}/base.js +0 -0
- /package/{dist/core → core}/clause.d.ts +0 -0
- /package/{dist/core → core}/clause.js +0 -0
- /package/{dist/core → core}/config.d.ts +0 -0
- /package/{dist/core → core}/config.js +0 -0
- /package/{dist/core → core}/const.d.ts +0 -0
- /package/{dist/core → core}/const.js +0 -0
- /package/{dist/core → core}/context.d.ts +0 -0
- /package/{dist/core → core}/context.js +0 -0
- /package/{dist/core → core}/convert.d.ts +0 -0
- /package/{dist/core → core}/convert.js +0 -0
- /package/{dist/core → core}/date.d.ts +0 -0
- /package/{dist/core → core}/date.js +0 -0
- /package/{dist/core → core}/db.d.ts +0 -0
- /package/{dist/core → core}/db.js +0 -0
- /package/{dist/core → core}/ent.d.ts +0 -0
- /package/{dist/core → core}/ent.js +0 -0
- /package/{dist/core → core}/global_schema.d.ts +0 -0
- /package/{dist/core → core}/global_schema.js +0 -0
- /package/{dist/core → core}/loaders/assoc_count_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/assoc_count_loader.js +0 -0
- /package/{dist/core → core}/loaders/assoc_edge_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/assoc_edge_loader.js +0 -0
- /package/{dist/core → core}/loaders/index.d.ts +0 -0
- /package/{dist/core → core}/loaders/index.js +0 -0
- /package/{dist/core → core}/loaders/loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/loader.js +0 -0
- /package/{dist/core → core}/loaders/object_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/object_loader.js +0 -0
- /package/{dist/core → core}/loaders/query_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/query_loader.js +0 -0
- /package/{dist/core → core}/loaders/raw_count_loader.d.ts +0 -0
- /package/{dist/core → core}/loaders/raw_count_loader.js +0 -0
- /package/{dist/core → core}/logger.d.ts +0 -0
- /package/{dist/core → core}/logger.js +0 -0
- /package/{dist/core → core}/privacy.d.ts +0 -0
- /package/{dist/core → core}/privacy.js +0 -0
- /package/{dist/core → core}/query/assoc_query.d.ts +0 -0
- /package/{dist/core → core}/query/assoc_query.js +0 -0
- /package/{dist/core → core}/query/custom_clause_query.d.ts +0 -0
- /package/{dist/core → core}/query/custom_clause_query.js +0 -0
- /package/{dist/core → core}/query/custom_query.d.ts +0 -0
- /package/{dist/core → core}/query/custom_query.js +0 -0
- /package/{dist/core → core}/query/index.d.ts +0 -0
- /package/{dist/core → core}/query/index.js +0 -0
- /package/{dist/core → core}/query/query.d.ts +0 -0
- /package/{dist/core → core}/query/query.js +0 -0
- /package/{dist/core → core}/query_impl.d.ts +0 -0
- /package/{dist/core → core}/query_impl.js +0 -0
- /package/{dist/core → core}/viewer.d.ts +0 -0
- /package/{dist/core → core}/viewer.js +0 -0
- /package/{dist/graphql → graphql}/builtins/connection.d.ts +0 -0
- /package/{dist/graphql → graphql}/builtins/connection.js +0 -0
- /package/{dist/graphql → graphql}/builtins/edge.d.ts +0 -0
- /package/{dist/graphql → graphql}/builtins/edge.js +0 -0
- /package/{dist/graphql → graphql}/builtins/node.d.ts +0 -0
- /package/{dist/graphql → graphql}/builtins/node.js +0 -0
- /package/{dist/graphql → graphql}/graphql.d.ts +0 -0
- /package/{dist/graphql → graphql}/graphql.js +0 -0
- /package/{dist/graphql → graphql}/graphql_field_helpers.d.ts +0 -0
- /package/{dist/graphql → graphql}/graphql_field_helpers.js +0 -0
- /package/{dist/graphql → graphql}/index.d.ts +0 -0
- /package/{dist/graphql → graphql}/index.js +0 -0
- /package/{dist/graphql → graphql}/mutations/union.d.ts +0 -0
- /package/{dist/graphql → graphql}/mutations/union.js +0 -0
- /package/{dist/graphql → graphql}/node_resolver.d.ts +0 -0
- /package/{dist/graphql → graphql}/node_resolver.js +0 -0
- /package/{dist/graphql → graphql}/query/connection_type.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/connection_type.js +0 -0
- /package/{dist/graphql → graphql}/query/edge_connection.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/edge_connection.js +0 -0
- /package/{dist/graphql → graphql}/query/page_info.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/page_info.js +0 -0
- /package/{dist/graphql → graphql}/query/shared_edge_connection.d.ts +0 -0
- /package/{dist/graphql → graphql}/query/shared_edge_connection.js +0 -0
- /package/{dist/graphql → graphql}/scalars/orderby_direction.d.ts +0 -0
- /package/{dist/graphql → graphql}/scalars/orderby_direction.js +0 -0
- /package/{dist/graphql → graphql}/scalars/time.d.ts +0 -0
- /package/{dist/graphql → graphql}/scalars/time.js +0 -0
- /package/{dist/imports → imports}/dataz/example1/_auth.d.ts +0 -0
- /package/{dist/imports → imports}/dataz/example1/_auth.js +0 -0
- /package/{dist/imports → imports}/dataz/example1/_viewer.d.ts +0 -0
- /package/{dist/imports → imports}/dataz/example1/_viewer.js +0 -0
- /package/{dist/imports → imports}/index.d.ts +0 -0
- /package/{dist/imports → imports}/index.js +0 -0
- /package/{dist/index.d.ts → index.d.ts} +0 -0
- /package/{dist/index.js → index.js} +0 -0
- /package/{dist/parse_schema → parse_schema}/parse.d.ts +0 -0
- /package/{dist/parse_schema → parse_schema}/parse.js +0 -0
- /package/{dist/schema → schema}/base_schema.d.ts +0 -0
- /package/{dist/schema → schema}/base_schema.js +0 -0
- /package/{dist/schema → schema}/field.d.ts +0 -0
- /package/{dist/schema → schema}/field.js +0 -0
- /package/{dist/schema → schema}/index.d.ts +0 -0
- /package/{dist/schema → schema}/index.js +0 -0
- /package/{dist/schema → schema}/json_field.d.ts +0 -0
- /package/{dist/schema → schema}/json_field.js +0 -0
- /package/{dist/schema → schema}/schema.d.ts +0 -0
- /package/{dist/schema → schema}/schema.js +0 -0
- /package/{dist/schema → schema}/struct_field.d.ts +0 -0
- /package/{dist/schema → schema}/struct_field.js +0 -0
- /package/{dist/schema → schema}/union_field.d.ts +0 -0
- /package/{dist/schema → schema}/union_field.js +0 -0
- /package/{dist/scripts → scripts}/custom_compiler.d.ts +0 -0
- /package/{dist/scripts → scripts}/custom_compiler.js +0 -0
- /package/{dist/scripts → scripts}/custom_graphql.d.ts +0 -0
- /package/{dist/scripts → scripts}/custom_graphql.js +0 -0
- /package/{dist/scripts → scripts}/migrate_v0.1.d.ts +0 -0
- /package/{dist/scripts → scripts}/migrate_v0.1.js +0 -0
- /package/{dist/scripts → scripts}/move_types.d.ts +0 -0
- /package/{dist/scripts → scripts}/move_types.js +0 -0
- /package/{dist/scripts → scripts}/read_schema.d.ts +0 -0
- /package/{dist/scripts → scripts}/read_schema.js +0 -0
- /package/{dist/testutils → testutils}/action/complex_schemas.d.ts +0 -0
- /package/{dist/testutils → testutils}/action/complex_schemas.js +0 -0
- /package/{dist/testutils → testutils}/builder.d.ts +0 -0
- /package/{dist/testutils → testutils}/builder.js +0 -0
- /package/{dist/testutils → testutils}/context/test_context.d.ts +0 -0
- /package/{dist/testutils → testutils}/context/test_context.js +0 -0
- /package/{dist/testutils → testutils}/db/fixture.d.ts +0 -0
- /package/{dist/testutils → testutils}/db/fixture.js +0 -0
- /package/{dist/testutils → testutils}/db/temp_db.d.ts +0 -0
- /package/{dist/testutils → testutils}/db/temp_db.js +0 -0
- /package/{dist/testutils → testutils}/db/value.d.ts +0 -0
- /package/{dist/testutils → testutils}/db/value.js +0 -0
- /package/{dist/testutils → testutils}/db_mock.d.ts +0 -0
- /package/{dist/testutils → testutils}/db_mock.js +0 -0
- /package/{dist/testutils → testutils}/db_time_zone.d.ts +0 -0
- /package/{dist/testutils → testutils}/db_time_zone.js +0 -0
- /package/{dist/testutils → testutils}/ent-graphql-tests/index.d.ts +0 -0
- /package/{dist/testutils → testutils}/ent-graphql-tests/index.js +0 -0
- /package/{dist/testutils → testutils}/fake_comms.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_comms.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/const.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/const.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/events_query.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/events_query.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_contact.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_contact.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_event.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_event.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_tag.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_tag.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_user.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/fake_user.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/index.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/index.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/internal.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/internal.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/tag_query.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/tag_query.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/test_helpers.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/test_helpers.js +0 -0
- /package/{dist/testutils → testutils}/fake_data/user_query.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_data/user_query.js +0 -0
- /package/{dist/testutils → testutils}/fake_log.d.ts +0 -0
- /package/{dist/testutils → testutils}/fake_log.js +0 -0
- /package/{dist/testutils → testutils}/mock_date.d.ts +0 -0
- /package/{dist/testutils → testutils}/mock_date.js +0 -0
- /package/{dist/testutils → testutils}/mock_log.d.ts +0 -0
- /package/{dist/testutils → testutils}/mock_log.js +0 -0
- /package/{dist/testutils → testutils}/parse_sql.d.ts +0 -0
- /package/{dist/testutils → testutils}/parse_sql.js +0 -0
- /package/{dist/testutils → testutils}/test_edge_global_schema.d.ts +0 -0
- /package/{dist/testutils → testutils}/test_edge_global_schema.js +0 -0
- /package/{dist/testutils → testutils}/write.d.ts +0 -0
- /package/{dist/testutils → testutils}/write.js +0 -0
- /package/{dist/tsc → tsc}/ast.d.ts +0 -0
- /package/{dist/tsc → tsc}/ast.js +0 -0
- /package/{dist/tsc → tsc}/compilerOptions.d.ts +0 -0
- /package/{dist/tsc → tsc}/compilerOptions.js +0 -0
- /package/{dist/tsc → tsc}/move_generated.d.ts +0 -0
- /package/{dist/tsc → tsc}/move_generated.js +0 -0
- /package/{dist/tsc → tsc}/transform.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform.js +0 -0
- /package/{dist/tsc → tsc}/transform_action.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform_action.js +0 -0
- /package/{dist/tsc → tsc}/transform_ent.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform_ent.js +0 -0
- /package/{dist/tsc → tsc}/transform_schema.d.ts +0 -0
- /package/{dist/tsc → tsc}/transform_schema.js +0 -0
package/src/action/operations.ts
DELETED
|
@@ -1,967 +0,0 @@
|
|
|
1
|
-
import { Queryer, SyncQueryer } from "../core/db";
|
|
2
|
-
import {
|
|
3
|
-
Viewer,
|
|
4
|
-
Ent,
|
|
5
|
-
ID,
|
|
6
|
-
Data,
|
|
7
|
-
DataOptions,
|
|
8
|
-
EditRowOptions,
|
|
9
|
-
LoadEntOptions,
|
|
10
|
-
Context,
|
|
11
|
-
CreateRowOptions,
|
|
12
|
-
} from "../core/base";
|
|
13
|
-
import { Executor } from "../action/action";
|
|
14
|
-
import * as clause from "../core/clause";
|
|
15
|
-
import { WriteOperation, Builder } from "../action";
|
|
16
|
-
import { ObjectLoader } from "../core/loaders";
|
|
17
|
-
import {
|
|
18
|
-
getStorageKey,
|
|
19
|
-
SQLStatementOperation,
|
|
20
|
-
TransformedEdgeUpdateOperation,
|
|
21
|
-
} from "../schema/schema";
|
|
22
|
-
import { __getGlobalSchema } from "../core/global_schema";
|
|
23
|
-
import {
|
|
24
|
-
AssocEdgeData,
|
|
25
|
-
buildQuery,
|
|
26
|
-
createRow,
|
|
27
|
-
createRowSync,
|
|
28
|
-
deleteRows,
|
|
29
|
-
deleteRowsSync,
|
|
30
|
-
editRow,
|
|
31
|
-
editRowSync,
|
|
32
|
-
loadEdgeData,
|
|
33
|
-
logQuery,
|
|
34
|
-
parameterizedQueryOptions,
|
|
35
|
-
} from "../core/ent";
|
|
36
|
-
|
|
37
|
-
export interface UpdatedOperation {
|
|
38
|
-
operation: WriteOperation;
|
|
39
|
-
builder: Builder<any>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// PS: anytime this is updated, need to update ConditionalOperation
|
|
43
|
-
export interface DataOperation<T extends Ent = Ent> {
|
|
44
|
-
// builder associated with the operation
|
|
45
|
-
builder: Builder<T>;
|
|
46
|
-
// any data that needs to be fetched before the write should be fetched here
|
|
47
|
-
// because of how SQLite works, we can't use asynchronous fetches during the write
|
|
48
|
-
// so we batch up fetching to be done beforehand here
|
|
49
|
-
preFetch?(queryer: Queryer, context?: Context): Promise<void>;
|
|
50
|
-
|
|
51
|
-
// performWriteSync is called for SQLITE and APIs that don't support asynchronous writes
|
|
52
|
-
performWriteSync(queryer: SyncQueryer, context?: Context): void;
|
|
53
|
-
performWrite(queryer: Queryer, context?: Context): Promise<void>;
|
|
54
|
-
|
|
55
|
-
placeholderID?: ID;
|
|
56
|
-
returnedRow?(): Data | null; // optional to get the raw row
|
|
57
|
-
createdEnt?(viewer: Viewer): T | null; // optional to indicate the ent that was created
|
|
58
|
-
|
|
59
|
-
// optional to indicate that the operation should not be performed. used for conditional changesets/operations
|
|
60
|
-
shortCircuit?(executor: Executor): boolean;
|
|
61
|
-
updatedOperation?(): UpdatedOperation | null;
|
|
62
|
-
resolve?(executor: Executor): void; //throws?
|
|
63
|
-
|
|
64
|
-
// any data that needs to be fetched asynchronously post write|post transaction
|
|
65
|
-
postFetch?(queryer: Queryer, context?: Context): Promise<void>;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export class DeleteNodeOperation implements DataOperation {
|
|
69
|
-
constructor(
|
|
70
|
-
private id: ID,
|
|
71
|
-
public readonly builder: Builder<Ent>,
|
|
72
|
-
private options: DataOptions,
|
|
73
|
-
) {}
|
|
74
|
-
|
|
75
|
-
async performWrite(queryer: Queryer, context?: Context): Promise<void> {
|
|
76
|
-
let options = {
|
|
77
|
-
...this.options,
|
|
78
|
-
context,
|
|
79
|
-
};
|
|
80
|
-
return deleteRows(queryer, options, clause.Eq("id", this.id));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
performWriteSync(queryer: SyncQueryer, context?: Context): void {
|
|
84
|
-
let options = {
|
|
85
|
-
...this.options,
|
|
86
|
-
context,
|
|
87
|
-
};
|
|
88
|
-
return deleteRowsSync(queryer, options, clause.Eq("id", this.id));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export class RawQueryOperation<
|
|
93
|
-
TEnt extends Ent<TViewer>,
|
|
94
|
-
TViewer extends Viewer = Viewer,
|
|
95
|
-
> implements DataOperation<TEnt>
|
|
96
|
-
{
|
|
97
|
-
constructor(
|
|
98
|
-
public builder: Builder<TEnt, TViewer>,
|
|
99
|
-
private queries: (string | parameterizedQueryOptions)[],
|
|
100
|
-
) {}
|
|
101
|
-
|
|
102
|
-
async performWrite(queryer: Queryer, context?: Context): Promise<void> {
|
|
103
|
-
for (const q of this.queries) {
|
|
104
|
-
if (typeof q === "string") {
|
|
105
|
-
logQuery(q, []);
|
|
106
|
-
await queryer.query(q);
|
|
107
|
-
} else {
|
|
108
|
-
logQuery(q.query, q.logValues || []);
|
|
109
|
-
await queryer.query(q.query, q.values);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
performWriteSync(queryer: SyncQueryer, context?: Context): void {
|
|
115
|
-
for (const q of this.queries) {
|
|
116
|
-
if (typeof q === "string") {
|
|
117
|
-
logQuery(q, []);
|
|
118
|
-
queryer.execSync(q);
|
|
119
|
-
} else {
|
|
120
|
-
logQuery(q.query, q.logValues || []);
|
|
121
|
-
queryer.execSync(q.query, q.values);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface EditNodeOptions<T extends Ent> extends EditRowOptions {
|
|
128
|
-
fieldsToResolve: string[];
|
|
129
|
-
loadEntOptions: LoadEntOptions<T>;
|
|
130
|
-
key: string;
|
|
131
|
-
onConflict?: CreateRowOptions["onConflict"];
|
|
132
|
-
builder: Builder<T>;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export class EditNodeOperation<T extends Ent> implements DataOperation {
|
|
136
|
-
private row: Data | null = null;
|
|
137
|
-
placeholderID?: ID | undefined;
|
|
138
|
-
private updatedOp: UpdatedOperation | null = null;
|
|
139
|
-
public builder: Builder<T>;
|
|
140
|
-
private resolved = false;
|
|
141
|
-
|
|
142
|
-
constructor(
|
|
143
|
-
public options: EditNodeOptions<T>,
|
|
144
|
-
private existingEnt: Ent | null = null,
|
|
145
|
-
) {
|
|
146
|
-
this.builder = options.builder;
|
|
147
|
-
this.placeholderID = options.builder.placeholderID;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
resolve<T extends Ent>(executor: Executor): void {
|
|
151
|
-
if (!this.options.fieldsToResolve.length) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (this.resolved) {
|
|
156
|
-
throw new Error(`already resolved ${this.placeholderID}`);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
let fields = this.options.fields;
|
|
160
|
-
this.options.fieldsToResolve.forEach((fieldName) => {
|
|
161
|
-
let value: Builder<T> | null = fields[fieldName];
|
|
162
|
-
if (!value) {
|
|
163
|
-
throw new Error(
|
|
164
|
-
`trying to resolve field ${fieldName} but not a valid field`,
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
let ent = executor.resolveValue(value.placeholderID);
|
|
168
|
-
if (!ent) {
|
|
169
|
-
throw new Error(
|
|
170
|
-
`couldn't resolve field \`${fieldName}\` with value ${value.placeholderID}`,
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
fields[fieldName] = ent.id;
|
|
174
|
-
});
|
|
175
|
-
this.options.fields = fields;
|
|
176
|
-
this.resolved = true;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
private hasData(data: Data) {
|
|
180
|
-
for (const _k in data) {
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
private buildOnConflictQuery(options: EditNodeOptions<T>) {
|
|
187
|
-
// assumes onConflict has been checked already...
|
|
188
|
-
const clauses: clause.Clause[] = [];
|
|
189
|
-
for (const col of this.options.onConflict!.onConflictCols) {
|
|
190
|
-
clauses.push(clause.Eq(col, options.fields[col]));
|
|
191
|
-
}
|
|
192
|
-
const cls = clause.AndOptional(...clauses);
|
|
193
|
-
const query = this.buildReloadQuery(options, cls);
|
|
194
|
-
return { cls, query };
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async performWrite(queryer: Queryer, context?: Context) {
|
|
198
|
-
let options = {
|
|
199
|
-
...this.options,
|
|
200
|
-
context,
|
|
201
|
-
};
|
|
202
|
-
if (this.existingEnt) {
|
|
203
|
-
if (this.hasData(options.fields)) {
|
|
204
|
-
// even this with returning * may not always work if transformed...
|
|
205
|
-
// we can have a transformed flag to see if it should be returned?
|
|
206
|
-
this.row = await editRow(queryer, options, "RETURNING *");
|
|
207
|
-
} else {
|
|
208
|
-
// @ts-ignore
|
|
209
|
-
this.row = this.existingEnt["data"];
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
// TODO: eventually, when we officially support auto-increment ids. need to make sure/test that this works
|
|
213
|
-
// https://github.com/lolopinto/ent/issues/1431
|
|
214
|
-
|
|
215
|
-
this.row = await createRow(queryer, options, "RETURNING *");
|
|
216
|
-
const key = this.options.key;
|
|
217
|
-
|
|
218
|
-
if (this.row && this.row[key] !== this.options.fields[key]) {
|
|
219
|
-
this.updatedOp = {
|
|
220
|
-
builder: this.options.builder,
|
|
221
|
-
operation: WriteOperation.Edit,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
if (
|
|
225
|
-
this.row === null &&
|
|
226
|
-
this.options.onConflict &&
|
|
227
|
-
!this.options.onConflict.updateCols?.length
|
|
228
|
-
) {
|
|
229
|
-
// no row returned and on conflict, do nothing, have to fetch the conflict row back...
|
|
230
|
-
const { cls, query } = this.buildOnConflictQuery(options);
|
|
231
|
-
|
|
232
|
-
logQuery(query, cls.logValues());
|
|
233
|
-
const res = await queryer.query(query, cls.values());
|
|
234
|
-
this.row = res.rows[0];
|
|
235
|
-
this.updatedOp = {
|
|
236
|
-
builder: this.options.builder,
|
|
237
|
-
operation: WriteOperation.Edit,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
private buildReloadQuery(options: EditNodeOptions<T>, cls: clause.Clause) {
|
|
244
|
-
// TODO this isn't always an ObjectLoader. should throw or figure out a way to get query
|
|
245
|
-
// and run this on its own...
|
|
246
|
-
const loader = this.options.loadEntOptions.loaderFactory.createLoader(
|
|
247
|
-
options.context,
|
|
248
|
-
) as ObjectLoader<T>;
|
|
249
|
-
const opts = loader.getOptions();
|
|
250
|
-
if (opts.clause) {
|
|
251
|
-
let optionClause: clause.Clause | undefined;
|
|
252
|
-
if (typeof opts.clause === "function") {
|
|
253
|
-
optionClause = opts.clause();
|
|
254
|
-
} else {
|
|
255
|
-
optionClause = opts.clause;
|
|
256
|
-
}
|
|
257
|
-
if (optionClause) {
|
|
258
|
-
cls = clause.And(cls, optionClause);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const query = buildQuery({
|
|
263
|
-
fields: opts.fields.length ? opts.fields : ["*"],
|
|
264
|
-
tableName: options.tableName,
|
|
265
|
-
clause: cls,
|
|
266
|
-
});
|
|
267
|
-
return query;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
private reloadRow(queryer: SyncQueryer, id: ID, options: EditNodeOptions<T>) {
|
|
271
|
-
const query = this.buildReloadQuery(options, clause.Eq(options.key, id));
|
|
272
|
-
|
|
273
|
-
// special case log here because we're not going through any of the normal
|
|
274
|
-
// methods here because those are async and this is sync
|
|
275
|
-
// this is the only place we're doing this so only handling here
|
|
276
|
-
logQuery(query, [id]);
|
|
277
|
-
const r = queryer.querySync(query, [id]);
|
|
278
|
-
if (r.rows.length === 1) {
|
|
279
|
-
this.row = r.rows[0];
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
performWriteSync(queryer: SyncQueryer, context?: Context): void {
|
|
284
|
-
let options = {
|
|
285
|
-
...this.options,
|
|
286
|
-
context,
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
if (this.existingEnt) {
|
|
290
|
-
if (this.hasData(this.options.fields)) {
|
|
291
|
-
editRowSync(queryer, options, "RETURNING *");
|
|
292
|
-
this.reloadRow(queryer, this.existingEnt.id, options);
|
|
293
|
-
} else {
|
|
294
|
-
// @ts-ignore
|
|
295
|
-
this.row = this.existingEnt["data"];
|
|
296
|
-
}
|
|
297
|
-
} else {
|
|
298
|
-
createRowSync(queryer, options, "RETURNING *");
|
|
299
|
-
const id = options.fields[options.key];
|
|
300
|
-
this.reloadRow(queryer, id, options);
|
|
301
|
-
const key = this.options.key;
|
|
302
|
-
|
|
303
|
-
if (this.row && this.row[key] !== this.options.fields[key]) {
|
|
304
|
-
this.updatedOp = {
|
|
305
|
-
builder: this.options.builder,
|
|
306
|
-
operation: WriteOperation.Edit,
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
// if we can't find the id, try and load the on conflict row
|
|
310
|
-
// no returning * with sqlite and have to assume the row was created more often than not
|
|
311
|
-
|
|
312
|
-
// there's a world in which we combine into one query if on-conflict
|
|
313
|
-
// seems like it's safer not to and sqlite (only sync client we currently have) is fast enough
|
|
314
|
-
// (single-process) that it's fine to do two queries
|
|
315
|
-
|
|
316
|
-
// we wanna do this in both on conflict do nothing or on conflict update
|
|
317
|
-
if (this.row === null && this.options.onConflict) {
|
|
318
|
-
const { cls, query } = this.buildOnConflictQuery(options);
|
|
319
|
-
|
|
320
|
-
// special case log here because we're not going through any of the normal
|
|
321
|
-
// methods here because those are async and this is sync
|
|
322
|
-
// this is the only place we're doing this so only handling here
|
|
323
|
-
logQuery(query, cls.logValues());
|
|
324
|
-
const r = queryer.querySync(query, cls.values());
|
|
325
|
-
if (r.rows.length === 1) {
|
|
326
|
-
this.row = r.rows[0];
|
|
327
|
-
}
|
|
328
|
-
this.updatedOp = {
|
|
329
|
-
builder: this.options.builder,
|
|
330
|
-
operation: WriteOperation.Edit,
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
returnedRow(): Data | null {
|
|
337
|
-
return this.row;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
createdEnt(viewer: Viewer): T | null {
|
|
341
|
-
if (!this.row) {
|
|
342
|
-
return null;
|
|
343
|
-
}
|
|
344
|
-
return new this.options.loadEntOptions.ent(viewer, this.row);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
updatedOperation(): UpdatedOperation | null {
|
|
348
|
-
return this.updatedOp;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
interface EdgeOperationOptions {
|
|
353
|
-
operation: WriteOperation;
|
|
354
|
-
id1Placeholder?: boolean;
|
|
355
|
-
id2Placeholder?: boolean;
|
|
356
|
-
dataPlaceholder?: boolean;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
export interface AssocEdgeInputOptions extends AssocEdgeOptions {
|
|
360
|
-
time?: Date;
|
|
361
|
-
data?: string | Builder<Ent>;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
export interface AssocEdgeOptions {
|
|
365
|
-
// if passed. indicates that it's conditional on the current builder's operator not changing
|
|
366
|
-
// e.g. if an upsert is being done, and the builder changes from insert to update,
|
|
367
|
-
// then the edge write should not be done if this is true
|
|
368
|
-
conditional?: boolean;
|
|
369
|
-
|
|
370
|
-
// if passed and we have global tranformWrite options on edges, it disables the tranformations
|
|
371
|
-
// e.g. if we have edge soft delete enabled, this exists to delete the edge without soft deleting
|
|
372
|
-
disableTransformations?: boolean;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
export interface AssocEdgeInput extends AssocEdgeInputOptions {
|
|
376
|
-
id1: ID;
|
|
377
|
-
id1Type: string;
|
|
378
|
-
edgeType: string;
|
|
379
|
-
id2: ID;
|
|
380
|
-
id2Type: string;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export class EdgeOperation implements DataOperation {
|
|
384
|
-
private edgeData: AssocEdgeData | undefined;
|
|
385
|
-
private constructor(
|
|
386
|
-
public builder: Builder<any>,
|
|
387
|
-
public edgeInput: AssocEdgeInput,
|
|
388
|
-
private options: EdgeOperationOptions,
|
|
389
|
-
) {}
|
|
390
|
-
|
|
391
|
-
async preFetch(queryer: Queryer, context?: Context): Promise<void> {
|
|
392
|
-
let edgeData = await loadEdgeData(this.edgeInput.edgeType);
|
|
393
|
-
if (!edgeData) {
|
|
394
|
-
throw new Error(`error loading edge data for ${this.edgeInput.edgeType}`);
|
|
395
|
-
}
|
|
396
|
-
this.edgeData = edgeData;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
async performWrite(queryer: Queryer, context?: Context): Promise<void> {
|
|
400
|
-
if (!this.edgeData) {
|
|
401
|
-
throw new Error(
|
|
402
|
-
`error fetching edgeData for type ${this.edgeInput.edgeType}`,
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
|
-
switch (this.options.operation) {
|
|
406
|
-
case WriteOperation.Delete:
|
|
407
|
-
return this.performDeleteWrite(
|
|
408
|
-
queryer,
|
|
409
|
-
this.edgeData,
|
|
410
|
-
this.edgeInput,
|
|
411
|
-
context,
|
|
412
|
-
);
|
|
413
|
-
case WriteOperation.Insert:
|
|
414
|
-
case WriteOperation.Edit:
|
|
415
|
-
return this.performInsertWrite(
|
|
416
|
-
queryer,
|
|
417
|
-
this.edgeData,
|
|
418
|
-
this.edgeInput,
|
|
419
|
-
context,
|
|
420
|
-
);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
performWriteSync(queryer: SyncQueryer, context?: Context): void {
|
|
425
|
-
if (!this.edgeData) {
|
|
426
|
-
throw new Error(
|
|
427
|
-
`error fetching edgeData for type ${this.edgeInput.edgeType}`,
|
|
428
|
-
);
|
|
429
|
-
}
|
|
430
|
-
switch (this.options.operation) {
|
|
431
|
-
case WriteOperation.Delete:
|
|
432
|
-
return this.performDeleteWriteSync(
|
|
433
|
-
queryer,
|
|
434
|
-
this.edgeData,
|
|
435
|
-
this.edgeInput,
|
|
436
|
-
context,
|
|
437
|
-
);
|
|
438
|
-
case WriteOperation.Insert:
|
|
439
|
-
case WriteOperation.Edit:
|
|
440
|
-
return this.performInsertWriteSync(
|
|
441
|
-
queryer,
|
|
442
|
-
this.edgeData,
|
|
443
|
-
this.edgeInput,
|
|
444
|
-
context,
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
private getDeleteRowParams(
|
|
450
|
-
edgeData: AssocEdgeData,
|
|
451
|
-
edge: AssocEdgeInput,
|
|
452
|
-
context?: Context,
|
|
453
|
-
) {
|
|
454
|
-
let transformed: TransformedEdgeUpdateOperation | null = null;
|
|
455
|
-
let op = SQLStatementOperation.Delete;
|
|
456
|
-
let updateData: Data | null = null;
|
|
457
|
-
|
|
458
|
-
const transformedEdgeWrite = __getGlobalSchema()?.transformEdgeWrite;
|
|
459
|
-
if (transformedEdgeWrite && !edge.disableTransformations) {
|
|
460
|
-
transformed = transformedEdgeWrite({
|
|
461
|
-
op: SQLStatementOperation.Delete,
|
|
462
|
-
edge,
|
|
463
|
-
});
|
|
464
|
-
if (transformed) {
|
|
465
|
-
op = transformed.op;
|
|
466
|
-
if (transformed.op === SQLStatementOperation.Insert) {
|
|
467
|
-
throw new Error(`cannot currently transform a delete into an insert`);
|
|
468
|
-
}
|
|
469
|
-
if (transformed.op === SQLStatementOperation.Update) {
|
|
470
|
-
if (!transformed.data) {
|
|
471
|
-
throw new Error(
|
|
472
|
-
`cannot transform a delete into an update without providing data`,
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
|
-
updateData = transformed.data;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
return {
|
|
481
|
-
op,
|
|
482
|
-
updateData,
|
|
483
|
-
options: {
|
|
484
|
-
tableName: edgeData.edgeTable,
|
|
485
|
-
context,
|
|
486
|
-
},
|
|
487
|
-
clause: clause.And(
|
|
488
|
-
clause.Eq("id1", edge.id1),
|
|
489
|
-
clause.Eq("id2", edge.id2),
|
|
490
|
-
clause.Eq("edge_type", edge.edgeType),
|
|
491
|
-
),
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
private async performDeleteWrite(
|
|
496
|
-
q: Queryer,
|
|
497
|
-
edgeData: AssocEdgeData,
|
|
498
|
-
edge: AssocEdgeInput,
|
|
499
|
-
context?: Context,
|
|
500
|
-
): Promise<void> {
|
|
501
|
-
const params = this.getDeleteRowParams(edgeData, edge, context);
|
|
502
|
-
if (params.op === SQLStatementOperation.Delete) {
|
|
503
|
-
return deleteRows(q, params.options, params.clause);
|
|
504
|
-
} else {
|
|
505
|
-
if (params.op !== SQLStatementOperation.Update) {
|
|
506
|
-
throw new Error(`invalid operation ${params.op}`);
|
|
507
|
-
}
|
|
508
|
-
await editRow(q, {
|
|
509
|
-
tableName: params.options.tableName,
|
|
510
|
-
whereClause: params.clause,
|
|
511
|
-
fields: params.updateData!,
|
|
512
|
-
fieldsToLog: params.updateData!,
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
private performDeleteWriteSync(
|
|
518
|
-
q: SyncQueryer,
|
|
519
|
-
edgeData: AssocEdgeData,
|
|
520
|
-
edge: AssocEdgeInput,
|
|
521
|
-
context?: Context,
|
|
522
|
-
): void {
|
|
523
|
-
const params = this.getDeleteRowParams(edgeData, edge, context);
|
|
524
|
-
if (params.op === SQLStatementOperation.Delete) {
|
|
525
|
-
return deleteRowsSync(q, params.options, params.clause);
|
|
526
|
-
} else {
|
|
527
|
-
if (params.op !== SQLStatementOperation.Update) {
|
|
528
|
-
throw new Error(`invalid operation ${params.op}`);
|
|
529
|
-
}
|
|
530
|
-
editRowSync(q, {
|
|
531
|
-
tableName: params.options.tableName,
|
|
532
|
-
whereClause: params.clause,
|
|
533
|
-
fields: params.updateData!,
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
private getInsertRowParams(
|
|
539
|
-
edgeData: AssocEdgeData,
|
|
540
|
-
edge: AssocEdgeInput,
|
|
541
|
-
context?: Context,
|
|
542
|
-
): [CreateRowOptions, string] {
|
|
543
|
-
const fields: Data = {
|
|
544
|
-
id1: edge.id1,
|
|
545
|
-
id2: edge.id2,
|
|
546
|
-
id1_type: edge.id1Type,
|
|
547
|
-
id2_type: edge.id2Type,
|
|
548
|
-
edge_type: edge.edgeType,
|
|
549
|
-
data: edge.data || null,
|
|
550
|
-
};
|
|
551
|
-
if (edge.time) {
|
|
552
|
-
fields["time"] = edge.time.toISOString();
|
|
553
|
-
} else {
|
|
554
|
-
// todo make this a schema field like what we do in generated base files...
|
|
555
|
-
// maybe when actions exist?
|
|
556
|
-
fields["time"] = new Date().toISOString();
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
const onConflictFields = ["data"];
|
|
560
|
-
|
|
561
|
-
const extraEdgeFields = __getGlobalSchema()?.extraEdgeFields;
|
|
562
|
-
if (extraEdgeFields) {
|
|
563
|
-
for (const name in extraEdgeFields) {
|
|
564
|
-
const f = extraEdgeFields[name];
|
|
565
|
-
if (f.defaultValueOnCreate) {
|
|
566
|
-
const storageKey = getStorageKey(f, name);
|
|
567
|
-
fields[storageKey] = f.defaultValueOnCreate(this.builder, {});
|
|
568
|
-
// onconflict make sure we override the default values
|
|
569
|
-
// e.g. setting deleted_at = null for soft delete
|
|
570
|
-
onConflictFields.push(storageKey);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
let transformed: TransformedEdgeUpdateOperation | null = null;
|
|
576
|
-
const transformEdgeWrite = __getGlobalSchema()?.transformEdgeWrite;
|
|
577
|
-
if (transformEdgeWrite && !edge.disableTransformations) {
|
|
578
|
-
transformed = transformEdgeWrite({
|
|
579
|
-
op: SQLStatementOperation.Insert,
|
|
580
|
-
edge,
|
|
581
|
-
});
|
|
582
|
-
if (transformed) {
|
|
583
|
-
throw new Error(`transforming an insert edge not currently supported`);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
return [
|
|
588
|
-
{
|
|
589
|
-
tableName: edgeData.edgeTable,
|
|
590
|
-
fields: fields,
|
|
591
|
-
fieldsToLog: fields,
|
|
592
|
-
context,
|
|
593
|
-
},
|
|
594
|
-
`ON CONFLICT(id1, edge_type, id2) DO UPDATE SET ${onConflictFields
|
|
595
|
-
.map((f) => `${f} = EXCLUDED.${f}`)
|
|
596
|
-
.join(", ")}`,
|
|
597
|
-
];
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
private async performInsertWrite(
|
|
601
|
-
q: Queryer,
|
|
602
|
-
edgeData: AssocEdgeData,
|
|
603
|
-
edge: AssocEdgeInput,
|
|
604
|
-
context?: Context,
|
|
605
|
-
): Promise<void> {
|
|
606
|
-
const [options, suffix] = this.getInsertRowParams(edgeData, edge, context);
|
|
607
|
-
|
|
608
|
-
await createRow(q, options, suffix);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
private performInsertWriteSync(
|
|
612
|
-
q: SyncQueryer,
|
|
613
|
-
edgeData: AssocEdgeData,
|
|
614
|
-
edge: AssocEdgeInput,
|
|
615
|
-
context?: Context,
|
|
616
|
-
): void {
|
|
617
|
-
const [options, suffix] = this.getInsertRowParams(edgeData, edge, context);
|
|
618
|
-
|
|
619
|
-
createRowSync(q, options, suffix);
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
private resolveImpl(
|
|
623
|
-
executor: Executor,
|
|
624
|
-
placeholder: ID,
|
|
625
|
-
desc: string,
|
|
626
|
-
): [ID, string] {
|
|
627
|
-
let ent = executor.resolveValue(placeholder);
|
|
628
|
-
if (!ent) {
|
|
629
|
-
throw new Error(
|
|
630
|
-
`could not resolve placeholder value ${placeholder} for ${desc} for edge ${this.edgeInput.edgeType}`,
|
|
631
|
-
);
|
|
632
|
-
}
|
|
633
|
-
if (ent.id === undefined) {
|
|
634
|
-
throw new Error(`id of resolved ent is not defined`);
|
|
635
|
-
}
|
|
636
|
-
return [ent.id, ent.nodeType];
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
resolve(executor: Executor): void {
|
|
640
|
-
if (this.options.id1Placeholder) {
|
|
641
|
-
[this.edgeInput.id1, this.edgeInput.id1Type] = this.resolveImpl(
|
|
642
|
-
executor,
|
|
643
|
-
this.edgeInput.id1,
|
|
644
|
-
"id1",
|
|
645
|
-
);
|
|
646
|
-
}
|
|
647
|
-
if (this.options.id2Placeholder) {
|
|
648
|
-
[this.edgeInput.id2, this.edgeInput.id2Type] = this.resolveImpl(
|
|
649
|
-
executor,
|
|
650
|
-
this.edgeInput.id2,
|
|
651
|
-
"id2",
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
if (this.options.dataPlaceholder) {
|
|
655
|
-
if (!this.edgeInput.data) {
|
|
656
|
-
throw new Error(`data placeholder set but edgeInput data undefined`);
|
|
657
|
-
}
|
|
658
|
-
let [data, _] = this.resolveImpl(
|
|
659
|
-
executor,
|
|
660
|
-
this.edgeInput.data.toString(),
|
|
661
|
-
"data",
|
|
662
|
-
);
|
|
663
|
-
this.edgeInput.data = data.toString();
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
symmetricEdge(): EdgeOperation {
|
|
668
|
-
return new EdgeOperation(
|
|
669
|
-
this.builder,
|
|
670
|
-
{
|
|
671
|
-
id1: this.edgeInput.id2,
|
|
672
|
-
id1Type: this.edgeInput.id2Type,
|
|
673
|
-
id2: this.edgeInput.id1,
|
|
674
|
-
id2Type: this.edgeInput.id1Type,
|
|
675
|
-
edgeType: this.edgeInput.edgeType,
|
|
676
|
-
time: this.edgeInput.time,
|
|
677
|
-
data: this.edgeInput.data,
|
|
678
|
-
disableTransformations: this.edgeInput.disableTransformations,
|
|
679
|
-
},
|
|
680
|
-
{
|
|
681
|
-
operation: this.options.operation,
|
|
682
|
-
id1Placeholder: this.options.id2Placeholder,
|
|
683
|
-
id2Placeholder: this.options.id1Placeholder,
|
|
684
|
-
dataPlaceholder: this.options.dataPlaceholder,
|
|
685
|
-
},
|
|
686
|
-
);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
inverseEdge(edgeData: AssocEdgeData): EdgeOperation {
|
|
690
|
-
return new EdgeOperation(
|
|
691
|
-
this.builder,
|
|
692
|
-
{
|
|
693
|
-
id1: this.edgeInput.id2,
|
|
694
|
-
id1Type: this.edgeInput.id2Type,
|
|
695
|
-
id2: this.edgeInput.id1,
|
|
696
|
-
id2Type: this.edgeInput.id1Type,
|
|
697
|
-
edgeType: edgeData.inverseEdgeType!,
|
|
698
|
-
time: this.edgeInput.time,
|
|
699
|
-
data: this.edgeInput.data,
|
|
700
|
-
disableTransformations: this.edgeInput.disableTransformations,
|
|
701
|
-
},
|
|
702
|
-
{
|
|
703
|
-
operation: this.options.operation,
|
|
704
|
-
id1Placeholder: this.options.id2Placeholder,
|
|
705
|
-
id2Placeholder: this.options.id1Placeholder,
|
|
706
|
-
dataPlaceholder: this.options.dataPlaceholder,
|
|
707
|
-
},
|
|
708
|
-
);
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
private static resolveIDs<T extends Ent, T2 extends Ent>(
|
|
712
|
-
srcBuilder: Builder<T>, // id1
|
|
713
|
-
destID: Builder<T2> | ID, // id2 ( and then you flip it)
|
|
714
|
-
): [ID, string, boolean, ID, boolean] {
|
|
715
|
-
let destIDVal: ID;
|
|
716
|
-
let destPlaceholder = false;
|
|
717
|
-
if (this.isBuilder(destID)) {
|
|
718
|
-
destIDVal = destID.placeholderID;
|
|
719
|
-
destPlaceholder = true;
|
|
720
|
-
} else {
|
|
721
|
-
destIDVal = destID;
|
|
722
|
-
}
|
|
723
|
-
let srcIDVal: ID;
|
|
724
|
-
let srcType: string;
|
|
725
|
-
|
|
726
|
-
let srcPlaceholder = false;
|
|
727
|
-
if (srcBuilder.existingEnt) {
|
|
728
|
-
srcIDVal = srcBuilder.existingEnt.id;
|
|
729
|
-
srcType = srcBuilder.existingEnt.nodeType;
|
|
730
|
-
} else {
|
|
731
|
-
srcPlaceholder = true;
|
|
732
|
-
// get placeholder.
|
|
733
|
-
srcIDVal = srcBuilder.placeholderID;
|
|
734
|
-
// expected to be filled later
|
|
735
|
-
srcType = "";
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
return [srcIDVal, srcType, srcPlaceholder, destIDVal, destPlaceholder];
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
private static isBuilder(val: Builder<Ent> | any): val is Builder<Ent> {
|
|
742
|
-
return (val as Builder<Ent>).placeholderID !== undefined;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
private static resolveData(
|
|
746
|
-
data?: Builder<Ent> | string,
|
|
747
|
-
): [string | undefined, boolean] {
|
|
748
|
-
if (!data) {
|
|
749
|
-
return [undefined, false];
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
if (this.isBuilder(data)) {
|
|
753
|
-
return [data.placeholderID.toString(), true];
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
return [data, false];
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
static inboundEdge<T extends Ent, T2 extends Ent>(
|
|
760
|
-
builder: Builder<T>,
|
|
761
|
-
edgeType: string,
|
|
762
|
-
id1: Builder<T2> | ID,
|
|
763
|
-
nodeType: string,
|
|
764
|
-
options?: AssocEdgeInputOptions,
|
|
765
|
-
): EdgeOperation {
|
|
766
|
-
let [id2Val, id2Type, id2Placeholder, id1Val, id1Placeholder] =
|
|
767
|
-
EdgeOperation.resolveIDs(builder, id1);
|
|
768
|
-
let [data, dataPlaceholder] = EdgeOperation.resolveData(options?.data);
|
|
769
|
-
const edge: AssocEdgeInput = {
|
|
770
|
-
id1: id1Val,
|
|
771
|
-
edgeType: edgeType,
|
|
772
|
-
id2: id2Val,
|
|
773
|
-
id2Type: id2Type,
|
|
774
|
-
id1Type: nodeType,
|
|
775
|
-
...options,
|
|
776
|
-
};
|
|
777
|
-
if (data) {
|
|
778
|
-
edge.data = data;
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
return new EdgeOperation(builder, edge, {
|
|
782
|
-
operation: WriteOperation.Insert,
|
|
783
|
-
id2Placeholder,
|
|
784
|
-
id1Placeholder,
|
|
785
|
-
dataPlaceholder,
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
static outboundEdge<T extends Ent, T2 extends Ent>(
|
|
790
|
-
builder: Builder<T>,
|
|
791
|
-
edgeType: string,
|
|
792
|
-
id2: Builder<T2> | ID,
|
|
793
|
-
nodeType: string,
|
|
794
|
-
options?: AssocEdgeInputOptions,
|
|
795
|
-
): EdgeOperation {
|
|
796
|
-
let [id1Val, id1Type, id1Placeholder, id2Val, id2Placeholder] =
|
|
797
|
-
EdgeOperation.resolveIDs(builder, id2);
|
|
798
|
-
let [data, dataPlaceholder] = EdgeOperation.resolveData(options?.data);
|
|
799
|
-
|
|
800
|
-
const edge: AssocEdgeInput = {
|
|
801
|
-
id1: id1Val,
|
|
802
|
-
edgeType: edgeType,
|
|
803
|
-
id2: id2Val,
|
|
804
|
-
id2Type: nodeType,
|
|
805
|
-
id1Type: id1Type,
|
|
806
|
-
...options,
|
|
807
|
-
};
|
|
808
|
-
if (data) {
|
|
809
|
-
edge.data = data;
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
return new EdgeOperation(builder, edge, {
|
|
813
|
-
operation: WriteOperation.Insert,
|
|
814
|
-
id1Placeholder,
|
|
815
|
-
id2Placeholder,
|
|
816
|
-
dataPlaceholder,
|
|
817
|
-
});
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
static removeInboundEdge<T extends Ent>(
|
|
821
|
-
builder: Builder<T>,
|
|
822
|
-
edgeType: string,
|
|
823
|
-
id1: ID,
|
|
824
|
-
options?: AssocEdgeInputOptions,
|
|
825
|
-
): EdgeOperation {
|
|
826
|
-
if (!builder.existingEnt) {
|
|
827
|
-
throw new Error("cannot remove an edge from a non-existing ent");
|
|
828
|
-
}
|
|
829
|
-
const edge: AssocEdgeInput = {
|
|
830
|
-
id1: id1,
|
|
831
|
-
edgeType: edgeType,
|
|
832
|
-
id2: builder.existingEnt!.id,
|
|
833
|
-
id2Type: "", // these 2 shouldn't matter
|
|
834
|
-
id1Type: "",
|
|
835
|
-
disableTransformations: options?.disableTransformations,
|
|
836
|
-
};
|
|
837
|
-
return new EdgeOperation(builder, edge, {
|
|
838
|
-
operation: WriteOperation.Delete,
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
static removeOutboundEdge<T extends Ent>(
|
|
843
|
-
builder: Builder<T>,
|
|
844
|
-
edgeType: string,
|
|
845
|
-
id2: ID,
|
|
846
|
-
options?: AssocEdgeInputOptions,
|
|
847
|
-
): EdgeOperation {
|
|
848
|
-
if (!builder.existingEnt) {
|
|
849
|
-
throw new Error("cannot remove an edge from a non-existing ent");
|
|
850
|
-
}
|
|
851
|
-
const edge: AssocEdgeInput = {
|
|
852
|
-
id2: id2,
|
|
853
|
-
edgeType: edgeType,
|
|
854
|
-
id1: builder.existingEnt!.id,
|
|
855
|
-
id2Type: "", // these 2 shouldn't matter
|
|
856
|
-
id1Type: "",
|
|
857
|
-
disableTransformations: options?.disableTransformations,
|
|
858
|
-
};
|
|
859
|
-
return new EdgeOperation(builder, edge, {
|
|
860
|
-
operation: WriteOperation.Delete,
|
|
861
|
-
});
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
export class ConditionalOperation<T extends Ent = Ent>
|
|
866
|
-
implements DataOperation<T>
|
|
867
|
-
{
|
|
868
|
-
placeholderID?: ID | undefined;
|
|
869
|
-
protected shortCircuited = false;
|
|
870
|
-
public readonly builder: Builder<T>;
|
|
871
|
-
|
|
872
|
-
constructor(
|
|
873
|
-
protected op: DataOperation<T>,
|
|
874
|
-
private conditionalBuilder: Builder<any>,
|
|
875
|
-
) {
|
|
876
|
-
this.builder = op.builder;
|
|
877
|
-
this.placeholderID = op.placeholderID;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
shortCircuit(executor: Executor): boolean {
|
|
881
|
-
this.shortCircuited = executor.builderOpChanged(this.conditionalBuilder);
|
|
882
|
-
return this.shortCircuited;
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
async preFetch(
|
|
886
|
-
queryer: Queryer,
|
|
887
|
-
context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
|
|
888
|
-
): Promise<void> {
|
|
889
|
-
if (this.op.preFetch) {
|
|
890
|
-
return this.op.preFetch(queryer, context);
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
performWriteSync(
|
|
895
|
-
queryer: SyncQueryer,
|
|
896
|
-
context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
|
|
897
|
-
): void {
|
|
898
|
-
this.op.performWriteSync(queryer, context);
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
performWrite(
|
|
902
|
-
queryer: Queryer,
|
|
903
|
-
context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
|
|
904
|
-
): Promise<void> {
|
|
905
|
-
return this.op.performWrite(queryer, context);
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
returnedRow(): Data | null {
|
|
909
|
-
if (this.op.returnedRow) {
|
|
910
|
-
return this.op.returnedRow();
|
|
911
|
-
}
|
|
912
|
-
return null;
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
updatedOperation(): UpdatedOperation | null {
|
|
916
|
-
if (this.op.updatedOperation) {
|
|
917
|
-
return this.op.updatedOperation();
|
|
918
|
-
}
|
|
919
|
-
return null;
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
resolve(executor: Executor): void {
|
|
923
|
-
if (this.op.resolve) {
|
|
924
|
-
return this.op.resolve(executor);
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
async postFetch(
|
|
929
|
-
queryer: Queryer,
|
|
930
|
-
context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined,
|
|
931
|
-
): Promise<void> {
|
|
932
|
-
if (this.op.postFetch) {
|
|
933
|
-
return this.op.postFetch(queryer, context);
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
// separate because we need to implement createdEnt and we manually run those before edge/other operations in executors
|
|
939
|
-
export class ConditionalNodeOperation<
|
|
940
|
-
T extends Ent,
|
|
941
|
-
> extends ConditionalOperation<T> {
|
|
942
|
-
createdEnt(viewer: Viewer): T | null {
|
|
943
|
-
if (this.op.createdEnt) {
|
|
944
|
-
return this.op.createdEnt(viewer);
|
|
945
|
-
}
|
|
946
|
-
return null;
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
updatedOperation(): UpdatedOperation | null {
|
|
950
|
-
if (!this.op.updatedOperation) {
|
|
951
|
-
return null;
|
|
952
|
-
}
|
|
953
|
-
const ret = this.op.updatedOperation();
|
|
954
|
-
if (ret !== null) {
|
|
955
|
-
return ret;
|
|
956
|
-
}
|
|
957
|
-
if (!this.shortCircuited) {
|
|
958
|
-
return null;
|
|
959
|
-
}
|
|
960
|
-
// hack. if this short circuited, claim that this updated as an edit and it should invalidate other builders
|
|
961
|
-
// this API needs to change or EditNodeOperation needs to be used instead of this...
|
|
962
|
-
return {
|
|
963
|
-
operation: WriteOperation.Edit,
|
|
964
|
-
builder: this.builder,
|
|
965
|
-
};
|
|
966
|
-
}
|
|
967
|
-
}
|