-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy patharango-document-datasource.js
130 lines (116 loc) · 3.36 KB
/
arango-document-datasource.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
const { DataSource } = require('apollo-datasource');
const DataLoader = require('dataloader');
const { aql } = require('arangojs');
/**
* An ArangoDb implementation of the Apollo DataSource.
*
* This DataSource is solely for resolving Arando Documents by their Id.
* Requests are batched and cached per request.
*
* @class ArangoDocumentDataSource
* @extends {DataSource}
*/
class ArangoDocumentDataSource extends DataSource {
/**
* Creates an instance of ArangoDocumentDataSource.
* @param {Database} db
* @memberof ArangoDocumentDataSource
*/
constructor(db) {
super();
this.db = db;
}
/**
* Initializes the DataSource. Called at the beginning of each request.
*
* @memberof ArangoDocumentDataSource
*/
initialize() {
this.dataloader = new DataLoader((keys) => this.loadKeys(keys));
this.existsDataloader = new DataLoader((keys) =>
this.checkForExistence(keys)
);
}
/**
* Gets a Document by its _id
*
* @param {string} id The _id to query for
* @returns {any} The corresponding Document
* @memberof ArangoDocumentDataSource
*/
async get(id) {
return this.dataloader.load(id);
}
/**
* Gets several Documents at once by their _id
* Note: if a key does not exist, null will be returned
*
* @param {string[]} ids The _ids to query for
* @returns {object|Error[]} The corresponding Documents. In the order their Ids were specified in the ids array.
* @memberof ArangoDocumentDataSource
*/
async getMany(ids) {
return this.dataloader.loadMany(ids);
}
/**
* Returns whether a given document exists
*
* @param {String} id The id of the document
* @returns {Boolean} Whether or not the document exists
* @memberof ArangoDocumentDataSource
*/
async exists(id) {
return this.existsDataloader.load(id);
}
/**
* Returns whether a given list of documents exist
*
* @param {String[]} ids A list of document ids to check
* @returns {Boolean[]} A corresponding list of booleans. The order matches the ids list.
* @memberof ArangoDocumentDataSource
*/
async manyExist(ids) {
return this.existsDataloader.loadMany(ids);
}
/**
* Queries the database for the given keys.
*
* @param {string[]} keys The keys to query for
* @private
* @returns {*[]} The corresponding Documents. In the order their Ids were specified in the ids array
* @memberof ArangoDocumentDataSource
*/
async loadKeys(keys) {
const cursor = await this.db.query(aql`RETURN DOCUMENT(${keys})`);
const [nodes] = await cursor.all();
return keys.map((key) => {
const node = nodes.find((node) => node._id === key);
if (node) {
node.id = node._id;
}
return node;
});
}
/**
* Checks whether the given keys exist
*
* @param {String[]} keys A list of keys to check for
* @returns {Boolean[]} The corresponding list of booleans. The order matches the keys list.
* @memberof ArangoDocumentDataSource
*/
async checkForExistence(keys) {
const cursor = await this.db.query(aql`
FOR key in ${keys}
RETURN (DOCUMENT(key))._id
`);
const nodes = await cursor.all();
const output = [];
for (const [index, id] of keys.entries()) {
output[index] = nodes[index] === id;
}
return output;
}
}
module.exports = {
ArangoDocumentDataSource: ArangoDocumentDataSource,
};