Skip to content

Commit 7113523

Browse files
committed
queries running
1 parent 2ae09a3 commit 7113523

6 files changed

Lines changed: 64 additions & 23 deletions

File tree

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{
22
"name": "apollo-datasource-cosmosdb",
3-
"version": "1.0.0",
3+
"version": "0.0.1",
44
"description": "An Apollo data source for Azure CosmosDB",
5-
"main": "index.js",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
67
"repository": "https://github.com/andrejpk/apollo-datasource-cosmosdb",
78
"author": "Andrej Kyselica",
89
"license": "MIT",
@@ -39,4 +40,4 @@
3940
"files": [
4041
"/dist"
4142
]
42-
}
43+
}

src/cache.ts

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Container, Operation } from "@azure/cosmos";
22
import { KeyValueCache } from "apollo-server-caching";
33
import DataLoader from "dataloader";
44
import { EJSON } from "bson";
5+
import { CosmosDataSourceOptions } from "./datasource";
56

67
// https://github.com/graphql/dataloader#batch-function
78
const orderDocs = <V>(ids: readonly string[]) => (
@@ -33,33 +34,53 @@ const orderDocs = <V>(ids: readonly string[]) => (
3334
export interface createCatchingMethodArgs {
3435
container: Container;
3536
cache: KeyValueCache;
37+
options: CosmosDataSourceOptions;
3638
}
3739

3840
export interface FindArgs {
3941
ttl?: number;
4042
}
4143

4244
export interface CachedMethods<DType> {
43-
findOneById: (id: string, args: FindArgs) => Promise<DType | undefined>;
45+
findOneById: (id: string, args?: FindArgs) => Promise<DType | undefined>;
4446
findManyByIds: (
4547
ids: string[],
46-
args: FindArgs
48+
args?: FindArgs
4749
) => Promise<(DType | undefined)[]>;
4850
deleteFromCacheById: (id: string) => Promise<void>;
4951
}
5052

5153
export const createCachingMethods = <DType>({
5254
container,
5355
cache,
56+
options,
5457
}: createCatchingMethodArgs): CachedMethods<DType> => {
5558
const loader = new DataLoader<string, DType>(async (ids) => {
56-
const operations = ids.map<Operation>((id) => ({
57-
operationType: "Read",
58-
id,
59-
}));
60-
const response = await container.items.bulk(operations);
61-
const responseDocs = response.map((r) =>
62-
r.resourceBody ? ((r.resourceBody as unknown) as DType) : undefined
59+
options?.logger?.debug(
60+
`CosmosDataSource/DataLoader: loading for IDs: ${ids}`
61+
);
62+
// const operations = ids.map<Operation>((id) => ({
63+
// operationType: "Read",
64+
// id,
65+
// }));
66+
// const response = await container.items.bulk(operations);
67+
const querySpec = {
68+
query: `select * from c where c.id in (${ids
69+
.map((id) => `'${id}'`)
70+
.join(",")})`,
71+
// query: "select * from c where c.id in (@ids)",
72+
// parameters: [{ name: "@ids", value: ids }],
73+
};
74+
const response = await container.items.query(querySpec).fetchAll();
75+
76+
options?.logger?.debug(
77+
`CosmosDataSource/DataLoader: response count: ${response.resources.length}`
78+
);
79+
options?.logger?.debug(
80+
`data: ${JSON.stringify(response.resources[0], null, " ")}`
81+
);
82+
const responseDocs = response.resources.map((r) =>
83+
r ? ((r as unknown) as DType) : undefined
6384
);
6485
return orderDocs<DType>(ids)(responseDocs);
6586
});
@@ -68,6 +89,7 @@ export const createCachingMethods = <DType>({
6889

6990
const methods: CachedMethods<DType> = {
7091
findOneById: async (id, { ttl } = {}) => {
92+
options?.logger?.debug(`CosmosDataSource: Running query for ID ${id}`);
7193
const key = cachePrefix + id;
7294

7395
const cacheDoc = await cache.get(key);
@@ -84,8 +106,10 @@ export const createCachingMethods = <DType>({
84106
return doc;
85107
},
86108

87-
findManyByIds: (ids, args = {}) =>
88-
Promise.all(ids.map((id) => methods.findOneById(id, args))),
109+
findManyByIds: (ids, args = {}) => {
110+
options?.logger?.debug(`CosmosDataSource: Running query for IDs ${ids}`);
111+
return Promise.all(ids.map((id) => methods.findOneById(id, args)));
112+
},
89113

90114
deleteFromCacheById: async (id) => {
91115
loader.clear(id);

src/datasource.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@ import { DataSource } from "apollo-datasource";
22
import { ApolloError } from "apollo-server-errors";
33
import { InMemoryLRUCache, KeyValueCache } from "apollo-server-caching";
44
import { Container } from "@azure/cosmos";
5+
import { Logger } from "./helpers";
56

67
import { isCosmosDbContainer } from "./helpers";
78
import { createCachingMethods, CachedMethods } from "./cache";
89

9-
export const placeholderHandler = () => {
10+
export interface CosmosDataSourceOptions {
11+
logger?: Logger;
12+
}
13+
14+
const placeholderHandler = () => {
1015
throw new Error("DataSource not initialized");
1116
};
1217

@@ -15,21 +20,25 @@ export class CosmosDataSource<TData, TContext = any>
1520
implements CachedMethods<TData> {
1621
container: Container;
1722
context?: TContext;
23+
private options: CosmosDataSourceOptions;
1824
// these get set by the initializer but they must be defined or nullable after the constructor
1925
// runs, so we guard against using them before init
20-
findOneById = placeholderHandler;
21-
findManyByIds = placeholderHandler;
22-
deleteFromCacheById = placeholderHandler;
26+
findOneById: CachedMethods<TData>["findOneById"] = placeholderHandler;
27+
findManyByIds: CachedMethods<TData>["findManyByIds"] = placeholderHandler;
28+
deleteFromCacheById: CachedMethods<TData>["deleteFromCacheById"] = placeholderHandler;
2329

24-
constructor(container: Container) {
30+
constructor(container: Container, options: CosmosDataSourceOptions = {}) {
2531
super();
32+
console.log(`options: ${options.logger}`);
33+
options?.logger?.info(`CosmosDataSource started`);
2634

2735
if (!isCosmosDbContainer(container)) {
2836
throw new ApolloError(
2937
"CosmosDataSource must be created with a CosmosDb container (from @azure/cosmos)"
3038
);
3139
}
3240

41+
this.options = options;
3342
this.container = container;
3443
}
3544

@@ -42,6 +51,7 @@ export class CosmosDataSource<TData, TContext = any>
4251
const methods = createCachingMethods<TData>({
4352
container: this.container,
4453
cache: cache || new InMemoryLRUCache(),
54+
options: this.options,
4555
});
4656

4757
Object.assign(this, methods);

src/helpers.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,11 @@ export const isCosmosDbContainer = (
1111
maybeContainer.getPartitionKeyDefinition
1212
);
1313
};
14+
15+
export type Logger = {
16+
// Ordered from least-severe to most-severe.
17+
debug(message?: any): void;
18+
info(message?: any): void;
19+
warn(message?: any): void;
20+
error(message?: any): void;
21+
}

src/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
import { CosmosDataSource } from "./datasource";
2-
3-
export default { CosmosDataSource };
1+
export { CosmosDataSource } from "./datasource";

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// "allowJs": true, /* Allow javascript files to be compiled. */
88
// "checkJs": true, /* Report errors in .js files. */
99
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
10-
// "declaration": true, /* Generates corresponding '.d.ts' file. */
10+
"declaration": true /* Generates corresponding '.d.ts' file. */,
1111
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
1212
"sourceMap": true /* Generates corresponding '.map' file. */,
1313
// "outFile": "./", /* Concatenate and emit output to single file. */

0 commit comments

Comments
 (0)