datastore-api 2.0.1 → 2.1.0

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.
@@ -1,368 +0,0 @@
1
- /*
2
- * dstore-api.test.ts
3
- *
4
- * Created by Dr. Maximilian Dornseif 2021-12-10 in huwawi3backend 11.10.0
5
- * Copyright (c) 2021 Dr. Maximilian Dornseif
6
- */
7
- import { Datastore } from '@google-cloud/datastore';
8
- import test from 'ava';
9
- import Emulator from 'google-datastore-emulator';
10
- import { Dstore } from './dstore-api';
11
- process.env.GCLOUD_PROJECT = 'project-id'; // Set the datastore project Id globally
12
- let emulator;
13
- test.before(async (_t) => {
14
- emulator = new Emulator({ debug: false });
15
- await emulator.start();
16
- });
17
- test.after('cleanup', async (_t) => {
18
- await emulator.stop();
19
- });
20
- function getDstore(projectId) {
21
- return new Dstore(new Datastore({ projectId }));
22
- }
23
- test('keySerialize', async (t) => {
24
- const kvStore = getDstore('test');
25
- t.deepEqual(kvStore.key(['testYodel', 123]).path, ['testYodel', 123]);
26
- t.deepEqual(JSON.parse(JSON.stringify(kvStore.key(['testYodel', 123]))), {
27
- id: 123,
28
- kind: 'testYodel',
29
- path: ['testYodel', 123],
30
- });
31
- const ser = kvStore.keySerialize(kvStore.key(['testYodel', 123]));
32
- t.deepEqual(ser, 'agByDwsSCXRlc3RZb2RlbBh7DA');
33
- t.deepEqual(JSON.parse(JSON.stringify(kvStore.keyFromSerialized(ser))), {
34
- id: '123',
35
- kind: 'testYodel',
36
- path: ['testYodel', '123'],
37
- });
38
- });
39
- test('allocation', async (t) => {
40
- const kvStore = getDstore('test');
41
- const id = await kvStore.allocateOneId();
42
- t.regex(id, /\d+/);
43
- });
44
- // describe("Read", () => {
45
- // it("get num_id", async () => {
46
- // expect.assertions(10);
47
- // const kvStore = getDstore("test");
48
- // const entity = { key: kvStore.key(["testYodel", 2]), data: { foo: "bar" } };
49
- // const entity2 = { key: kvStore.key(["testYodel", 3]), data: { foo: "bar" } };
50
- // const commitResponse = await kvStore.save([entity, entity2]);
51
- // expect(isNumber(commitResponse?.[0]?.indexUpdates)).toBeTruthy();
52
- // // expect(commitResponse).toMatchInlineSnapshot(`
53
- // // Array [
54
- // // Object {
55
- // // "indexUpdates": 0,
56
- // // "mutationResults": Array [
57
- // // Object {
58
- // // "conflictDetected": false,
59
- // // "key": null,
60
- // // "version": "1234567890123456",
61
- // // },
62
- // // ],
63
- // // },
64
- // // ]
65
- // // `);
66
- // expect(entity).toMatchInlineSnapshot(`
67
- // Object {
68
- // "data": Object {
69
- // "foo": "bar",
70
- // },
71
- // "key": Key {
72
- // "id": 2,
73
- // "kind": "testYodel",
74
- // "namespace": "test",
75
- // "path": Array [
76
- // "testYodel",
77
- // 2,
78
- // ],
79
- // },
80
- // }
81
- // `);
82
- // const result = await kvStore.get(entity.key);
83
- // // get returns a single Entity
84
- // expect(Array.isArray(result)).toBeFalsy();
85
- // expect(result).toMatchInlineSnapshot(`
86
- // Object {
87
- // "_keyStr": "agdodXdhd2kzcg8LEgl0ZXN0WW9kZWwYAgyiAQR0ZXN0",
88
- // "foo": "bar",
89
- // Symbol(KEY): Key {
90
- // "id": "2",
91
- // "kind": "testYodel",
92
- // "namespace": "test",
93
- // "path": Array [
94
- // "testYodel",
95
- // "2",
96
- // ],
97
- // },
98
- // }
99
- // `);
100
- // assertIsObject(result);
101
- // expect(kvStore.readKey(result)).toBeInstanceOf(Key);
102
- // const result2 = await kvStore.getMulti([entity.key]);
103
- // // getMulti returns a Array even for single keys
104
- // expect(result2).toMatchInlineSnapshot(`
105
- // Array [
106
- // Object {
107
- // "_keyStr": "agdodXdhd2kzcg8LEgl0ZXN0WW9kZWwYAgyiAQR0ZXN0",
108
- // "foo": "bar",
109
- // Symbol(KEY): Key {
110
- // "id": "2",
111
- // "kind": "testYodel",
112
- // "namespace": "test",
113
- // "path": Array [
114
- // "testYodel",
115
- // "2",
116
- // ],
117
- // },
118
- // },
119
- // ]
120
- // `);
121
- // const result3 = await kvStore.getMulti([entity.key, kvStore.key(["testYodel", 3])]);
122
- // // getMulti returns a Array with multiple keys
123
- // // expect(Array.isArray(result)).toBeTruthy();
124
- // expect(result3).toMatchInlineSnapshot(`
125
- // Array [
126
- // Object {
127
- // "_keyStr": "agdodXdhd2kzcg8LEgl0ZXN0WW9kZWwYAgyiAQR0ZXN0",
128
- // "foo": "bar",
129
- // Symbol(KEY): Key {
130
- // "id": "2",
131
- // "kind": "testYodel",
132
- // "namespace": "test",
133
- // "path": Array [
134
- // "testYodel",
135
- // "2",
136
- // ],
137
- // },
138
- // },
139
- // Object {
140
- // "_keyStr": "agdodXdhd2kzcg8LEgl0ZXN0WW9kZWwYAwyiAQR0ZXN0",
141
- // "foo": "bar",
142
- // Symbol(KEY): Key {
143
- // "id": "3",
144
- // "kind": "testYodel",
145
- // "namespace": "test",
146
- // "path": Array [
147
- // "testYodel",
148
- // "3",
149
- // ],
150
- // },
151
- // },
152
- // ]
153
- // `);
154
- // const result4 = await kvStore.getMulti([entity.key, entity.key]);
155
- // // getMulti returns a Array but collapses duplicate keys
156
- // // expect(Array.isArray(result)).toBeTruthy();
157
- // // Firestore in Datastore returns the entity once
158
- // // Datastore Emulator returns the Entity twice
159
- // // kvStore should normalize that.
160
- // expect(result4).toMatchInlineSnapshot(`
161
- // Array [
162
- // Object {
163
- // "_keyStr": "agdodXdhd2kzcg8LEgl0ZXN0WW9kZWwYAgyiAQR0ZXN0",
164
- // "foo": "bar",
165
- // Symbol(KEY): Key {
166
- // "id": "2",
167
- // "kind": "testYodel",
168
- // "namespace": "test",
169
- // "path": Array [
170
- // "testYodel",
171
- // "2",
172
- // ],
173
- // },
174
- // },
175
- // Object {
176
- // "_keyStr": "agdodXdhd2kzcg8LEgl0ZXN0WW9kZWwYAgyiAQR0ZXN0",
177
- // "foo": "bar",
178
- // Symbol(KEY): Key {
179
- // "id": "2",
180
- // "kind": "testYodel",
181
- // "namespace": "test",
182
- // "path": Array [
183
- // "testYodel",
184
- // "2",
185
- // ],
186
- // },
187
- // },
188
- // ]
189
- // `);
190
- // const result5 = await kvStore.getMulti([entity.key, kvStore.key(["YodelNotThere", 3])]);
191
- // // getMulti returns a Array but omits unknown keys
192
- // // expect(Array.isArray(result)).toBeTruthy();
193
- // expect(result5).toMatchInlineSnapshot(`
194
- // Array [
195
- // Object {
196
- // "_keyStr": "agdodXdhd2kzcg8LEgl0ZXN0WW9kZWwYAgyiAQR0ZXN0",
197
- // "foo": "bar",
198
- // Symbol(KEY): Key {
199
- // "id": "2",
200
- // "kind": "testYodel",
201
- // "namespace": "test",
202
- // "path": Array [
203
- // "testYodel",
204
- // "2",
205
- // ],
206
- // },
207
- // },
208
- // ]
209
- // `);
210
- // const result6 = await kvStore.getMulti([]);
211
- // // getMulti returns a empty Array for an empty array
212
- // // expect(Array.isArray(result)).toBeTruthy();
213
- // expect(result6).toMatchInlineSnapshot(`Array []`);
214
- // });
215
- test('get name', async (t) => {
216
- const kvStore = getDstore('test');
217
- const entity = {
218
- key: kvStore.key(['testYodel', 'two']),
219
- data: { foo: 'bar' },
220
- };
221
- await kvStore.save([entity]);
222
- const result = await kvStore.get(entity.key);
223
- t.is(result?._keyStr, 'agByEgsSCXRlc3RZb2RlbCIDdHdvDA');
224
- t.is(result?.foo, 'bar');
225
- });
226
- test('query', async (t) => {
227
- const kvStore = getDstore('test');
228
- const entity = {
229
- key: kvStore.key(['testYodel', '3']),
230
- data: { foo: 'bar', baz: 'baz' },
231
- };
232
- await kvStore.save([entity]);
233
- const query = kvStore.createQuery('testYodel');
234
- query.limit(1);
235
- const [entities, runQueryInfo] = await kvStore.runQuery(query);
236
- t.is(entities.length, 1);
237
- t.is(entities?.[0]?.foo, 'bar');
238
- t.is(entities?.[0]?.[Datastore.KEY]?.kind, 'testYodel');
239
- t.is(runQueryInfo?.moreResults, 'MORE_RESULTS_AFTER_LIMIT');
240
- // modern interface
241
- const [result2] = await kvStore.query('testYodel', [], 1, [], ['baz']);
242
- t.is(result2.length, 1);
243
- // foo is removed by selection
244
- t.deepEqual(JSON.parse(JSON.stringify(result2?.[0])), {
245
- _keyStr: 'agByEAsSCXRlc3RZb2RlbCIBMww',
246
- baz: 'baz',
247
- });
248
- const key = kvStore.readKey(result2?.[0]);
249
- t.is(key.id, entity.key.id);
250
- });
251
- test('set', async (t) => {
252
- // expect.assertions(2);
253
- const kvStore = getDstore('test');
254
- const result = await kvStore.set(kvStore.key(['testYodel', '5e7']), {
255
- foo: 'bar',
256
- });
257
- t.deepEqual(result.name, '5e7');
258
- t.deepEqual(result.kind, 'testYodel');
259
- // autogenerate key
260
- const result2 = await kvStore.set(kvStore.key(['testYodel']), { foo: 'bar' });
261
- t.deepEqual(result2.kind, 'testYodel');
262
- });
263
- test('save / upsert', async (t) => {
264
- // expect.assertions(2);
265
- const kvStore = getDstore('test');
266
- const entity = {
267
- key: kvStore.key(['testYodel', 3]),
268
- data: { foo: 'bar' },
269
- };
270
- const result = await kvStore.save([entity]);
271
- // const result2 = await kvStore.upsert([entity]);
272
- t.is(result?.[0]?.mutationResults?.[0]?.conflictDetected, false);
273
- t.deepEqual(entity.data._keyStr, 'agByDwsSCXRlc3RZb2RlbBgDDA');
274
- t.deepEqual(entity.data.foo, 'bar');
275
- t.deepEqual(entity.data[Datastore.KEY].kind, 'testYodel');
276
- });
277
- test('update', async (t) => {
278
- // expect.assertions(3);
279
- const kvStore = getDstore('test');
280
- const keyName = `4insert${Math.random()}`;
281
- const entity = {
282
- key: kvStore.key(['testYodel', keyName]),
283
- data: { foo: 'bar' },
284
- };
285
- // const request = kvStore.update([entity]);
286
- // await expect(request).rejects.toThrowError(Error);
287
- await kvStore.save([entity]);
288
- const result = await kvStore.update([entity]);
289
- t.is(result?.[0]?.mutationResults?.[0]?.conflictDetected, false);
290
- t.is(result?.[0]?.mutationResults?.[0]?.key, null);
291
- t.is(result?.[0]?.indexUpdates, 2);
292
- });
293
- test('insert / delete', async (t) => {
294
- // expect.assertions(2);
295
- const kvStore = getDstore('test');
296
- const entity = {
297
- key: kvStore.key(['testYodel', 4]),
298
- data: { foo: 'bar' },
299
- };
300
- const result = await kvStore.insert([entity]);
301
- t.is(result?.[0]?.mutationResults?.[0]?.conflictDetected, false);
302
- t.is(result?.[0]?.indexUpdates, 3);
303
- // t.is(result?.[0]?.mutationResults?.[0]?.version, '4'); sometimes 4 sometimes 5, sometimes 3
304
- t.deepEqual(entity.data.foo, 'bar');
305
- t.deepEqual(entity.key.path, ['testYodel', 4]);
306
- const result2 = await kvStore.delete([entity.key]);
307
- t.is(result2?.[0]?.mutationResults?.[0]?.conflictDetected, false);
308
- });
309
- test('exception', async (t) => {
310
- // expect.assertions(2);
311
- const kvStore = getDstore('test');
312
- try {
313
- const result = await kvStore.set(kvStore.key(['testYodel', NaN]), {
314
- foo: 'bar',
315
- });
316
- }
317
- catch (e) {
318
- t.regex(e.stack, /Dstore\.set/);
319
- }
320
- });
321
- // describe("Transactions", () => {
322
- // it("simple", async () => {
323
- // expect.assertions(2);
324
- // const kvStore = getDstore("huwawi3Datastore");
325
- // const outerResult = await kvStore.runInTransaction<any>(async () => {
326
- // // write inside the transaction
327
- // const entity = { key: kvStore.key(["testYodel", 6]), data: { foo: "foobar" } };
328
- // const innerResult = await kvStore.save([entity]);
329
- // // save does not return anything within transactions
330
- // expect(innerResult).toMatchInlineSnapshot(`undefined`);
331
- // return 123;
332
- // });
333
- // expect(outerResult).toMatchInlineSnapshot(`123`);
334
- // // this fails in the Datastore Emulator
335
- // const entitiey = await kvStore.get(kvStore.key(["testYodel", 6]));
336
- // // expect(entitiey).toMatchInlineSnapshot(`
337
- // // Object {
338
- // // "foo": "foobar",
339
- // // Symbol(KEY): Key {
340
- // // "id": "6",
341
- // // "kind": "testYodel",
342
- // // "namespace": "test",
343
- // // "path": Array [
344
- // // "testYodel",
345
- // // "6",
346
- // // ],
347
- // // },
348
- // // }
349
- // // `);
350
- // });
351
- // it("throws", async () => {
352
- // expect.assertions(1);
353
- // const kvStore = getDstore("huwawi3Datastore");
354
- // const request = kvStore.runInTransaction<any>(async () => {
355
- // throw new DstoreError("TestError", undefined);
356
- // });
357
- // await expect(request).rejects.toThrowError(DstoreError);
358
- // });
359
- // });
360
- // describe('Exceptions', () => {
361
- // it('simple', async () => {
362
- // const t = () => {
363
- // throw new DstoreError('bla', undefined);
364
- // };
365
- // expect(t).toThrow(DstoreError);
366
- // });
367
- // });
368
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHN0b3JlLWFwaS5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9kc3RvcmUtYXBpLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxJQUFJLE1BQU0sS0FBSyxDQUFDO0FBQ3ZCLE9BQU8sUUFBUSxNQUFNLDJCQUEyQixDQUFDO0FBRWpELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEdBQUcsWUFBWSxDQUFDLENBQUMsd0NBQXdDO0FBQ25GLElBQUksUUFBUSxDQUFDO0FBRWIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUU7SUFDdkIsUUFBUSxHQUFHLElBQUksUUFBUSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDMUMsTUFBTSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDekIsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUU7SUFDakMsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDeEIsQ0FBQyxDQUFDLENBQUM7QUFFSCxTQUFTLFNBQVMsQ0FBQyxTQUFTO0lBQzFCLE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxTQUFTLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbEQsQ0FBQztBQUVELElBQUksQ0FBQyxjQUFjLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO0lBQy9CLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsQyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxH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
File without changes