@snowtop/ent 0.1.0-alpha160-test5 → 0.1.0-alpha160-test6
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/dist/package.json +64 -0
- package/{scripts → dist/scripts}/custom_compiler.js +0 -0
- package/{scripts → dist/scripts}/custom_graphql.js +0 -0
- package/package.json +47 -5
- package/src/action/action.ts +330 -0
- package/src/action/executor.ts +453 -0
- package/src/action/experimental_action.ts +277 -0
- package/src/action/index.ts +31 -0
- package/src/action/operations.ts +967 -0
- package/src/action/orchestrator.ts +1527 -0
- package/src/action/privacy.ts +37 -0
- package/src/action/relative_value.ts +242 -0
- package/src/action/transaction.ts +38 -0
- package/src/auth/auth.ts +77 -0
- package/src/auth/index.ts +8 -0
- package/src/core/base.ts +367 -0
- package/src/core/clause.ts +1065 -0
- package/src/core/config.ts +219 -0
- package/src/core/const.ts +5 -0
- package/src/core/context.ts +135 -0
- package/src/core/convert.ts +106 -0
- package/src/core/date.ts +23 -0
- package/src/core/db.ts +498 -0
- package/src/core/ent.ts +1740 -0
- package/src/core/global_schema.ts +49 -0
- package/src/core/loaders/assoc_count_loader.ts +99 -0
- package/src/core/loaders/assoc_edge_loader.ts +250 -0
- package/src/core/loaders/index.ts +12 -0
- package/src/core/loaders/loader.ts +66 -0
- package/src/core/loaders/object_loader.ts +489 -0
- package/src/core/loaders/query_loader.ts +314 -0
- package/src/core/loaders/raw_count_loader.ts +175 -0
- package/src/core/logger.ts +49 -0
- package/src/core/privacy.ts +660 -0
- package/src/core/query/assoc_query.ts +240 -0
- package/src/core/query/custom_clause_query.ts +174 -0
- package/src/core/query/custom_query.ts +302 -0
- package/src/core/query/index.ts +9 -0
- package/src/core/query/query.ts +674 -0
- package/src/core/query_impl.ts +32 -0
- package/src/core/viewer.ts +52 -0
- package/src/ent.code-workspace +73 -0
- package/src/graphql/builtins/connection.ts +25 -0
- package/src/graphql/builtins/edge.ts +16 -0
- package/src/graphql/builtins/node.ts +12 -0
- package/src/graphql/graphql.ts +891 -0
- package/src/graphql/graphql_field_helpers.ts +221 -0
- package/src/graphql/index.ts +42 -0
- package/src/graphql/mutations/union.ts +39 -0
- package/src/graphql/node_resolver.ts +122 -0
- package/src/graphql/query/connection_type.ts +113 -0
- package/src/graphql/query/edge_connection.ts +171 -0
- package/src/graphql/query/page_info.ts +34 -0
- package/src/graphql/query/shared_edge_connection.ts +287 -0
- package/src/graphql/scalars/orderby_direction.ts +13 -0
- package/src/graphql/scalars/time.ts +38 -0
- package/src/imports/dataz/example1/_auth.ts +51 -0
- package/src/imports/dataz/example1/_viewer.ts +35 -0
- package/src/imports/index.ts +213 -0
- package/src/index.ts +145 -0
- package/src/parse_schema/parse.ts +585 -0
- package/src/schema/base_schema.ts +224 -0
- package/src/schema/field.ts +1087 -0
- package/src/schema/index.ts +53 -0
- package/src/schema/json_field.ts +94 -0
- package/src/schema/schema.ts +1028 -0
- package/src/schema/struct_field.ts +234 -0
- package/src/schema/union_field.ts +105 -0
- package/src/scripts/custom_compiler.ts +331 -0
- package/src/scripts/custom_graphql.ts +550 -0
- package/src/scripts/migrate_v0.1.ts +41 -0
- package/src/scripts/move_types.ts +131 -0
- package/src/scripts/read_schema.ts +67 -0
- package/src/setupPackage.js +42 -0
- package/src/testutils/action/complex_schemas.ts +517 -0
- package/src/testutils/builder.ts +422 -0
- package/src/testutils/context/test_context.ts +25 -0
- package/src/testutils/db/fixture.ts +32 -0
- package/src/testutils/db/temp_db.ts +941 -0
- package/src/testutils/db/value.ts +294 -0
- package/src/testutils/db_mock.ts +351 -0
- package/src/testutils/db_time_zone.ts +40 -0
- package/src/testutils/ent-graphql-tests/index.ts +653 -0
- package/src/testutils/fake_comms.ts +50 -0
- package/src/testutils/fake_data/const.ts +64 -0
- package/src/testutils/fake_data/events_query.ts +145 -0
- package/src/testutils/fake_data/fake_contact.ts +150 -0
- package/src/testutils/fake_data/fake_event.ts +150 -0
- package/src/testutils/fake_data/fake_tag.ts +139 -0
- package/src/testutils/fake_data/fake_user.ts +232 -0
- package/src/testutils/fake_data/index.ts +1 -0
- package/src/testutils/fake_data/internal.ts +8 -0
- package/src/testutils/fake_data/tag_query.ts +56 -0
- package/src/testutils/fake_data/test_helpers.ts +388 -0
- package/src/testutils/fake_data/user_query.ts +524 -0
- package/src/testutils/fake_log.ts +52 -0
- package/src/testutils/mock_date.ts +10 -0
- package/src/testutils/mock_log.ts +39 -0
- package/src/testutils/parse_sql.ts +685 -0
- package/src/testutils/test_edge_global_schema.ts +49 -0
- package/src/testutils/write.ts +70 -0
- package/src/tsc/ast.ts +351 -0
- package/src/tsc/compilerOptions.ts +85 -0
- package/src/tsc/move_generated.ts +191 -0
- package/src/tsc/transform.ts +226 -0
- package/src/tsc/transform_action.ts +224 -0
- package/src/tsc/transform_ent.ts +66 -0
- package/src/tsc/transform_schema.ts +546 -0
- package/tsconfig.json +20 -0
- package/core/query/shared_assoc_test.d.ts +0 -2
- package/core/query/shared_assoc_test.js +0 -804
- package/core/query/shared_test.d.ts +0 -21
- package/core/query/shared_test.js +0 -736
- package/graphql/query/shared_assoc_test.d.ts +0 -1
- package/graphql/query/shared_assoc_test.js +0 -203
- /package/{action → dist/action}/action.d.ts +0 -0
- /package/{action → dist/action}/action.js +0 -0
- /package/{action → dist/action}/executor.d.ts +0 -0
- /package/{action → dist/action}/executor.js +0 -0
- /package/{action → dist/action}/experimental_action.d.ts +0 -0
- /package/{action → dist/action}/experimental_action.js +0 -0
- /package/{action → dist/action}/index.d.ts +0 -0
- /package/{action → dist/action}/index.js +0 -0
- /package/{action → dist/action}/operations.d.ts +0 -0
- /package/{action → dist/action}/operations.js +0 -0
- /package/{action → dist/action}/orchestrator.d.ts +0 -0
- /package/{action → dist/action}/orchestrator.js +0 -0
- /package/{action → dist/action}/privacy.d.ts +0 -0
- /package/{action → dist/action}/privacy.js +0 -0
- /package/{action → dist/action}/relative_value.d.ts +0 -0
- /package/{action → dist/action}/relative_value.js +0 -0
- /package/{action → dist/action}/transaction.d.ts +0 -0
- /package/{action → dist/action}/transaction.js +0 -0
- /package/{auth → dist/auth}/auth.d.ts +0 -0
- /package/{auth → dist/auth}/auth.js +0 -0
- /package/{auth → dist/auth}/index.d.ts +0 -0
- /package/{auth → dist/auth}/index.js +0 -0
- /package/{core → dist/core}/base.d.ts +0 -0
- /package/{core → dist/core}/base.js +0 -0
- /package/{core → dist/core}/clause.d.ts +0 -0
- /package/{core → dist/core}/clause.js +0 -0
- /package/{core → dist/core}/config.d.ts +0 -0
- /package/{core → dist/core}/config.js +0 -0
- /package/{core → dist/core}/const.d.ts +0 -0
- /package/{core → dist/core}/const.js +0 -0
- /package/{core → dist/core}/context.d.ts +0 -0
- /package/{core → dist/core}/context.js +0 -0
- /package/{core → dist/core}/convert.d.ts +0 -0
- /package/{core → dist/core}/convert.js +0 -0
- /package/{core → dist/core}/date.d.ts +0 -0
- /package/{core → dist/core}/date.js +0 -0
- /package/{core → dist/core}/db.d.ts +0 -0
- /package/{core → dist/core}/db.js +0 -0
- /package/{core → dist/core}/ent.d.ts +0 -0
- /package/{core → dist/core}/ent.js +0 -0
- /package/{core → dist/core}/global_schema.d.ts +0 -0
- /package/{core → dist/core}/global_schema.js +0 -0
- /package/{core → dist/core}/loaders/assoc_count_loader.d.ts +0 -0
- /package/{core → dist/core}/loaders/assoc_count_loader.js +0 -0
- /package/{core → dist/core}/loaders/assoc_edge_loader.d.ts +0 -0
- /package/{core → dist/core}/loaders/assoc_edge_loader.js +0 -0
- /package/{core → dist/core}/loaders/index.d.ts +0 -0
- /package/{core → dist/core}/loaders/index.js +0 -0
- /package/{core → dist/core}/loaders/loader.d.ts +0 -0
- /package/{core → dist/core}/loaders/loader.js +0 -0
- /package/{core → dist/core}/loaders/object_loader.d.ts +0 -0
- /package/{core → dist/core}/loaders/object_loader.js +0 -0
- /package/{core → dist/core}/loaders/query_loader.d.ts +0 -0
- /package/{core → dist/core}/loaders/query_loader.js +0 -0
- /package/{core → dist/core}/loaders/raw_count_loader.d.ts +0 -0
- /package/{core → dist/core}/loaders/raw_count_loader.js +0 -0
- /package/{core → dist/core}/logger.d.ts +0 -0
- /package/{core → dist/core}/logger.js +0 -0
- /package/{core → dist/core}/privacy.d.ts +0 -0
- /package/{core → dist/core}/privacy.js +0 -0
- /package/{core → dist/core}/query/assoc_query.d.ts +0 -0
- /package/{core → dist/core}/query/assoc_query.js +0 -0
- /package/{core → dist/core}/query/custom_clause_query.d.ts +0 -0
- /package/{core → dist/core}/query/custom_clause_query.js +0 -0
- /package/{core → dist/core}/query/custom_query.d.ts +0 -0
- /package/{core → dist/core}/query/custom_query.js +0 -0
- /package/{core → dist/core}/query/index.d.ts +0 -0
- /package/{core → dist/core}/query/index.js +0 -0
- /package/{core → dist/core}/query/query.d.ts +0 -0
- /package/{core → dist/core}/query/query.js +0 -0
- /package/{core → dist/core}/query_impl.d.ts +0 -0
- /package/{core → dist/core}/query_impl.js +0 -0
- /package/{core → dist/core}/viewer.d.ts +0 -0
- /package/{core → dist/core}/viewer.js +0 -0
- /package/{graphql → dist/graphql}/builtins/connection.d.ts +0 -0
- /package/{graphql → dist/graphql}/builtins/connection.js +0 -0
- /package/{graphql → dist/graphql}/builtins/edge.d.ts +0 -0
- /package/{graphql → dist/graphql}/builtins/edge.js +0 -0
- /package/{graphql → dist/graphql}/builtins/node.d.ts +0 -0
- /package/{graphql → dist/graphql}/builtins/node.js +0 -0
- /package/{graphql → dist/graphql}/graphql.d.ts +0 -0
- /package/{graphql → dist/graphql}/graphql.js +0 -0
- /package/{graphql → dist/graphql}/graphql_field_helpers.d.ts +0 -0
- /package/{graphql → dist/graphql}/graphql_field_helpers.js +0 -0
- /package/{graphql → dist/graphql}/index.d.ts +0 -0
- /package/{graphql → dist/graphql}/index.js +0 -0
- /package/{graphql → dist/graphql}/mutations/union.d.ts +0 -0
- /package/{graphql → dist/graphql}/mutations/union.js +0 -0
- /package/{graphql → dist/graphql}/node_resolver.d.ts +0 -0
- /package/{graphql → dist/graphql}/node_resolver.js +0 -0
- /package/{graphql → dist/graphql}/query/connection_type.d.ts +0 -0
- /package/{graphql → dist/graphql}/query/connection_type.js +0 -0
- /package/{graphql → dist/graphql}/query/edge_connection.d.ts +0 -0
- /package/{graphql → dist/graphql}/query/edge_connection.js +0 -0
- /package/{graphql → dist/graphql}/query/page_info.d.ts +0 -0
- /package/{graphql → dist/graphql}/query/page_info.js +0 -0
- /package/{graphql → dist/graphql}/query/shared_edge_connection.d.ts +0 -0
- /package/{graphql → dist/graphql}/query/shared_edge_connection.js +0 -0
- /package/{graphql → dist/graphql}/scalars/orderby_direction.d.ts +0 -0
- /package/{graphql → dist/graphql}/scalars/orderby_direction.js +0 -0
- /package/{graphql → dist/graphql}/scalars/time.d.ts +0 -0
- /package/{graphql → dist/graphql}/scalars/time.js +0 -0
- /package/{imports → dist/imports}/dataz/example1/_auth.d.ts +0 -0
- /package/{imports → dist/imports}/dataz/example1/_auth.js +0 -0
- /package/{imports → dist/imports}/dataz/example1/_viewer.d.ts +0 -0
- /package/{imports → dist/imports}/dataz/example1/_viewer.js +0 -0
- /package/{imports → dist/imports}/index.d.ts +0 -0
- /package/{imports → dist/imports}/index.js +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{index.js → dist/index.js} +0 -0
- /package/{parse_schema → dist/parse_schema}/parse.d.ts +0 -0
- /package/{parse_schema → dist/parse_schema}/parse.js +0 -0
- /package/{schema → dist/schema}/base_schema.d.ts +0 -0
- /package/{schema → dist/schema}/base_schema.js +0 -0
- /package/{schema → dist/schema}/field.d.ts +0 -0
- /package/{schema → dist/schema}/field.js +0 -0
- /package/{schema → dist/schema}/index.d.ts +0 -0
- /package/{schema → dist/schema}/index.js +0 -0
- /package/{schema → dist/schema}/json_field.d.ts +0 -0
- /package/{schema → dist/schema}/json_field.js +0 -0
- /package/{schema → dist/schema}/schema.d.ts +0 -0
- /package/{schema → dist/schema}/schema.js +0 -0
- /package/{schema → dist/schema}/struct_field.d.ts +0 -0
- /package/{schema → dist/schema}/struct_field.js +0 -0
- /package/{schema → dist/schema}/union_field.d.ts +0 -0
- /package/{schema → dist/schema}/union_field.js +0 -0
- /package/{scripts → dist/scripts}/custom_compiler.d.ts +0 -0
- /package/{scripts → dist/scripts}/custom_graphql.d.ts +0 -0
- /package/{scripts → dist/scripts}/migrate_v0.1.d.ts +0 -0
- /package/{scripts → dist/scripts}/migrate_v0.1.js +0 -0
- /package/{scripts → dist/scripts}/move_types.d.ts +0 -0
- /package/{scripts → dist/scripts}/move_types.js +0 -0
- /package/{scripts → dist/scripts}/read_schema.d.ts +0 -0
- /package/{scripts → dist/scripts}/read_schema.js +0 -0
- /package/{testutils → dist/testutils}/action/complex_schemas.d.ts +0 -0
- /package/{testutils → dist/testutils}/action/complex_schemas.js +0 -0
- /package/{testutils → dist/testutils}/builder.d.ts +0 -0
- /package/{testutils → dist/testutils}/builder.js +0 -0
- /package/{testutils → dist/testutils}/context/test_context.d.ts +0 -0
- /package/{testutils → dist/testutils}/context/test_context.js +0 -0
- /package/{testutils → dist/testutils}/db/fixture.d.ts +0 -0
- /package/{testutils → dist/testutils}/db/fixture.js +0 -0
- /package/{testutils → dist/testutils}/db/temp_db.d.ts +0 -0
- /package/{testutils → dist/testutils}/db/temp_db.js +0 -0
- /package/{testutils → dist/testutils}/db/value.d.ts +0 -0
- /package/{testutils → dist/testutils}/db/value.js +0 -0
- /package/{testutils → dist/testutils}/db_mock.d.ts +0 -0
- /package/{testutils → dist/testutils}/db_mock.js +0 -0
- /package/{testutils → dist/testutils}/db_time_zone.d.ts +0 -0
- /package/{testutils → dist/testutils}/db_time_zone.js +0 -0
- /package/{testutils → dist/testutils}/ent-graphql-tests/index.d.ts +0 -0
- /package/{testutils → dist/testutils}/ent-graphql-tests/index.js +0 -0
- /package/{testutils → dist/testutils}/fake_comms.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_comms.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/const.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/const.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/events_query.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/events_query.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_contact.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_contact.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_event.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_event.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_tag.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_tag.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_user.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/fake_user.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/index.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/index.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/internal.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/internal.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/tag_query.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/tag_query.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/test_helpers.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/test_helpers.js +0 -0
- /package/{testutils → dist/testutils}/fake_data/user_query.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_data/user_query.js +0 -0
- /package/{testutils → dist/testutils}/fake_log.d.ts +0 -0
- /package/{testutils → dist/testutils}/fake_log.js +0 -0
- /package/{testutils → dist/testutils}/mock_date.d.ts +0 -0
- /package/{testutils → dist/testutils}/mock_date.js +0 -0
- /package/{testutils → dist/testutils}/mock_log.d.ts +0 -0
- /package/{testutils → dist/testutils}/mock_log.js +0 -0
- /package/{testutils → dist/testutils}/parse_sql.d.ts +0 -0
- /package/{testutils → dist/testutils}/parse_sql.js +0 -0
- /package/{testutils → dist/testutils}/test_edge_global_schema.d.ts +0 -0
- /package/{testutils → dist/testutils}/test_edge_global_schema.js +0 -0
- /package/{testutils → dist/testutils}/write.d.ts +0 -0
- /package/{testutils → dist/testutils}/write.js +0 -0
- /package/{tsc → dist/tsc}/ast.d.ts +0 -0
- /package/{tsc → dist/tsc}/ast.js +0 -0
- /package/{tsc → dist/tsc}/compilerOptions.d.ts +0 -0
- /package/{tsc → dist/tsc}/compilerOptions.js +0 -0
- /package/{tsc → dist/tsc}/move_generated.d.ts +0 -0
- /package/{tsc → dist/tsc}/move_generated.js +0 -0
- /package/{tsc → dist/tsc}/transform.d.ts +0 -0
- /package/{tsc → dist/tsc}/transform.js +0 -0
- /package/{tsc → dist/tsc}/transform_action.d.ts +0 -0
- /package/{tsc → dist/tsc}/transform_action.js +0 -0
- /package/{tsc → dist/tsc}/transform_ent.d.ts +0 -0
- /package/{tsc → dist/tsc}/transform_ent.js +0 -0
- /package/{tsc → dist/tsc}/transform_schema.d.ts +0 -0
- /package/{tsc → dist/tsc}/transform_schema.js +0 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ID,
|
|
3
|
+
Ent,
|
|
4
|
+
Viewer,
|
|
5
|
+
LoadEntOptions,
|
|
6
|
+
EdgeQueryableDataOptions,
|
|
7
|
+
} from "../base";
|
|
8
|
+
import { AssocEdge, loadEdgeData, loadEntsList } from "../ent";
|
|
9
|
+
import { AssocEdgeCountLoaderFactory } from "../loaders/assoc_count_loader";
|
|
10
|
+
import { AssocEdgeLoaderFactory } from "../loaders/assoc_edge_loader";
|
|
11
|
+
import { EdgeQuery, BaseEdgeQuery, IDInfo } from "./query";
|
|
12
|
+
|
|
13
|
+
// TODO no more plurals for privacy reasons?
|
|
14
|
+
export type EdgeQuerySource<
|
|
15
|
+
TSource extends Ent<TViewer>,
|
|
16
|
+
TDest extends Ent<TViewer> = Ent<any>,
|
|
17
|
+
TViewer extends Viewer = Viewer,
|
|
18
|
+
> = TSource | TSource[] | ID | ID[] | EdgeQuery<TDest, Ent, AssocEdge>;
|
|
19
|
+
|
|
20
|
+
type loaderOptionsFunc<TViewer extends Viewer> = (
|
|
21
|
+
type: string,
|
|
22
|
+
) => LoadEntOptions<Ent, TViewer>;
|
|
23
|
+
|
|
24
|
+
interface typeData {
|
|
25
|
+
ids: ID[];
|
|
26
|
+
options: LoadEntOptions<Ent>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// would be nice to someday have an API for assoc asc
|
|
30
|
+
export abstract class AssocEdgeQueryBase<
|
|
31
|
+
TSource extends Ent<TViewer>,
|
|
32
|
+
TDest extends Ent<TViewer>,
|
|
33
|
+
TEdge extends AssocEdge,
|
|
34
|
+
TViewer extends Viewer = Viewer,
|
|
35
|
+
>
|
|
36
|
+
extends BaseEdgeQuery<TSource, TDest, TEdge>
|
|
37
|
+
implements EdgeQuery<TSource, TDest, TEdge>
|
|
38
|
+
{
|
|
39
|
+
constructor(
|
|
40
|
+
public viewer: TViewer,
|
|
41
|
+
public src: EdgeQuerySource<TSource, TDest, TViewer>,
|
|
42
|
+
private countLoaderFactory: AssocEdgeCountLoaderFactory,
|
|
43
|
+
private dataLoaderFactory: AssocEdgeLoaderFactory<TEdge>,
|
|
44
|
+
// if function, it's a polymorphic edge and need to provide
|
|
45
|
+
// a function that goes from edgeType to LoadEntOptions
|
|
46
|
+
private options:
|
|
47
|
+
| LoadEntOptions<TDest, TViewer>
|
|
48
|
+
| loaderOptionsFunc<TViewer>,
|
|
49
|
+
) {
|
|
50
|
+
super(viewer, "time", "id2");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private isEdgeQuery(
|
|
54
|
+
obj: TSource | ID | EdgeQuery<TDest, Ent, AssocEdge>,
|
|
55
|
+
): obj is EdgeQuery<TDest, Ent, AssocEdge> {
|
|
56
|
+
if ((obj as EdgeQuery<TDest, Ent, AssocEdge>).queryIDs !== undefined) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
abstract sourceEnt(id: ID): Promise<Ent | null>;
|
|
63
|
+
|
|
64
|
+
async getTableName(): Promise<string> {
|
|
65
|
+
const edgeData = await loadEdgeData(this.countLoaderFactory.getEdgeType());
|
|
66
|
+
if (!edgeData) {
|
|
67
|
+
throw new Error(`couldn't load edgeData`);
|
|
68
|
+
}
|
|
69
|
+
return edgeData.edgeTable;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private async getSingleID() {
|
|
73
|
+
const infos = await this.genIDInfosToFetch();
|
|
74
|
+
if (infos.length !== 1) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
"cannot call queryRawCount when more than one id is requested",
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return infos[0];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// doesn't work with filters...
|
|
83
|
+
async queryRawCount(): Promise<number> {
|
|
84
|
+
const info = await this.getSingleID();
|
|
85
|
+
if (info.invalidated) {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return this.countLoaderFactory
|
|
90
|
+
.createConfigurableLoader(
|
|
91
|
+
this.getDefaultEdgeQueryOptions() ?? {},
|
|
92
|
+
this.viewer.context,
|
|
93
|
+
)
|
|
94
|
+
.load(info.id);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async queryAllRawCount(): Promise<Map<ID, number>> {
|
|
98
|
+
let results: Map<ID, number> = new Map();
|
|
99
|
+
const infos = await this.genIDInfosToFetch();
|
|
100
|
+
|
|
101
|
+
const loader = this.countLoaderFactory.createLoader(this.viewer.context);
|
|
102
|
+
await Promise.all(
|
|
103
|
+
infos.map(async (info) => {
|
|
104
|
+
if (info.invalidated) {
|
|
105
|
+
results.set(info.id, 0);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const count = await loader.load(info.id);
|
|
109
|
+
results.set(info.id, count);
|
|
110
|
+
}),
|
|
111
|
+
);
|
|
112
|
+
return results;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
protected async loadEntsFromEdges(
|
|
116
|
+
id: ID,
|
|
117
|
+
edges: AssocEdge[],
|
|
118
|
+
): Promise<TDest[]> {
|
|
119
|
+
if (typeof this.options === "function") {
|
|
120
|
+
const m = new Map<string, typeData>();
|
|
121
|
+
for (const edge of edges) {
|
|
122
|
+
const nodeType = edge.id2Type;
|
|
123
|
+
let data = m.get(nodeType);
|
|
124
|
+
if (data === undefined) {
|
|
125
|
+
const opts = this.options(nodeType);
|
|
126
|
+
if (opts === undefined) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`getLoaderOptions returned undefined for type ${nodeType}`,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
data = {
|
|
132
|
+
ids: [],
|
|
133
|
+
options: opts,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
data.ids.push(edge.id2);
|
|
137
|
+
m.set(nodeType, data);
|
|
138
|
+
}
|
|
139
|
+
let promises: Promise<Ent[]>[] = [];
|
|
140
|
+
for (const [_, value] of m) {
|
|
141
|
+
promises.push(loadEntsList(this.viewer, value.options, ...value.ids));
|
|
142
|
+
}
|
|
143
|
+
const entss = await Promise.all(promises);
|
|
144
|
+
const r: Ent[] = [];
|
|
145
|
+
for (const ents of entss) {
|
|
146
|
+
r.push(...ents);
|
|
147
|
+
}
|
|
148
|
+
return r as TDest[];
|
|
149
|
+
}
|
|
150
|
+
const ids = edges.map((edge) => edge.id2);
|
|
151
|
+
return loadEntsList(this.viewer, this.options, ...ids);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
dataToID(edge: AssocEdge): ID {
|
|
155
|
+
return edge.id2;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
protected async loadRawIDs(addID: (src: ID | TSource) => void) {
|
|
159
|
+
if (Array.isArray(this.src)) {
|
|
160
|
+
this.src.forEach((obj: TSource | ID) => addID(obj));
|
|
161
|
+
} else if (this.isEdgeQuery(this.src)) {
|
|
162
|
+
const idsMap = await this.src.queryAllIDs();
|
|
163
|
+
for (const [_, ids] of idsMap) {
|
|
164
|
+
ids.forEach((id) => addID(id));
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
addID(this.src);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
protected async loadRawData(
|
|
172
|
+
infos: IDInfo[],
|
|
173
|
+
options: EdgeQueryableDataOptions,
|
|
174
|
+
) {
|
|
175
|
+
const loader = this.dataLoaderFactory.createConfigurableLoader(
|
|
176
|
+
options,
|
|
177
|
+
this.viewer.context,
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
await Promise.all(
|
|
181
|
+
infos.map(async (info) => {
|
|
182
|
+
if (info.invalidated) {
|
|
183
|
+
this.edges.set(info.id, []);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// there'll be filters for special edges here...
|
|
187
|
+
// and then depending on that, we use this
|
|
188
|
+
// what happens if you do first(10).id2(XX)
|
|
189
|
+
// doesn't make sense
|
|
190
|
+
// so only makes sense if one of these...
|
|
191
|
+
|
|
192
|
+
// Id2 needs to be an option
|
|
193
|
+
const edges = await loader.load(info.id);
|
|
194
|
+
this.edges.set(info.id, edges);
|
|
195
|
+
}),
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async queryID2(id2: ID): Promise<TEdge | undefined> {
|
|
200
|
+
const info = await this.getSingleID();
|
|
201
|
+
if (info.invalidated) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const loader = this.dataLoaderFactory.createLoader(this.viewer.context);
|
|
206
|
+
return loader.loadEdgeForID2(info.id, id2);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async queryAllID2(id2: ID): Promise<Map<ID, TEdge>> {
|
|
210
|
+
const infos = await this.genIDInfosToFetch();
|
|
211
|
+
|
|
212
|
+
const loader = this.dataLoaderFactory.createLoader(this.viewer.context);
|
|
213
|
+
|
|
214
|
+
const m = new Map<ID, TEdge>();
|
|
215
|
+
await Promise.all(
|
|
216
|
+
infos.map(async (info) => {
|
|
217
|
+
if (info.invalidated) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const edge = await loader.loadEdgeForID2(info.id, id2);
|
|
221
|
+
if (edge) {
|
|
222
|
+
m.set(info.id, edge);
|
|
223
|
+
}
|
|
224
|
+
}),
|
|
225
|
+
);
|
|
226
|
+
return m;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface EdgeQueryCtr<
|
|
231
|
+
TSource extends Ent,
|
|
232
|
+
TDest extends Ent,
|
|
233
|
+
TEdge extends AssocEdge,
|
|
234
|
+
> {
|
|
235
|
+
new (viewer: Viewer, src: EdgeQuerySource<TSource>): EdgeQuery<
|
|
236
|
+
TSource,
|
|
237
|
+
TDest,
|
|
238
|
+
TEdge
|
|
239
|
+
>;
|
|
240
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Data,
|
|
3
|
+
EdgeQueryableDataOptions,
|
|
4
|
+
Ent,
|
|
5
|
+
ID,
|
|
6
|
+
LoadEntOptions,
|
|
7
|
+
Viewer,
|
|
8
|
+
} from "../base";
|
|
9
|
+
import { AndOptional, Clause } from "../clause";
|
|
10
|
+
import {
|
|
11
|
+
applyPrivacyPolicyForRows,
|
|
12
|
+
getDefaultLimit,
|
|
13
|
+
loadRow,
|
|
14
|
+
loadRows,
|
|
15
|
+
} from "../ent";
|
|
16
|
+
import { OrderBy } from "../query_impl";
|
|
17
|
+
|
|
18
|
+
import { BaseEdgeQuery, IDInfo } from "./query";
|
|
19
|
+
|
|
20
|
+
export interface CustomClauseQueryOptions<
|
|
21
|
+
TDest extends Ent<TViewer>,
|
|
22
|
+
TViewer extends Viewer = Viewer,
|
|
23
|
+
> {
|
|
24
|
+
loadEntOptions: LoadEntOptions<TDest, TViewer>;
|
|
25
|
+
clause: Clause;
|
|
26
|
+
// query-name used to create loaders...
|
|
27
|
+
// and then from there it does what it needs to do to do the right thing...
|
|
28
|
+
name: string;
|
|
29
|
+
// pass this if the primary sort (first column in orderby) column is unique and it'll be used for the cursor and used to
|
|
30
|
+
// generate the query
|
|
31
|
+
primarySortColIsUnique?: boolean;
|
|
32
|
+
orderby?: OrderBy;
|
|
33
|
+
|
|
34
|
+
// these next 3 are deprecated. use orderby
|
|
35
|
+
// defaults to id
|
|
36
|
+
// @deprecated use orderby
|
|
37
|
+
sortColumn?: string;
|
|
38
|
+
// @deprecated use orderby
|
|
39
|
+
orderByDirection?: "ASC" | "DESC";
|
|
40
|
+
// in Postgres, NULLS FIRST is the default for DESC order, and NULLS LAST otherwise.
|
|
41
|
+
// @deprecated user orderby`
|
|
42
|
+
nullsPlacement?: "first" | "last";
|
|
43
|
+
|
|
44
|
+
disableTransformations?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getClause<TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer>(
|
|
48
|
+
opts: CustomClauseQueryOptions<TDest, TViewer>,
|
|
49
|
+
) {
|
|
50
|
+
let cls = opts.clause;
|
|
51
|
+
if (opts.disableTransformations) {
|
|
52
|
+
return cls;
|
|
53
|
+
}
|
|
54
|
+
let optClause = opts.loadEntOptions.loaderFactory?.options?.clause;
|
|
55
|
+
if (typeof optClause === "function") {
|
|
56
|
+
optClause = optClause();
|
|
57
|
+
}
|
|
58
|
+
if (!optClause) {
|
|
59
|
+
return cls;
|
|
60
|
+
}
|
|
61
|
+
return AndOptional(cls, optClause);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class CustomClauseQuery<
|
|
65
|
+
TDest extends Ent<TViewer>,
|
|
66
|
+
TViewer extends Viewer = Viewer,
|
|
67
|
+
> extends BaseEdgeQuery<any, TDest, Data> {
|
|
68
|
+
private clause: Clause;
|
|
69
|
+
constructor(
|
|
70
|
+
public viewer: TViewer,
|
|
71
|
+
private options: CustomClauseQueryOptions<TDest, TViewer>,
|
|
72
|
+
) {
|
|
73
|
+
let orderby: OrderBy;
|
|
74
|
+
let primarySortCol: string;
|
|
75
|
+
|
|
76
|
+
if (
|
|
77
|
+
options.orderby &&
|
|
78
|
+
(options.sortColumn || options.orderByDirection || options.nullsPlacement)
|
|
79
|
+
) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`cannot pass orderby and sortColumn|orderByDirection|nullsPlacement`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (options.orderby) {
|
|
85
|
+
primarySortCol = options.orderby[0].column;
|
|
86
|
+
orderby = options.orderby;
|
|
87
|
+
} else {
|
|
88
|
+
primarySortCol = options.sortColumn || "id";
|
|
89
|
+
orderby = [
|
|
90
|
+
{
|
|
91
|
+
column: primarySortCol,
|
|
92
|
+
direction: options.orderByDirection ?? "DESC",
|
|
93
|
+
nullsPlacement: options.nullsPlacement,
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
let cursorCol = options.primarySortColIsUnique
|
|
98
|
+
? primarySortCol
|
|
99
|
+
: options.loadEntOptions.loaderFactory.options?.key || "id";
|
|
100
|
+
|
|
101
|
+
super(viewer, {
|
|
102
|
+
orderby,
|
|
103
|
+
cursorCol,
|
|
104
|
+
});
|
|
105
|
+
this.clause = getClause(options);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async sourceEnt(_id: ID) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
getTableName() {
|
|
113
|
+
return this.options.loadEntOptions.tableName;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async queryRawCount(): Promise<number> {
|
|
117
|
+
const row = await loadRow({
|
|
118
|
+
tableName: this.options.loadEntOptions.tableName,
|
|
119
|
+
// sqlite needs as count otherwise it returns count(1)
|
|
120
|
+
fields: ["count(1) as count"],
|
|
121
|
+
clause: this.clause,
|
|
122
|
+
context: this.viewer.context,
|
|
123
|
+
});
|
|
124
|
+
return parseInt(row?.count, 10) || 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async queryAllRawCount(): Promise<Map<ID, number>> {
|
|
128
|
+
throw new Error(`queryAllRawCount doesn't make sense in CustomClauseQuery`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// nothing to do here
|
|
132
|
+
protected async loadRawIDs(_addID: (src: ID) => void): Promise<void> {}
|
|
133
|
+
|
|
134
|
+
protected async loadRawData(
|
|
135
|
+
_infos: IDInfo[],
|
|
136
|
+
options: EdgeQueryableDataOptions,
|
|
137
|
+
) {
|
|
138
|
+
if (!options.orderby) {
|
|
139
|
+
options.orderby = [
|
|
140
|
+
{
|
|
141
|
+
column: this.getSortCol(),
|
|
142
|
+
direction: this.options.orderByDirection ?? "DESC",
|
|
143
|
+
nullsPlacement: this.options.nullsPlacement,
|
|
144
|
+
},
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
if (!options.limit) {
|
|
148
|
+
options.limit = getDefaultLimit();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const rows = await loadRows({
|
|
152
|
+
tableName: this.options.loadEntOptions.tableName,
|
|
153
|
+
fields: this.options.loadEntOptions.fields,
|
|
154
|
+
clause: AndOptional(this.clause, options.clause),
|
|
155
|
+
orderby: options.orderby,
|
|
156
|
+
limit: options?.limit || getDefaultLimit(),
|
|
157
|
+
context: this.viewer.context,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
this.edges.set(1, rows);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
dataToID(edge: Data): ID {
|
|
164
|
+
return edge.id;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
protected async loadEntsFromEdges(id: ID, rows: Data[]): Promise<TDest[]> {
|
|
168
|
+
return applyPrivacyPolicyForRows(
|
|
169
|
+
this.viewer,
|
|
170
|
+
rows,
|
|
171
|
+
this.options.loadEntOptions,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Data,
|
|
3
|
+
Ent,
|
|
4
|
+
ID,
|
|
5
|
+
EdgeQueryableDataOptions,
|
|
6
|
+
LoadEntOptions,
|
|
7
|
+
Viewer,
|
|
8
|
+
LoaderFactory,
|
|
9
|
+
ConfigurableLoaderFactory,
|
|
10
|
+
} from "../base";
|
|
11
|
+
import { AndOptional, Clause } from "../clause";
|
|
12
|
+
import { applyPrivacyPolicyForRows, getDefaultLimit } from "../ent";
|
|
13
|
+
import {
|
|
14
|
+
ObjectLoaderFactory,
|
|
15
|
+
QueryLoaderFactory,
|
|
16
|
+
RawCountLoader,
|
|
17
|
+
} from "../loaders";
|
|
18
|
+
import { OrderBy } from "../query_impl";
|
|
19
|
+
import { BaseEdgeQuery, IDInfo, EdgeQuery } from "./query";
|
|
20
|
+
|
|
21
|
+
// TODO kill this. only used in graphql tests
|
|
22
|
+
export interface CustomEdgeQueryOptionsDeprecated<
|
|
23
|
+
TSource extends Ent<TViewer>,
|
|
24
|
+
TDest extends Ent<TViewer>,
|
|
25
|
+
TViewer extends Viewer = Viewer,
|
|
26
|
+
> {
|
|
27
|
+
src: TSource | ID;
|
|
28
|
+
countLoaderFactory: LoaderFactory<ID, number>;
|
|
29
|
+
dataLoaderFactory: ConfigurableLoaderFactory<ID, Data[]>;
|
|
30
|
+
options: LoadEntOptions<TDest, TViewer>;
|
|
31
|
+
// defaults to id
|
|
32
|
+
sortColumn?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CustomEdgeQueryOptions<
|
|
36
|
+
TSource extends Ent<TViewer>,
|
|
37
|
+
TDest extends Ent<TViewer>,
|
|
38
|
+
TViewer extends Viewer = Viewer,
|
|
39
|
+
> {
|
|
40
|
+
src: TSource | ID;
|
|
41
|
+
loadEntOptions: LoadEntOptions<TDest, TViewer>;
|
|
42
|
+
// must provide at least one of these
|
|
43
|
+
groupCol?: string;
|
|
44
|
+
clause?: Clause;
|
|
45
|
+
// query-name used to create loaders...
|
|
46
|
+
// and then from there it does what it needs to do to do the right thing...
|
|
47
|
+
name: string;
|
|
48
|
+
// defaults to id
|
|
49
|
+
// @deprecated use orderby
|
|
50
|
+
sortColumn?: string;
|
|
51
|
+
orderby?: OrderBy;
|
|
52
|
+
// pass this if the primary sort (first column in orderby) column is unique and it'll be used for the cursor and used to
|
|
53
|
+
// generate the query
|
|
54
|
+
primarySortColIsUnique?: boolean;
|
|
55
|
+
|
|
56
|
+
disableTransformations?: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getClause<
|
|
60
|
+
TSource extends Ent<TViewer>,
|
|
61
|
+
TDest extends Ent<TViewer>,
|
|
62
|
+
TViewer extends Viewer = Viewer,
|
|
63
|
+
>(opts: CustomEdgeQueryOptions<TSource, TDest, TViewer>) {
|
|
64
|
+
let cls = opts.clause;
|
|
65
|
+
if (opts.disableTransformations) {
|
|
66
|
+
return cls;
|
|
67
|
+
}
|
|
68
|
+
let optClause = opts.loadEntOptions.loaderFactory?.options?.clause;
|
|
69
|
+
if (typeof optClause === "function") {
|
|
70
|
+
optClause = optClause();
|
|
71
|
+
}
|
|
72
|
+
if (!optClause) {
|
|
73
|
+
return cls;
|
|
74
|
+
}
|
|
75
|
+
return AndOptional(cls, optClause);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function getRawCountLoader<
|
|
79
|
+
TSource extends Ent<TViewer>,
|
|
80
|
+
TDest extends Ent<TViewer>,
|
|
81
|
+
TViewer extends Viewer = Viewer,
|
|
82
|
+
>(viewer: TViewer, opts: CustomEdgeQueryOptions<TSource, TDest, TViewer>) {
|
|
83
|
+
if (!viewer.context?.cache) {
|
|
84
|
+
return new RawCountLoader({
|
|
85
|
+
tableName: opts.loadEntOptions.tableName,
|
|
86
|
+
groupCol: opts.groupCol,
|
|
87
|
+
clause: getClause(opts),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const name = `custom_query_count_loader:${opts.name}`;
|
|
91
|
+
return viewer.context.cache.getLoader(
|
|
92
|
+
name,
|
|
93
|
+
() =>
|
|
94
|
+
new RawCountLoader({
|
|
95
|
+
tableName: opts.loadEntOptions.tableName,
|
|
96
|
+
groupCol: opts.groupCol,
|
|
97
|
+
clause: getClause(opts),
|
|
98
|
+
}),
|
|
99
|
+
) as RawCountLoader<ID>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getQueryLoader<
|
|
103
|
+
TSource extends Ent<TViewer>,
|
|
104
|
+
TDest extends Ent<TViewer>,
|
|
105
|
+
TViewer extends Viewer = Viewer,
|
|
106
|
+
>(
|
|
107
|
+
viewer: TViewer,
|
|
108
|
+
opts: CustomEdgeQueryOptions<TSource, TDest, TViewer>,
|
|
109
|
+
options: EdgeQueryableDataOptions,
|
|
110
|
+
) {
|
|
111
|
+
const loader = opts.loadEntOptions.loaderFactory as ObjectLoaderFactory<Data>;
|
|
112
|
+
const name = `custom_query_loader:${opts.name}`;
|
|
113
|
+
|
|
114
|
+
return QueryLoaderFactory.createConfigurableLoader(
|
|
115
|
+
name,
|
|
116
|
+
{
|
|
117
|
+
tableName: opts.loadEntOptions.tableName,
|
|
118
|
+
fields: opts.loadEntOptions.fields,
|
|
119
|
+
groupCol: opts.groupCol,
|
|
120
|
+
clause: getClause(opts),
|
|
121
|
+
toPrime: [loader],
|
|
122
|
+
},
|
|
123
|
+
options,
|
|
124
|
+
viewer.context,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function isDeprecatedOptions<
|
|
129
|
+
TSource extends Ent<TViewer>,
|
|
130
|
+
TDest extends Ent<TViewer>,
|
|
131
|
+
TViewer extends Viewer = Viewer,
|
|
132
|
+
>(
|
|
133
|
+
options:
|
|
134
|
+
| CustomEdgeQueryOptionsDeprecated<TSource, TDest, TViewer>
|
|
135
|
+
| CustomEdgeQueryOptions<TSource, TDest, TViewer>,
|
|
136
|
+
): options is CustomEdgeQueryOptionsDeprecated<TSource, TDest, TViewer> {
|
|
137
|
+
return (
|
|
138
|
+
(options as CustomEdgeQueryOptionsDeprecated<TSource, TDest, TViewer>)
|
|
139
|
+
.countLoaderFactory !== undefined
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export abstract class CustomEdgeQueryBase<
|
|
144
|
+
TSource extends Ent<TViewer>,
|
|
145
|
+
TDest extends Ent<TViewer>,
|
|
146
|
+
TViewer extends Viewer = Viewer,
|
|
147
|
+
>
|
|
148
|
+
extends BaseEdgeQuery<TSource, TDest, Data>
|
|
149
|
+
implements EdgeQuery<TSource, TDest, Data>
|
|
150
|
+
{
|
|
151
|
+
private id: ID;
|
|
152
|
+
private opts: LoadEntOptions<TDest>;
|
|
153
|
+
constructor(
|
|
154
|
+
public viewer: TViewer,
|
|
155
|
+
private options:
|
|
156
|
+
| CustomEdgeQueryOptionsDeprecated<TSource, TDest, TViewer>
|
|
157
|
+
| CustomEdgeQueryOptions<TSource, TDest, TViewer>,
|
|
158
|
+
) {
|
|
159
|
+
let opts: LoadEntOptions<TDest>;
|
|
160
|
+
let defaultSort = "id";
|
|
161
|
+
|
|
162
|
+
let uniqueColIsSort = false;
|
|
163
|
+
|
|
164
|
+
let orderby: OrderBy | undefined;
|
|
165
|
+
let sortCol: string | undefined;
|
|
166
|
+
|
|
167
|
+
if (isDeprecatedOptions(options)) {
|
|
168
|
+
opts = options.options;
|
|
169
|
+
} else {
|
|
170
|
+
opts = options.loadEntOptions;
|
|
171
|
+
if (options.primarySortColIsUnique) {
|
|
172
|
+
uniqueColIsSort = true;
|
|
173
|
+
}
|
|
174
|
+
if (options.orderby) {
|
|
175
|
+
orderby = options.orderby;
|
|
176
|
+
sortCol = options.orderby[0].column;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
let uniqueCol = opts.loaderFactory.options?.key || "id";
|
|
180
|
+
|
|
181
|
+
if (!orderby) {
|
|
182
|
+
options.sortColumn = options.sortColumn || defaultSort;
|
|
183
|
+
sortCol = options.sortColumn;
|
|
184
|
+
|
|
185
|
+
orderby = [
|
|
186
|
+
{
|
|
187
|
+
column: options.sortColumn,
|
|
188
|
+
direction: "DESC",
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (uniqueColIsSort) {
|
|
194
|
+
uniqueCol = sortCol || defaultSort;
|
|
195
|
+
}
|
|
196
|
+
super(viewer, {
|
|
197
|
+
cursorCol: uniqueCol,
|
|
198
|
+
orderby,
|
|
199
|
+
});
|
|
200
|
+
if (typeof options.src === "object") {
|
|
201
|
+
this.id = options.src.id;
|
|
202
|
+
} else {
|
|
203
|
+
this.id = options.src;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
this.opts = opts;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
getTableName() {
|
|
210
|
+
return this.opts.tableName;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
abstract sourceEnt(id: ID): Promise<Ent | null>;
|
|
214
|
+
|
|
215
|
+
private async idVisible() {
|
|
216
|
+
const ids = await this.genIDInfosToFetch();
|
|
217
|
+
if (ids.length !== 1) {
|
|
218
|
+
throw new Error("invalid number of IDInfo");
|
|
219
|
+
}
|
|
220
|
+
return !ids[0].invalidated;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private getCountLoader() {
|
|
224
|
+
if (isDeprecatedOptions(this.options)) {
|
|
225
|
+
return this.options.countLoaderFactory.createLoader(this.viewer.context);
|
|
226
|
+
}
|
|
227
|
+
return getRawCountLoader(this.viewer, this.options);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private getQueryLoader(options: EdgeQueryableDataOptions) {
|
|
231
|
+
if (isDeprecatedOptions(this.options)) {
|
|
232
|
+
return this.options.dataLoaderFactory.createConfigurableLoader(
|
|
233
|
+
options,
|
|
234
|
+
this.viewer.context,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
return getQueryLoader(this.viewer, this.options, options);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async queryRawCount(): Promise<number> {
|
|
241
|
+
const idVisible = await this.idVisible();
|
|
242
|
+
if (!idVisible) {
|
|
243
|
+
return 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return this.getCountLoader().load(this.id);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async queryAllRawCount(): Promise<Map<ID, number>> {
|
|
250
|
+
let count = 0;
|
|
251
|
+
const idVisible = await this.idVisible();
|
|
252
|
+
if (idVisible) {
|
|
253
|
+
count = await this.queryRawCount();
|
|
254
|
+
}
|
|
255
|
+
return new Map<ID, number>([[this.id, count]]);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
protected async loadRawIDs(
|
|
259
|
+
addID: (src: ID | TSource) => void,
|
|
260
|
+
): Promise<void> {
|
|
261
|
+
addID(this.options.src);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
protected async loadRawData(
|
|
265
|
+
infos: IDInfo[],
|
|
266
|
+
options: EdgeQueryableDataOptions,
|
|
267
|
+
) {
|
|
268
|
+
if (infos.length !== 1) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
`expected 1 info passed to loadRawData. ${infos.length} passed`,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
if (!options.orderby) {
|
|
274
|
+
options.orderby = [
|
|
275
|
+
{
|
|
276
|
+
column: this.getSortCol(),
|
|
277
|
+
direction: "DESC",
|
|
278
|
+
},
|
|
279
|
+
];
|
|
280
|
+
}
|
|
281
|
+
if (!options.limit) {
|
|
282
|
+
options.limit = getDefaultLimit();
|
|
283
|
+
}
|
|
284
|
+
const loader = this.getQueryLoader(options);
|
|
285
|
+
const info = infos[0];
|
|
286
|
+
if (info.invalidated) {
|
|
287
|
+
this.edges.set(this.id, []);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const rows = await loader.load(this.id);
|
|
291
|
+
|
|
292
|
+
this.edges.set(this.id, rows);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
dataToID(edge: Data): ID {
|
|
296
|
+
return edge.id;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
protected async loadEntsFromEdges(id: ID, rows: Data[]): Promise<TDest[]> {
|
|
300
|
+
return applyPrivacyPolicyForRows(this.viewer, rows, this.opts);
|
|
301
|
+
}
|
|
302
|
+
}
|