event-storage 0.7.2 → 0.9.1

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,955 +0,0 @@
1
- const expect = require('expect.js');
2
- const fs = require('fs-extra');
3
- const Storage = require('../src/Storage');
4
- const zlib = require('zlib');
5
- //const lz4 = require('lz4');
6
-
7
- const dataDirectory = __dirname + '/data';
8
-
9
- describe('Storage', function() {
10
-
11
- /**
12
- * @var {WritableStorage}
13
- */
14
- let storage;
15
- let refs = [];
16
-
17
- function createStorage(options = {}) {
18
- const newStorage = new Storage(Object.assign({ dataDirectory }, options));
19
- refs.push(newStorage);
20
- return newStorage;
21
- }
22
-
23
- function createReader(options = {}) {
24
- const newStorage = new Storage.ReadOnly(Object.assign({ dataDirectory }, options));
25
- refs.push(newStorage);
26
- return newStorage;
27
- }
28
-
29
- beforeEach(function () {
30
- try {
31
- fs.emptyDirSync(dataDirectory);
32
- } catch (e) {
33
- }
34
- });
35
-
36
- afterEach(function () {
37
- refs.forEach(ref => ref.close());
38
- refs = [];
39
- if (storage) storage.close();
40
- storage = null;
41
- });
42
-
43
- it('creates the storage directory if it does not exist', function() {
44
- fs.removeSync(dataDirectory);
45
- storage = createStorage();
46
- expect(fs.existsSync(dataDirectory)).to.be(true);
47
- });
48
-
49
- it('can be opened multiple times', function(){
50
- storage = createStorage();
51
- storage.open();
52
- expect(() => {
53
- storage.open();
54
- }).to.not.throwError();
55
- });
56
-
57
- describe('write', function() {
58
-
59
- it('writes objects', function(done) {
60
- storage = createStorage();
61
- storage.open();
62
-
63
- storage.write({ foo: 'bar' }, done);
64
- });
65
-
66
- it('writes documents sequentially', function() {
67
- storage = createStorage();
68
- storage.open();
69
-
70
- for (let i = 1; i <= 10; i++) {
71
- expect(storage.write({ foo: 'bar' })).to.be(i);
72
- }
73
- expect(storage.index.length).to.be(10);
74
- });
75
-
76
- it('can write durable', function(done) {
77
- storage = createStorage({ maxWriteBufferDocuments: 1, syncOnFlush: true });
78
- storage.open();
79
-
80
- storage.write({ foo: 'bar' }, () => {
81
- let fileContent = fs.readFileSync('test/data/storage', 'utf8');
82
- expect(fileContent).to.contain(JSON.stringify({ foo: 'bar' }));
83
- done();
84
- });
85
- });
86
-
87
- it('reopens partition if partition was closed', function() {
88
- storage = createStorage();
89
- storage.open();
90
-
91
- const part = storage.getPartition('');
92
- part.close();
93
- expect(() => storage.write({ foo: 'bar' })).to.not.throwError();
94
- expect(storage.index.length).to.be(1);
95
- });
96
-
97
- it('can partition writes', function(done) {
98
- storage = createStorage({ partitioner: (doc, number) => 'part-' + ((number-1) % 4) });
99
- storage.open();
100
-
101
- for (let i = 1; i <= 4; i++) {
102
- storage.write({ foo: 'bar' }, i === 4 ? () => {
103
- expect(fs.existsSync('test/data/storage.part-0')).to.be(true);
104
- expect(fs.existsSync('test/data/storage.part-1')).to.be(true);
105
- expect(fs.existsSync('test/data/storage.part-2')).to.be(true);
106
- expect(fs.existsSync('test/data/storage.part-3')).to.be(true);
107
- done();
108
- } : undefined);
109
- }
110
- });
111
-
112
- it('can open secondary indexes lazily', function() {
113
- storage = createStorage();
114
- const index = storage.ensureIndex('foo', { type: 'foo' });
115
- storage.close();
116
-
117
- expect(index.isOpen()).to.be(false);
118
- for (let i = 1; i <= 10; i++) {
119
- storage.write({ type: (i % 3) ? 'bar' : 'foo' });
120
- }
121
- expect(index.isOpen()).to.be(true);
122
- });
123
-
124
- });
125
-
126
- describe('length', function() {
127
-
128
- it('returns the amount of documents in the storage', function() {
129
- storage = createStorage();
130
- storage.open();
131
-
132
- for (let i = 1; i <= 10; i++) {
133
- storage.write({ foo: 'bar' });
134
- expect(storage.length).to.be(i);
135
- }
136
-
137
- storage.close();
138
- storage.open();
139
-
140
- expect(storage.length).to.be(10);
141
- });
142
-
143
- });
144
-
145
- describe('read', function() {
146
-
147
- it('returns false when trying to read out of bounds', function() {
148
- storage = createStorage();
149
- storage.open();
150
-
151
- storage.write({ foo: 'bar' });
152
- expect(storage.read(2)).to.be(false);
153
- });
154
-
155
- it('can read back written documents', function() {
156
- storage = createStorage();
157
- storage.open();
158
-
159
- storage.write({ foo: 'bar' });
160
- expect(storage.read(1)).to.eql({ foo: 'bar' });
161
-
162
- storage.close();
163
- storage.open();
164
-
165
- expect(storage.read(1)).to.eql({ foo: 'bar' });
166
- });
167
-
168
- it('can read back random documents', function() {
169
- storage = createStorage();
170
- storage.open();
171
-
172
- for (let i = 1; i <= 10; i++) {
173
- storage.write({ foo: i });
174
- }
175
-
176
- expect(storage.read(5)).to.eql({ foo: 5 });
177
-
178
- storage.close();
179
- storage.open();
180
-
181
- expect(storage.read(5)).to.eql({ foo: 5 });
182
- });
183
-
184
- it('can read back from partitioned storage', function() {
185
- storage = createStorage({ partitioner: (doc, number) => 'part-' + ((number-1) % 4) });
186
- storage.open();
187
-
188
- for (let i = 1; i <= 8; i++) {
189
- storage.write({ foo: i });
190
- }
191
-
192
- for (let i = 1; i <= 8; i++) {
193
- expect(storage.read(i)).to.eql({ foo: i });
194
- }
195
-
196
- storage.close();
197
- storage.open();
198
-
199
- for (let i = 1; i <= 8; i++) {
200
- expect(storage.read(i)).to.eql({ foo: i });
201
- }
202
-
203
- storage.close();
204
- storage = createStorage();
205
- storage.open();
206
-
207
- for (let i = 1; i <= 8; i++) {
208
- expect(storage.read(i)).to.eql({ foo: i });
209
- }
210
- });
211
-
212
- it('can read with using secondary index', function() {
213
- storage = createStorage();
214
- storage.open();
215
- let odd = storage.ensureIndex('odd', (doc) => (doc.foo % 2) === 1);
216
-
217
- for (let i = 1; i <= 10; i++) {
218
- storage.write({ foo: i });
219
- }
220
-
221
- expect(storage.read(3, odd)).to.eql({ foo: 5 });
222
-
223
- storage.close();
224
- storage.open();
225
-
226
- expect(storage.read(3, odd)).to.eql({ foo: 5 });
227
- });
228
-
229
- it('can open secondary indexes lazily', function() {
230
- storage = createStorage();
231
- const index = storage.ensureIndex('foo', { type: 'foo' });
232
- for (let i = 1; i <= 10; i++) {
233
- storage.write({ type: (i % 3) ? 'bar' : 'foo' });
234
- }
235
- storage.close();
236
-
237
- expect(index.isOpen()).to.be(false);
238
- storage.read(1, index);
239
- expect(index.isOpen()).to.be(true);
240
- });
241
-
242
- });
243
-
244
- describe('readRange', function() {
245
-
246
- it('can read full range', function() {
247
- storage = createStorage();
248
- storage.open();
249
-
250
- for (let i = 1; i <= 10; i++) {
251
- storage.write({ foo: i });
252
- }
253
- storage.close();
254
- storage.open();
255
-
256
- let documents = storage.readRange(1);
257
- let i = 1;
258
- for (let doc of documents) {
259
- expect(doc).to.eql({ foo: i++ });
260
- }
261
- expect(i).to.be(11);
262
- });
263
-
264
- it('can read full range in reverse', function() {
265
- storage = createStorage();
266
- storage.open();
267
-
268
- for (let i = 1; i <= 20; i++) {
269
- storage.write({ foo: i });
270
- }
271
- storage.close();
272
- storage.open();
273
-
274
- let i = 20;
275
- let documents = storage.readRange(i, 1);
276
- for (let doc of documents) {
277
- expect(doc).to.eql({ foo: i-- });
278
- }
279
- expect(i).to.be(0);
280
- });
281
-
282
- it('can read a sub range', function() {
283
- storage = createStorage();
284
- storage.open();
285
-
286
- for (let i = 1; i <= 10; i++) {
287
- storage.write({ foo: i });
288
- }
289
- storage.close();
290
- storage.open();
291
-
292
- let documents = storage.readRange(4, 6);
293
- let i = 4;
294
- for (let doc of documents) {
295
- expect(doc).to.eql({ foo: i++ });
296
- }
297
- expect(i).to.be(7);
298
- });
299
-
300
- it('can read a range from end', function() {
301
- storage = createStorage();
302
- storage.open();
303
-
304
- for (let i = 1; i <= 10; i++) {
305
- storage.write({ foo: i });
306
- }
307
- storage.close();
308
- storage.open();
309
-
310
- let documents = storage.readRange(-4);
311
- let i = 7;
312
- for (let doc of documents) {
313
- expect(doc).to.eql({ foo: i++ });
314
- }
315
- expect(i).to.be(11);
316
- });
317
-
318
- it('can read a range until a position from end', function() {
319
- storage = createStorage();
320
- storage.open();
321
-
322
- for (let i = 1; i <= 10; i++) {
323
- storage.write({ foo: i });
324
- }
325
- storage.close();
326
- storage.open();
327
-
328
- let documents = storage.readRange(1, -4); // readRange(1, 7)
329
- let i = 1;
330
- for (let doc of documents) {
331
- expect(doc).to.eql({ foo: i++ });
332
- }
333
- expect(i).to.be(8);
334
- });
335
-
336
- it('can read a range from secondary index', function() {
337
- storage = createStorage();
338
- storage.open();
339
- let odd = storage.ensureIndex('odd', (doc) => (doc.foo % 2) === 1);
340
-
341
- for (let i = 1; i <= 10; i++) {
342
- storage.write({ foo: i });
343
- }
344
- storage.close();
345
- storage.open();
346
-
347
- let documents = storage.readRange(1, 3, odd);
348
- let i = 1;
349
- for (let doc of documents) {
350
- expect(doc).to.eql({ foo: i });
351
- i += 2;
352
- }
353
- expect(i).to.be(7);
354
- });
355
-
356
- it('throws on invalid range', function() {
357
- storage = createStorage();
358
- storage.open();
359
-
360
- for (let i = 1; i <= 10; i++) {
361
- storage.write({ foo: i });
362
- }
363
- storage.close();
364
- storage.open();
365
-
366
- expect(() => storage.readRange(0).next()).to.throwError();
367
- expect(() => storage.readRange(11).next()).to.throwError();
368
- expect(() => storage.readRange(1, 14).next()).to.throwError();
369
- });
370
-
371
- it('can open secondary indexes lazily', function() {
372
- storage = createStorage();
373
- const index = storage.ensureIndex('foo', { type: 'foo' });
374
- for (let i = 1; i <= 10; i++) {
375
- storage.write({ type: (i % 3) ? 'bar' : 'foo' });
376
- }
377
- storage.close();
378
-
379
- expect(index.isOpen()).to.be(false);
380
- Array.from(storage.readRange(1, 2, index));
381
- expect(index.isOpen()).to.be(true);
382
- });
383
-
384
- });
385
-
386
- describe('ensureIndex', function() {
387
-
388
- it('creates non-existing indexes', function() {
389
- storage = createStorage();
390
- storage.open();
391
-
392
- storage.ensureIndex('foo', () => true);
393
- expect(fs.existsSync('test/data/storage.foo.index')).to.be(true);
394
- });
395
-
396
- it('can be called multiple times', function() {
397
- storage = createStorage();
398
- storage.open();
399
-
400
- const index1 = storage.ensureIndex('foo', () => true);
401
- const index2 = storage.ensureIndex('foo', () => true);
402
- expect(index1).to.be(index2);
403
- });
404
-
405
- it('throws when calling for non-existing index without matcher', function() {
406
- storage = createStorage();
407
- storage.open();
408
-
409
- expect(() => storage.ensureIndex('foo')).to.throwError(/matcher/);
410
- });
411
-
412
- it('indexes documents by function matcher', function() {
413
- storage = createStorage();
414
- storage.open();
415
- let index = storage.ensureIndex('foo', (doc) => doc.type === 'Foo');
416
- storage.write({type: 'Bar'});
417
- storage.write({type: 'Foo'});
418
- storage.write({type: 'Baz'});
419
- expect(index.length).to.be(1);
420
- });
421
-
422
- it('indexes documents by property object matcher', function() {
423
- storage = createStorage();
424
- storage.open();
425
- let index = storage.ensureIndex('foo', { type: 'Foo' });
426
- storage.write({type: 'Bar'});
427
- storage.write({type: 'Foo'});
428
- storage.write({type: 'Baz'});
429
- expect(index.length).to.be(1);
430
- });
431
-
432
- it('reopens existing indexes', function() {
433
- storage = createStorage();
434
- storage.open();
435
- let index = storage.ensureIndex('foo', () => true);
436
- storage.write({foo: 'bar'});
437
- expect(index.length).to.be(1);
438
- storage.close();
439
-
440
- storage = createStorage();
441
- storage.open();
442
-
443
- index = storage.ensureIndex('foo', () => true);
444
- expect(index.length).to.be(1);
445
- });
446
-
447
- it('restores matcher from existing index', function() {
448
- storage = createStorage();
449
- storage.open();
450
- let index = storage.ensureIndex('foo', (doc) => doc.type === 'Foo');
451
- storage.write({type: 'Foo'});
452
- expect(index.length).to.be(1);
453
- storage.close();
454
-
455
- storage = createStorage();
456
- storage.open();
457
-
458
- index = storage.ensureIndex('foo');
459
- storage.write({type: 'Foo'});
460
- expect(index.length).to.be(2);
461
- });
462
-
463
- it('throws when hmac does not validate matcher from existing index', function() {
464
- storage = createStorage({ hmacSecret: 'foo' });
465
- storage.open();
466
- storage.ensureIndex('foo-hmac', (doc) => doc.type === 'Foo');
467
- storage.close();
468
-
469
- storage = createStorage({ hmacSecret: 'bar' });
470
- storage.open();
471
-
472
- expect(() => storage.ensureIndex('foo-hmac', (doc) => doc.type === 'Foo')).to.throwError();
473
- });
474
-
475
- it('throws when reopening with different matcher', function() {
476
- storage = createStorage();
477
- storage.open();
478
- storage.ensureIndex('foo-matcher', () => true);
479
- storage.close();
480
-
481
- storage = createStorage();
482
- storage.open();
483
-
484
- expect(() => storage.ensureIndex('foo-matcher', (doc) => doc.type === 'Foo')).to.throwError();
485
- });
486
-
487
- it('does not create an index when filling it fails', function() {
488
- storage = createStorage();
489
- storage.open();
490
- storage.write({type: 'Foo'});
491
-
492
- const Index = require('../src/Index');
493
- const originalAdd = Index.prototype.add;
494
- Index.prototype.add = () => { throw new Error('Failure'); };
495
- try {
496
- storage.ensureIndex('foo-new', (doc) => doc.type === 'Foo');
497
- } catch (e) {}
498
- expect(fs.existsSync('test/data/storage.foo-new.index')).to.be(false);
499
- Index.prototype.add = originalAdd;
500
- });
501
-
502
- });
503
-
504
- describe('openIndex', function() {
505
-
506
- it('throws on non-existing indexes', function () {
507
- storage = createStorage();
508
- storage.open();
509
-
510
- expect(() => storage.openIndex('foo')).to.throwError(/does not exist/);
511
- });
512
-
513
- it('throws when hmac does not validate matcher from existing index', function () {
514
- storage = createStorage({ hmacSecret: 'foo'});
515
- storage.open();
516
- storage.ensureIndex('foo', (doc) => doc.type === 'Foo');
517
- storage.close();
518
-
519
- storage = createStorage({ hmacSecret: 'bar'});
520
- storage.open();
521
- expect(() => storage.openIndex('foo')).to.throwError(/HMAC/);
522
- });
523
-
524
- it('opens existing indexes', function () {
525
- storage = createStorage();
526
- storage.open();
527
- storage.ensureIndex('foo', (doc) => doc.type === 'Foo');
528
- storage.write({type: 'Foo'});
529
- storage.close();
530
-
531
- storage = createStorage();
532
- storage.open();
533
- const index = storage.openIndex('foo');
534
- expect(index.length).to.be(1);
535
- });
536
-
537
- });
538
-
539
- describe('truncate', function() {
540
-
541
- it('does nothing if truncating after the current position', function() {
542
- storage = createStorage();
543
- storage.open();
544
-
545
- for (let i = 1; i <= 10; i++) {
546
- storage.write({ foo: i });
547
- }
548
- storage.close();
549
- storage.open();
550
-
551
- storage.truncate(12);
552
-
553
- expect(storage.length).to.be(10);
554
- });
555
-
556
- it('correctly truncates to empty', function() {
557
- storage = createStorage();
558
- storage.open();
559
-
560
- for (let i = 1; i <= 10; i++) {
561
- storage.write({ foo: i });
562
- }
563
- storage.close();
564
- storage.open();
565
-
566
- storage.truncate(0);
567
-
568
- expect(storage.length).to.be(0);
569
- });
570
-
571
- it('truncates after the given document number', function() {
572
- storage = createStorage();
573
- storage.open();
574
-
575
- for (let i = 1; i <= 10; i++) {
576
- storage.write({ foo: i });
577
- }
578
- storage.close();
579
- storage.open();
580
-
581
- storage.truncate(6);
582
-
583
- expect(storage.length).to.be(6);
584
-
585
- let documents = storage.readRange(1);
586
- let i = 1;
587
- for (let doc of documents) {
588
- expect(doc).to.eql({ foo: i++ });
589
- }
590
- expect(i).to.be(7);
591
- });
592
-
593
- it('truncates after the given document number on each partition', function() {
594
- storage = createStorage({
595
- partitioner: (doc, number) => 'part-' + (parseInt((number - 1) / 4) % 4)
596
- });
597
- storage.open();
598
-
599
- for (let i = 1; i <= 10; i++) {
600
- storage.write({foo: i});
601
- }
602
-
603
- storage.close();
604
- storage.open();
605
-
606
- storage.truncate(6);
607
-
608
- expect(storage.length).to.be(6);
609
-
610
- let documents = storage.readRange(1);
611
- let i = 1;
612
- for (let doc of documents) {
613
- expect(doc).to.eql({ foo: i++ });
614
- }
615
- expect(i).to.be(7);
616
- });
617
-
618
- it('truncates secondary indexes correctly', function() {
619
- storage = createStorage();
620
- storage.open();
621
- let index = storage.ensureIndex('foobar', (doc) => doc.foo % 2 === 0);
622
-
623
- for (let i = 1; i <= 10; i++) {
624
- storage.write({foo: i});
625
- }
626
-
627
- storage.close();
628
- storage.open();
629
-
630
- storage.truncate(6);
631
-
632
- expect(storage.length).to.be(6);
633
- expect(index.length).to.be(3);
634
-
635
- let documents = storage.readRange(1, -1, index);
636
- let i = 2;
637
- for (let doc of documents) {
638
- expect(doc).to.eql({ foo: i });
639
- i += 2;
640
- }
641
- expect(i).to.be(8);
642
- });
643
-
644
- it('keeps truncated secondary indexes closed', function() {
645
- storage = createStorage();
646
- storage.open();
647
- let index = storage.ensureIndex('foobar', (doc) => doc.foo % 2 === 0);
648
-
649
- for (let i = 1; i <= 10; i++) {
650
- storage.write({foo: i});
651
- }
652
-
653
- storage.close();
654
-
655
- storage.truncate(6);
656
-
657
- expect(index.isOpen()).to.be(false);
658
- index.open();
659
- expect(index.length).to.be(3);
660
- });
661
- });
662
-
663
- describe('matches', function() {
664
-
665
- const matches = Storage.matches;
666
-
667
- it('returns true if no matcher specified', function() {
668
- expect(matches({ foo: 'bar' })).to.be(true);
669
- });
670
-
671
- it('returns false if no document specified', function() {
672
- expect(matches()).to.be(false);
673
- });
674
-
675
- it('works with object matchers', function() {
676
- expect(matches({ foo: 'foo', bar: { baz: 'baz', quux: 'quux' } }, { foo: 'foo', bar: { baz: 'baz' } })).to.be(true);
677
- expect(matches({ foo: 'foo', bar: { baz: 'baz2', quux: 'quux' } }, { foo: 'foo', bar: { baz: 'baz' } })).to.be(false);
678
- });
679
-
680
- it('works with function matchers', function() {
681
- expect(matches({ foo: 'foo', bar: { baz: 'baz', quux: 'quux' } }, (doc) => doc.foo === 'foo')).to.be(true);
682
- expect(matches({ foo: 'foo2', bar: { baz: 'baz', quux: 'quux' } }, (doc) => doc.foo === 'foo')).to.be(false);
683
- });
684
-
685
- });
686
-
687
- describe('forEachDocument', function() {
688
-
689
- it('does nothing when called on empty storage', function(done) {
690
- storage = createStorage();
691
- storage.open();
692
-
693
- storage.forEachDocument((doc) => expect(this).to.be(false));
694
- setTimeout(done, 1);
695
- });
696
-
697
- });
698
-
699
- it('works with compression applied in serializer', function() {
700
- const dictionary = Buffer.from('"metadata":{"committedAt":,"commitId":,"commitVersion":,"streamVersion":{"stream":"Event-0f0da93d-260a-4ffd-94a0-126bd67ee8ff","payload":{"type":,"metadata":{"occuredAt":');
701
- storage = createStorage({ serializer: {
702
- serialize: (doc) => {
703
- return zlib.deflateRawSync(Buffer.from(JSON.stringify(doc)), { dictionary }).toString('binary');
704
- //return lz4.encode(Buffer.from(JSON.stringify(doc))).toString('binary');
705
- },
706
- deserialize: (string) => {
707
- return JSON.parse(zlib.inflateRawSync(Buffer.from(string, 'binary'), { dictionary }).toString());
708
- //return JSON.parse(lz4.decode(Buffer.from(string, 'binary')));
709
- }
710
- }});
711
- storage.open();
712
-
713
- const doc = {"stream":"Event-0f0da93d-260a-4ffd-94a0-126bd67ee8ff","payload":{"type":"DomainEvent","payload":{"type":"EventCreated","payload":{"eventIdentifier":"0f0da93d-260a-4ffd-94a0-126bd67ee8ff","name":"testi"}},"metadata":{"occuredAt":1482764928713,"aggregateId":"0f0da93d-260a-4ffd-94a0-126bd67ee8ff","version":0,"type":"EventCreated","correlationId":"9242b72b-03a0-4078-ae62-f37af7cb1b39"}},"metadata":{"committedAt":1482764928715,"commitId":1,"commitVersion":0,"streamVersion":0}};
714
- storage.write(doc);
715
- storage.write(doc);
716
- expect(storage.read(1)).to.be.eql(doc);
717
- expect(storage.read(2)).to.be.eql(doc);
718
- });
719
-
720
- describe('concurrency', function() {
721
-
722
- it('allows multiple writers to different partitions', function () {
723
- // t.b.d. - only possible if there is no storage global index
724
- });
725
-
726
- it('allows only a single writer', function(){
727
- let storage2 = createStorage();
728
- storage2.open();
729
- expect(() => {
730
- storage = createStorage();
731
- storage.open();
732
- }).to.throwError(e => e instanceof Storage.StorageLockedError);
733
- storage2.close();
734
- });
735
-
736
- it('releases write lock after closing', function(){
737
- const storage2 = createStorage();
738
- storage2.open();
739
- storage2.close();
740
- expect(() => {
741
- storage = createStorage();
742
- storage.open();
743
- }).to.not.throwError();
744
- });
745
-
746
- it('allows multiple readers for one storage', function () {
747
- storage = createStorage();
748
- storage.open();
749
- for (let i = 1; i <= 10; i++) {
750
- storage.write({foo: i});
751
- }
752
- storage.flush();
753
-
754
- let reader1 = createReader();
755
- reader1.open();
756
- expect(reader1.length).to.be(storage.length);
757
-
758
- let reader2 = createReader();
759
- reader2.open();
760
- expect(reader2.length).to.be(storage.length);
761
-
762
- reader1.close();
763
- reader2.close();
764
- });
765
-
766
- });
767
-
768
- describe('ReadOnly', function(){
769
-
770
- it('triggers event when writer appends', function(done){
771
- storage = createStorage({ syncOnFlush: true });
772
- storage.open();
773
- for (let i = 1; i <= 10; i++) {
774
- storage.write({foo: i});
775
- }
776
- storage.flush();
777
-
778
- let reader = createReader();
779
- reader.open();
780
- reader.on('index-add', () => expect(this).to.be(false));
781
- reader.on('wrote', (doc, entry, position) => {
782
- expect(entry.number).to.be(11);
783
- expect(doc).to.eql({foo: 11});
784
- reader.close();
785
- done();
786
- });
787
- expect(reader.length).to.be(storage.length);
788
-
789
- storage.write({ foo: 11 });
790
- storage.flush();
791
- });
792
-
793
- it('updates secondary indexes when writer appends', function(done){
794
- storage = createStorage({ syncOnFlush: true });
795
- storage.open();
796
- storage.ensureIndex('foo', doc => doc.type === 'foo');
797
- for (let i = 1; i <= 10; i++) {
798
- storage.write({foo: i, type: 'foo'});
799
- }
800
- storage.flush();
801
-
802
- let reader = createReader();
803
- reader.open();
804
- reader.openIndex('foo');
805
- reader.on('index-add', (name, number, doc) => {
806
- expect(name).to.be('foo');
807
- expect(number).to.be(11);
808
- expect(doc).to.eql({foo: 11, type: 'foo'});
809
- reader.close();
810
- done();
811
- });
812
- expect(reader.length).to.be(storage.length);
813
-
814
- storage.write({ foo: 11, type: 'foo' });
815
- storage.flush();
816
- });
817
-
818
- it('triggers event when writer truncates', function(done){
819
- storage = createStorage({ syncOnFlush: true });
820
- storage.open();
821
- for (let i = 1; i <= 10; i++) {
822
- storage.write({foo: i});
823
- }
824
- storage.flush();
825
-
826
- let reader = createReader();
827
- reader.open();
828
- reader.on('truncate', (prevLength, newLength) => {
829
- expect(prevLength).to.be(10);
830
- expect(newLength).to.be(4);
831
- reader.close();
832
- done();
833
- });
834
- expect(reader.length).to.be(storage.length);
835
-
836
- storage.truncate(4);
837
- });
838
-
839
- it('does not trigger truncate for secondary indexes', function(done){
840
- storage = createStorage({ syncOnFlush: true });
841
- storage.open();
842
- storage.ensureIndex('foo', doc => doc.type === 'foo');
843
- for (let i = 1; i <= 10; i++) {
844
- storage.write({foo: i, type: i > 5 ? 'foo' : 'bar'});
845
- }
846
- storage.flush();
847
-
848
- let reader = createReader();
849
- reader.open();
850
- reader.on('truncate', (prevLength, newLength) => {
851
- expect(prevLength).to.be(10);
852
- expect(newLength).to.be(4);
853
- setTimeout(() => {
854
- reader.close();
855
- done();
856
- }, 5);
857
- });
858
- expect(reader.length).to.be(storage.length);
859
-
860
- storage.truncate(4);
861
- });
862
-
863
- it('recognizes new indexes created by writer', function(done){
864
- storage = createStorage({ syncOnFlush: true, partitioner: (document, number) => document.type });
865
- storage.open();
866
-
867
- let reader = createReader();
868
- reader.open();
869
- reader.on('index-created', (name) => {
870
- expect(name.substr(-9, 3)).to.be('one');
871
- expect(reader.secondaryIndexes[name]).to.be(undefined);
872
- reader.close();
873
- done();
874
- });
875
-
876
- storage.ensureIndex('one', doc => doc.type === 'one');
877
- storage.flush();
878
- });
879
-
880
- it('ignores new indexes created by other storage', function(done){
881
- storage = createStorage();
882
- storage.open();
883
- storage.close();
884
-
885
- storage = new Storage('other-storage', { dataDirectory, syncOnFlush: true, partitioner: (document, number) => document.type });
886
- storage.open();
887
-
888
- let reader = createReader();
889
- reader.open();
890
- reader.on('index-created', (name) => {
891
- expect(this).to.be(false);
892
- reader.close();
893
- });
894
-
895
- storage.write({ foo: 1, type: 'one' });
896
- storage.ensureIndex('one', doc => doc.type === 'one');
897
- storage.flush();
898
- setTimeout(() => {
899
- reader.close();
900
- done();
901
- }, 5);
902
- });
903
-
904
- it('recognizes new partitions created by writer', function(done){
905
- storage = createStorage({ syncOnFlush: true, partitioner: (document, number) => document.type });
906
- storage.open();
907
-
908
- let reader = createReader();
909
- reader.open();
910
- reader.on('partition-created', (id) => {
911
- expect(reader.getPartition(id).name.substr(-3)).to.be('one');
912
- reader.close();
913
- done();
914
- });
915
-
916
- storage.write({ foo: 1, type: 'one' });
917
- storage.flush();
918
- });
919
-
920
- it('ignores new partitions created by other storage', function(done){
921
- storage = createStorage();
922
- storage.open();
923
- storage.close();
924
-
925
- storage = new Storage('other-storage', { dataDirectory, syncOnFlush: true, partitioner: (document, number) => document.type });
926
- storage.open();
927
-
928
- let reader = createReader();
929
- reader.open();
930
- reader.on('partition-created', (name) => {
931
- expect(this).to.be(false);
932
- reader.close();
933
- });
934
-
935
- storage.write({ foo: 1, type: 'one' });
936
- storage.flush();
937
- setTimeout(() => {
938
- reader.close();
939
- done();
940
- }, 5);
941
- });
942
-
943
- it('can be opened and closed multiple times', function(){
944
- storage = createStorage();
945
- storage.open();
946
-
947
- let reader = createReader();
948
- reader.open();
949
- expect(reader.open()).to.be(true);
950
- reader.close();
951
- reader.close();
952
- });
953
-
954
- });
955
- });