@snowtop/ent 0.1.0-alpha160-test4 → 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 +48 -6
- 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,314 @@
|
|
|
1
|
+
import DataLoader from "dataloader";
|
|
2
|
+
import {
|
|
3
|
+
Context,
|
|
4
|
+
ID,
|
|
5
|
+
EdgeQueryableDataOptions,
|
|
6
|
+
Loader,
|
|
7
|
+
LoaderFactory,
|
|
8
|
+
Data,
|
|
9
|
+
PrimableLoader,
|
|
10
|
+
} from "../base";
|
|
11
|
+
import {
|
|
12
|
+
getDefaultLimit,
|
|
13
|
+
performRawQuery,
|
|
14
|
+
buildGroupQuery,
|
|
15
|
+
loadRows,
|
|
16
|
+
} from "../ent";
|
|
17
|
+
import * as clause from "../clause";
|
|
18
|
+
import { logEnabled } from "../logger";
|
|
19
|
+
import { CacheMap, getCustomLoader, getLoader } from "./loader";
|
|
20
|
+
import memoizee from "memoizee";
|
|
21
|
+
import { ObjectLoaderFactory } from "./object_loader";
|
|
22
|
+
import { OrderBy, getOrderByPhrase } from "../query_impl";
|
|
23
|
+
|
|
24
|
+
function getOrderByLocal(
|
|
25
|
+
options: QueryOptions,
|
|
26
|
+
queryOptions?: EdgeQueryableDataOptions,
|
|
27
|
+
): OrderBy {
|
|
28
|
+
return (
|
|
29
|
+
options.orderby ??
|
|
30
|
+
queryOptions?.orderby ?? [
|
|
31
|
+
{
|
|
32
|
+
column: "created_at",
|
|
33
|
+
direction: "DESC",
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function simpleCase<K extends any>(
|
|
40
|
+
options: QueryOptions,
|
|
41
|
+
id: K,
|
|
42
|
+
queryOptions?: EdgeQueryableDataOptions,
|
|
43
|
+
) {
|
|
44
|
+
let cls: clause.Clause;
|
|
45
|
+
if (options.groupCol) {
|
|
46
|
+
cls = clause.Eq(options.groupCol, id);
|
|
47
|
+
if (options.clause) {
|
|
48
|
+
cls = clause.And(cls, options.clause);
|
|
49
|
+
}
|
|
50
|
+
} else if (options.clause) {
|
|
51
|
+
cls = options.clause;
|
|
52
|
+
} else {
|
|
53
|
+
throw new Error(`need options.groupCol or options.clause`);
|
|
54
|
+
}
|
|
55
|
+
if (queryOptions?.clause) {
|
|
56
|
+
cls = clause.And(cls, queryOptions.clause);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return await loadRows({
|
|
60
|
+
...options,
|
|
61
|
+
clause: cls,
|
|
62
|
+
orderby: getOrderByLocal(options, queryOptions),
|
|
63
|
+
limit: queryOptions?.limit || getDefaultLimit(),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createLoader<K extends any>(
|
|
68
|
+
options: QueryOptions,
|
|
69
|
+
queryOptions?: EdgeQueryableDataOptions,
|
|
70
|
+
): DataLoader<K, Data[]> {
|
|
71
|
+
const loaderOptions: DataLoader.Options<K, Data[]> = {};
|
|
72
|
+
|
|
73
|
+
// if query logging is enabled, we should log what's happening with loader
|
|
74
|
+
if (logEnabled("query")) {
|
|
75
|
+
loaderOptions.cacheMap = new CacheMap(options);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return new DataLoader(async (keys: K[]) => {
|
|
79
|
+
if (!keys.length) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// keep query simple if we're only fetching for one id
|
|
84
|
+
// or can't group because no groupCol...
|
|
85
|
+
if (keys.length == 1 || !options.groupCol) {
|
|
86
|
+
const rows = await simpleCase(options, keys[0], queryOptions);
|
|
87
|
+
return [rows];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let m = new Map<K, number>();
|
|
91
|
+
let result: Data[][] = [];
|
|
92
|
+
for (let i = 0; i < keys.length; i++) {
|
|
93
|
+
result.push([]);
|
|
94
|
+
// store the index....
|
|
95
|
+
m.set(keys[i], i);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const col = options.groupCol;
|
|
99
|
+
let extraClause: clause.Clause | undefined;
|
|
100
|
+
if (options.clause && queryOptions?.clause) {
|
|
101
|
+
extraClause = clause.And(options.clause, queryOptions.clause);
|
|
102
|
+
} else if (options.clause) {
|
|
103
|
+
extraClause = options.clause;
|
|
104
|
+
} else if (queryOptions?.clause) {
|
|
105
|
+
extraClause = queryOptions.clause;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const [query, cls2] = buildGroupQuery({
|
|
109
|
+
tableName: options.tableName,
|
|
110
|
+
fields: options.fields,
|
|
111
|
+
values: keys,
|
|
112
|
+
orderby: getOrderByLocal(options, queryOptions),
|
|
113
|
+
limit: queryOptions?.limit || getDefaultLimit(),
|
|
114
|
+
groupColumn: col,
|
|
115
|
+
clause: extraClause,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const rows = await performRawQuery(query, cls2.values(), cls2.logValues());
|
|
119
|
+
for (const row of rows) {
|
|
120
|
+
const srcID = row[col];
|
|
121
|
+
const idx = m.get(srcID);
|
|
122
|
+
delete row.row_num;
|
|
123
|
+
if (idx === undefined) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`malformed query. got ${srcID} back but didn't query for it`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
result[idx].push(row);
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
}, loaderOptions);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
class QueryDirectLoader<K extends any> implements Loader<K, Data[]> {
|
|
135
|
+
private memoizedInitPrime: () => void;
|
|
136
|
+
private primedLoaders:
|
|
137
|
+
| Map<string, PrimableLoader<any, Data | null>>
|
|
138
|
+
| undefined;
|
|
139
|
+
constructor(
|
|
140
|
+
private options: QueryOptions,
|
|
141
|
+
private queryOptions?: EdgeQueryableDataOptions,
|
|
142
|
+
public context?: Context,
|
|
143
|
+
) {
|
|
144
|
+
this.memoizedInitPrime = memoizee(this.initPrime.bind(this));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private initPrime() {
|
|
148
|
+
if (!this.context || !this.options?.toPrime) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
let primedLoaders = new Map();
|
|
152
|
+
this.options.toPrime.forEach((prime) => {
|
|
153
|
+
const l2 = prime.createLoader(this.context);
|
|
154
|
+
if ((l2 as PrimableLoader<any, Data | null>).prime === undefined) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
primedLoaders.set(prime.options.key, l2);
|
|
158
|
+
});
|
|
159
|
+
this.primedLoaders = primedLoaders;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async load(id: K): Promise<Data[]> {
|
|
163
|
+
const rows = await simpleCase(this.options, id, this.queryOptions);
|
|
164
|
+
if (this.context) {
|
|
165
|
+
this.memoizedInitPrime();
|
|
166
|
+
if (this.primedLoaders) {
|
|
167
|
+
for (const row of rows) {
|
|
168
|
+
for (const [key, loader] of this.primedLoaders) {
|
|
169
|
+
const value = row[key];
|
|
170
|
+
if (value !== undefined) {
|
|
171
|
+
loader.prime(row);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return rows;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
clearAll() {}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// note, you should never call this directly
|
|
184
|
+
// there's scenarios where QueryDirectLoader is needed instead of this...
|
|
185
|
+
class QueryLoader<K extends any> implements Loader<K, Data[]> {
|
|
186
|
+
private loader: DataLoader<K, Data[]> | undefined;
|
|
187
|
+
private primedLoaders:
|
|
188
|
+
| Map<string, PrimableLoader<any, Data | null>>
|
|
189
|
+
| undefined;
|
|
190
|
+
private memoizedInitPrime: () => void;
|
|
191
|
+
constructor(
|
|
192
|
+
private options: QueryOptions,
|
|
193
|
+
public context?: Context,
|
|
194
|
+
private queryOptions?: EdgeQueryableDataOptions,
|
|
195
|
+
) {
|
|
196
|
+
if (context) {
|
|
197
|
+
this.loader = createLoader(options, queryOptions);
|
|
198
|
+
}
|
|
199
|
+
this.memoizedInitPrime = memoizee(this.initPrime.bind(this));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private initPrime() {
|
|
203
|
+
if (!this.context || !this.options?.toPrime) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
let primedLoaders = new Map();
|
|
207
|
+
this.options.toPrime.forEach((prime) => {
|
|
208
|
+
const l2 = prime.createLoader(this.context);
|
|
209
|
+
if ((l2 as PrimableLoader<any, Data | null>).prime === undefined) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
primedLoaders.set(prime.options.key, l2);
|
|
213
|
+
});
|
|
214
|
+
this.primedLoaders = primedLoaders;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async load(id: K): Promise<Data[]> {
|
|
218
|
+
if (this.loader) {
|
|
219
|
+
this.memoizedInitPrime();
|
|
220
|
+
const rows = await this.loader.load(id);
|
|
221
|
+
if (this.primedLoaders) {
|
|
222
|
+
for (const row of rows) {
|
|
223
|
+
for (const [key, loader] of this.primedLoaders) {
|
|
224
|
+
const value = row[key];
|
|
225
|
+
if (value !== undefined) {
|
|
226
|
+
loader.prime(row);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return rows;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return simpleCase(this.options, id, this.queryOptions);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
clearAll() {
|
|
238
|
+
this.loader && this.loader.clearAll();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
interface QueryOptions {
|
|
243
|
+
fields: string[];
|
|
244
|
+
tableName: string; // or function for assoc_edge. come back to it
|
|
245
|
+
// if provided, we'll group queries to the database via this key and this will be the unique id we're querying for
|
|
246
|
+
// using window functions or not
|
|
247
|
+
groupCol?: string;
|
|
248
|
+
// will be combined with groupCol to make a simple or complex query
|
|
249
|
+
// if no groupCol, this is required
|
|
250
|
+
// if no clause and groupCol, we'll just use groupCol to make the query
|
|
251
|
+
clause?: clause.Clause;
|
|
252
|
+
// order by
|
|
253
|
+
orderby?: OrderBy;
|
|
254
|
+
|
|
255
|
+
// if provided, will be used to prime data in this object...
|
|
256
|
+
toPrime?: ObjectLoaderFactory<Data>[];
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export class QueryLoaderFactory<K extends any>
|
|
260
|
+
implements LoaderFactory<K, Data[]>
|
|
261
|
+
{
|
|
262
|
+
name: string;
|
|
263
|
+
constructor(private options: QueryOptions) {
|
|
264
|
+
if (options.groupCol) {
|
|
265
|
+
this.name = `queryLoader:${options.tableName}:${options.groupCol}`;
|
|
266
|
+
} else if (options.clause) {
|
|
267
|
+
this.name = `queryLoader:${
|
|
268
|
+
options.tableName
|
|
269
|
+
}:${options.clause.instanceKey()}`;
|
|
270
|
+
} else {
|
|
271
|
+
throw new Error(
|
|
272
|
+
`must pass at least one of groupCol and clause to QueryLoaderFactory`,
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
createLoader(context?: Context) {
|
|
278
|
+
return getLoader(
|
|
279
|
+
this,
|
|
280
|
+
() => new QueryLoader(this.options, context),
|
|
281
|
+
context,
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
createConfigurableLoader(
|
|
286
|
+
options: EdgeQueryableDataOptions,
|
|
287
|
+
context?: Context,
|
|
288
|
+
) {
|
|
289
|
+
return QueryLoaderFactory.createConfigurableLoader(
|
|
290
|
+
this.name,
|
|
291
|
+
this.options,
|
|
292
|
+
options,
|
|
293
|
+
context,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
static createConfigurableLoader(
|
|
298
|
+
name: string,
|
|
299
|
+
queryOptions: QueryOptions,
|
|
300
|
+
options: EdgeQueryableDataOptions,
|
|
301
|
+
context?: Context,
|
|
302
|
+
) {
|
|
303
|
+
if (options.clause || !context) {
|
|
304
|
+
return new QueryDirectLoader(queryOptions, options, context);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const key = `${name}:limit:${options.limit}:orderby:${options.orderby}`;
|
|
308
|
+
return getCustomLoader(
|
|
309
|
+
key,
|
|
310
|
+
() => new QueryLoader(queryOptions, context, options),
|
|
311
|
+
context,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import DataLoader from "dataloader";
|
|
2
|
+
import {
|
|
3
|
+
LoadRowOptions,
|
|
4
|
+
ID,
|
|
5
|
+
Context,
|
|
6
|
+
Loader,
|
|
7
|
+
LoaderFactory,
|
|
8
|
+
SelectBaseDataOptions,
|
|
9
|
+
} from "../base";
|
|
10
|
+
import { loadRow, loadRows } from "../ent";
|
|
11
|
+
import * as clause from "../clause";
|
|
12
|
+
import { logEnabled } from "../logger";
|
|
13
|
+
import { CacheMap, getLoader } from "./loader";
|
|
14
|
+
|
|
15
|
+
interface QueryCountOptions {
|
|
16
|
+
tableName: string;
|
|
17
|
+
|
|
18
|
+
// must provide at least one or both of these
|
|
19
|
+
// if groupCol provided, we can do group by queries for multiple
|
|
20
|
+
// if not, can't group. similar philosophy to QueryLoader
|
|
21
|
+
groupCol?: string;
|
|
22
|
+
// if postgres and using an integer primary key, we need to pass this so that when we do an In query,
|
|
23
|
+
// we can cast accurately
|
|
24
|
+
// TODO https://github.com/lolopinto/ent/issues/1431
|
|
25
|
+
groupColType?: string;
|
|
26
|
+
clause?: clause.Clause;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function simpleCase<K extends any>(
|
|
30
|
+
options: QueryCountOptions,
|
|
31
|
+
key: K,
|
|
32
|
+
context?: Context,
|
|
33
|
+
) {
|
|
34
|
+
let cls: clause.Clause;
|
|
35
|
+
if (options.groupCol && options.clause) {
|
|
36
|
+
cls = clause.And(clause.Eq(options.groupCol, key), options.clause);
|
|
37
|
+
} else if (options.groupCol) {
|
|
38
|
+
cls = clause.Eq(options.groupCol, key);
|
|
39
|
+
} else if (options.clause) {
|
|
40
|
+
cls = options.clause;
|
|
41
|
+
} else {
|
|
42
|
+
throw new Error(`need options.groupCol or options.clause`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const row = await loadRow({
|
|
46
|
+
...options,
|
|
47
|
+
// sqlite needs as count otherwise it returns count(1)
|
|
48
|
+
fields: ["count(1) as count"],
|
|
49
|
+
clause: cls,
|
|
50
|
+
context,
|
|
51
|
+
});
|
|
52
|
+
return [parseInt(row?.count, 10) || 0];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function createCountDataLoader<K extends any>(
|
|
56
|
+
options: QueryCountOptions,
|
|
57
|
+
) {
|
|
58
|
+
const loaderOptions: DataLoader.Options<K, number> = {};
|
|
59
|
+
|
|
60
|
+
// if query logging is enabled, we should log what's happening with loader
|
|
61
|
+
if (logEnabled("query")) {
|
|
62
|
+
loaderOptions.cacheMap = new CacheMap(options);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return new DataLoader(async (keys: K[]) => {
|
|
66
|
+
if (!keys.length) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// keep query simple if we're only fetching for one id
|
|
71
|
+
if (keys.length == 1 || !options.groupCol) {
|
|
72
|
+
return simpleCase(options, keys[0]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let typ = options.groupColType || "uuid";
|
|
76
|
+
let cls: clause.Clause = clause.DBTypeIn(options.groupCol, keys, typ);
|
|
77
|
+
if (options.clause) {
|
|
78
|
+
cls = clause.And(cls, options.clause);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let m = new Map<K, number>();
|
|
82
|
+
let result: number[] = [];
|
|
83
|
+
for (let i = 0; i < keys.length; i++) {
|
|
84
|
+
result.push(0);
|
|
85
|
+
// store the index....
|
|
86
|
+
m.set(keys[i], i);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const rowOptions: LoadRowOptions = {
|
|
90
|
+
...options,
|
|
91
|
+
fields: ["count(1) as count", options.groupCol],
|
|
92
|
+
groupby: options.groupCol,
|
|
93
|
+
clause: cls,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const rows = await loadRows(rowOptions);
|
|
97
|
+
|
|
98
|
+
for (const row of rows) {
|
|
99
|
+
const id = row[options.groupCol];
|
|
100
|
+
const idx = m.get(id);
|
|
101
|
+
if (idx === undefined) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`malformed query. got ${id} back but didn't query for it`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
result[idx] = parseInt(row.count, 10);
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
}, loaderOptions);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// for now this only works for single column counts
|
|
113
|
+
// e.g. foreign key count
|
|
114
|
+
export class RawCountLoader<K extends any> implements Loader<K, number> {
|
|
115
|
+
private loader: DataLoader<K, number> | undefined;
|
|
116
|
+
// tableName, columns
|
|
117
|
+
constructor(private options: QueryCountOptions, public context?: Context) {
|
|
118
|
+
if (context && options.groupCol) {
|
|
119
|
+
this.loader = createCountDataLoader(options);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async load(id: K): Promise<number> {
|
|
124
|
+
if (this.loader) {
|
|
125
|
+
return await this.loader.load(id);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const rows = await simpleCase(this.options, id, this.context);
|
|
129
|
+
return rows[0];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
clearAll() {
|
|
133
|
+
this.loader && this.loader.clearAll();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export class RawCountLoaderFactory implements LoaderFactory<ID, number> {
|
|
138
|
+
name: string;
|
|
139
|
+
private options: QueryCountOptions;
|
|
140
|
+
constructor(options: SelectBaseDataOptions, col: string);
|
|
141
|
+
constructor(options: QueryCountOptions);
|
|
142
|
+
constructor(
|
|
143
|
+
options: SelectBaseDataOptions | QueryCountOptions,
|
|
144
|
+
col?: string,
|
|
145
|
+
) {
|
|
146
|
+
if (typeof col === "string") {
|
|
147
|
+
// old API
|
|
148
|
+
this.options = {
|
|
149
|
+
...options,
|
|
150
|
+
groupCol: col,
|
|
151
|
+
};
|
|
152
|
+
} else {
|
|
153
|
+
this.options = options;
|
|
154
|
+
}
|
|
155
|
+
if (this.options.groupCol) {
|
|
156
|
+
this.name = `${this.options.tableName}:${this.options.groupCol}`;
|
|
157
|
+
} else if (this.options.clause) {
|
|
158
|
+
this.name = `${
|
|
159
|
+
this.options.tableName
|
|
160
|
+
}:${this.options.clause.instanceKey()}`;
|
|
161
|
+
} else {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`must pass at least one of groupCol and clause to QueryLoaderFactory`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
createLoader(context?: Context) {
|
|
169
|
+
return getLoader(
|
|
170
|
+
this,
|
|
171
|
+
() => new RawCountLoader(this.options, context),
|
|
172
|
+
context,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// query are things that go in database
|
|
2
|
+
type logType = "query" | "warn" | "info" | "error" | "debug" | "cache";
|
|
3
|
+
var m: { [key in logType]: string } = {
|
|
4
|
+
query: "log",
|
|
5
|
+
warn: "warn",
|
|
6
|
+
info: "log",
|
|
7
|
+
error: "error",
|
|
8
|
+
debug: "debug",
|
|
9
|
+
cache: "log",
|
|
10
|
+
};
|
|
11
|
+
var logLevels = new Map<logType, boolean>();
|
|
12
|
+
|
|
13
|
+
export function setLogLevels(levels: logType | logType[]) {
|
|
14
|
+
if (!Array.isArray(levels)) {
|
|
15
|
+
levels = [levels];
|
|
16
|
+
}
|
|
17
|
+
levels.forEach((level) => logLevels.set(level, true));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function clearLogLevels() {
|
|
21
|
+
logLevels.clear();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function log(level: logType, msg: any) {
|
|
25
|
+
if (logLevels.has(level)) {
|
|
26
|
+
// mostly for sqlite error but fine for any type of error
|
|
27
|
+
if (level == "error" && msg instanceof Error && msg.message !== undefined) {
|
|
28
|
+
console.error(msg.message);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console[m[level]](msg);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function logIf(level: logType, logFn: () => any) {
|
|
36
|
+
if (logLevels.has(level)) {
|
|
37
|
+
console[m[level]](logFn());
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function logTrace() {
|
|
42
|
+
if (logLevels.has("debug")) {
|
|
43
|
+
console.trace();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function logEnabled(level: logType) {
|
|
48
|
+
return logLevels.has(level);
|
|
49
|
+
}
|