total5 0.0.1 → 0.0.2

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.
@@ -0,0 +1,617 @@
1
+ // Total.js NoSQL FileStream
2
+ // The MIT License
3
+ // Copyright 2020-2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ 'use strict';
6
+
7
+ const BUFFERSIZE = 1024 * 32;
8
+ const BUFFERDOCS = 15;
9
+ const NEWLINEBUFFER = Buffer.from('\n', 'utf8');
10
+ const DEFSTATS = { size: 0 };
11
+
12
+ function NoSQLStream(filename) {
13
+ this.filename = filename;
14
+ this.fd = null;
15
+ this.stats = DEFSTATS;
16
+ this.type = null;
17
+ this.bytesread = 0;
18
+ this.ticks = 0;
19
+ this.position = 0;
20
+ this.cache = [null, null];
21
+ this.buffer = null;
22
+ this.divider = ',';
23
+ this.remchar = '-';
24
+ this.buffercount = BUFFERDOCS;
25
+ this.buffersize = BUFFERSIZE;
26
+ this.linesize = 0;
27
+ this.start = 0;
28
+ this.indexer = 0;
29
+ // this.canceled = false;
30
+ // this.docs = '';
31
+ // this.docscount = 0;
32
+ }
33
+
34
+ // Because of performance
35
+ NoSQLStream.prototype.readhelpers = function() {
36
+
37
+ var self = this;
38
+
39
+ self.cb_read = () => self.read();
40
+
41
+ self.cb_readbuffer = function(err, size, chunk) {
42
+
43
+ self.position += size;
44
+
45
+ var beg = 0;
46
+
47
+ if (self.buffer) {
48
+ self.cache[0] = self.buffer;
49
+ self.cache[1] = chunk;
50
+
51
+ beg = self.buffer.length - 1;
52
+
53
+ if (beg < 0)
54
+ beg = 0;
55
+
56
+ self.buffer = Buffer.concat(self.cache);
57
+
58
+ } else
59
+ self.buffer = chunk;
60
+
61
+ var index = self.buffer.lastIndexOf(NEWLINEBUFFER);
62
+ if (index === -1) {
63
+ self.read();
64
+ return;
65
+ }
66
+
67
+ var tmp = self.buffer.toString('utf8', 0, index).split('\n');
68
+ for (var i = 0; i < tmp.length; i++) {
69
+ if (tmp[i][0] !== self.remchar) {
70
+ if (self.array)
71
+ self.docs.push(tmp[i]);
72
+ else
73
+ self.docs += (self.docs ? self.divider : '') + tmp[i];
74
+ self.docscount++;
75
+ self.indexer++;
76
+ }
77
+ }
78
+
79
+ self.buffer = self.buffer.slice(index + 1);
80
+
81
+ if (self.ondocuments() === false)
82
+ self.canceled = true;
83
+
84
+ self.docs = self.array ? [] : '';
85
+ self.docscount = 0;
86
+ self.ticks++;
87
+
88
+ if (self.ticks % 5 === 0)
89
+ setImmediate(self.cb_readticks);
90
+ else
91
+ self.read();
92
+ };
93
+
94
+ self.cb_readticks = () => self.read();
95
+ self.cb_readreverse = () => self.readreverse2();
96
+
97
+ self.cb_readreversebuffer = function(err, size, chunk) {
98
+
99
+ self.bytesread += size;
100
+
101
+ if (self.buffer) {
102
+ self.cache[0] = chunk;
103
+ self.cache[1] = self.buffer;
104
+ self.buffer = Buffer.concat(self.cache);
105
+ } else
106
+ self.buffer = chunk;
107
+
108
+ var index = self.buffer.indexOf(NEWLINEBUFFER);
109
+ if (index === -1) {
110
+ self.readreverse2();
111
+ return;
112
+ }
113
+
114
+ var tmp = self.buffer.toString('utf8', index).trim().split('\n');
115
+ for (var i = 0; i < tmp.length; i++) {
116
+ if (tmp[i][0] !== self.remchar) {
117
+ if (self.array)
118
+ self.docs.push(tmp[i]);
119
+ else
120
+ self.docs += (self.docs ? self.divider : '') + tmp[i];
121
+ self.docscount++;
122
+ self.indexer++;
123
+ }
124
+ }
125
+
126
+ if (self.ondocuments() === false)
127
+ self.canceled = true;
128
+
129
+ self.buffer = self.buffer.slice(0, index + 1);
130
+ self.docs = self.array ? [] : '';
131
+ self.docscount = 0;
132
+ self.ticks++;
133
+
134
+ if (self.ticks % 5 === 0)
135
+ setImmediate(self.cb_readreverseticks);
136
+ else
137
+ self.readreverse2();
138
+ };
139
+
140
+ self.cb_readreverseticks = () => self.readreverse2();
141
+
142
+ self.cb_readstream = function(chunk) {
143
+
144
+ if (self.canceled)
145
+ return;
146
+
147
+ var beg = 0;
148
+
149
+ if (self.buffer) {
150
+
151
+ self.cache[0] = self.buffer;
152
+ self.cache[1] = chunk;
153
+ self.buffer = Buffer.concat(self.cache);
154
+ beg = self.cache[0].length - 1;
155
+
156
+ if (beg < 0)
157
+ beg = 0;
158
+ } else
159
+ self.buffer = chunk;
160
+
161
+ var index = self.buffer.lastIndexOf(NEWLINEBUFFER);
162
+ if (index === -1)
163
+ return;
164
+
165
+ var tmp = self.buffer.toString('utf8', 0, index).split('\n');
166
+ for (var i = 0; i < tmp.length; i++) {
167
+ if (tmp[i][0] !== self.remchar) {
168
+ if (self.array)
169
+ self.docs.push(tmp[i]);
170
+ else
171
+ self.docs += (self.docs ? self.divider : '') + tmp[i];
172
+ self.docscount++;
173
+ self.indexer++;
174
+ }
175
+ }
176
+
177
+ self.buffer = self.buffer.slice(index + 1);
178
+
179
+ if (self.ondocuments() === false)
180
+ self.canceled = true;
181
+
182
+ if (self.canceled) {
183
+ self.stream.destroy && self.stream.destroy();
184
+ } else {
185
+ self.docs = self.array ? [] : '';
186
+ self.docscount = 0;
187
+ self.ticks++;
188
+ }
189
+ };
190
+
191
+ };
192
+
193
+ // Because of performance
194
+ NoSQLStream.prototype.writehelpers = function() {
195
+
196
+ var self = this;
197
+
198
+ self.cb_writeAddUpdAdd = function(err, size) {
199
+ if (err) {
200
+ console.log('ERROR --> TextDBStreamer.writer (add)', err);
201
+ self.canceled = true;
202
+ self.bufferstacknew.length = 0;
203
+ self.bufferstack.length = 0;
204
+ self.writing = false;
205
+ } else {
206
+ self.positionappend += size;
207
+ var item = self.bufferstack.shift();
208
+ F.Fs.write(self.fd, item.data, item.position, 'utf8', self.cb_writeAddUpdUpd);
209
+ }
210
+ };
211
+
212
+ self.cb_writeAddUpdUpd = function(err) {
213
+
214
+ self.writing = false;
215
+
216
+ if (err) {
217
+ console.log('ERROR --> TextDBStreamer.writer (upd)', err);
218
+ self.canceled = true;
219
+ self.bufferstack.length = 0;
220
+ self.bufferstacknew.length = 0;
221
+ } else
222
+ self.$write();
223
+ };
224
+
225
+ self.cb_writeAdd = function(err, size) {
226
+
227
+ self.writing = false;
228
+ self.positionappend += size;
229
+
230
+ if (err) {
231
+ console.log('ERROR --> TextDBStreamer.writer (add)', err);
232
+ self.canceled = true;
233
+ } else
234
+ self.$write();
235
+ };
236
+
237
+ self.cb_writeUpd = function(err) {
238
+
239
+ self.writing = false;
240
+
241
+ if (err) {
242
+ console.log('ERROR --> TextDBStreamer.writer (upd)', err);
243
+ self.canceled = true;
244
+ } else
245
+ self.$write();
246
+ };
247
+
248
+ self.cb_flush = () => self.flush();
249
+
250
+ self.cb_readwritebuffer = function(err, size, chunk) {
251
+
252
+ self.position += size;
253
+
254
+ var beg = 0;
255
+ var index;
256
+
257
+ if (self.buffer) {
258
+ self.cache[0] = self.buffer;
259
+ self.cache[1] = chunk;
260
+ beg = self.buffer.length - 1;
261
+ if (beg < 0)
262
+ beg = 0;
263
+ self.buffer = Buffer.concat(self.cache);
264
+ } else
265
+ self.buffer = chunk;
266
+
267
+
268
+ var index = self.buffer.lastIndexOf(NEWLINEBUFFER);
269
+ if (index === -1) {
270
+ self.readupdate();
271
+ return;
272
+ }
273
+
274
+ var tmp = self.buffer.toString('utf8', 0, index).split('\n');
275
+ for (var i = 0; i < tmp.length; i++) {
276
+ var size = Buffer.byteLength(tmp[i], 'utf8');
277
+ if (tmp[i][0] !== self.remchar) {
278
+ if (self.array)
279
+ self.docs.push(tmp[i]);
280
+ else
281
+ self.docs += (self.docs ? self.divider : '') + tmp[i];
282
+ self.docsbuffer.push({ length: size, doc: tmp[i], position: self.positionupdate });
283
+ self.docscount++;
284
+ self.indexer++;
285
+ }
286
+ self.positionupdate += size + 1;
287
+ }
288
+
289
+ if (self.ondocuments() === false)
290
+ self.canceled = true;
291
+
292
+ self.docsbuffer = [];
293
+ self.docs = self.array ? [] : '';
294
+ self.buffer = self.buffer.slice(index + 1);
295
+
296
+ if (self.bufferstack.length || self.bufferstacknew.length)
297
+ setImmediate(self.cb_writeticks);
298
+ else
299
+ self.readupdate();
300
+ };
301
+
302
+ self.cb_writeticks = function() {
303
+ if (self.bufferstack.length || self.bufferstacknew.length)
304
+ setImmediate(self.cb_writeticks);
305
+ else
306
+ self.readupdate();
307
+ };
308
+ };
309
+
310
+ NoSQLStream.prototype.openread = function() {
311
+ var self = this;
312
+ self.type = 'r';
313
+ self.position = self.start;
314
+ self.open();
315
+ return self;
316
+ };
317
+
318
+ NoSQLStream.prototype.openreadreverse = function() {
319
+ var self = this;
320
+ self.type = 'r';
321
+ self.position = self.start;
322
+ self.$reverse = true;
323
+ self.open();
324
+ return self;
325
+ };
326
+
327
+ NoSQLStream.prototype.openupdate = function() {
328
+ var self = this;
329
+ self.type = 'r+';
330
+ F.Fs.open(self.filename, self.type, function(err, fd) {
331
+
332
+ if (err) {
333
+ self.$callback(err);
334
+ return;
335
+ }
336
+
337
+ F.Fs.fstat(fd, function(err, stats) {
338
+
339
+ self.docs = self.array ? [] : '';
340
+ self.docscount = 0;
341
+
342
+ if (err) {
343
+ F.Fs.close(fd, NOOP);
344
+ self.$callback(err);
345
+ return;
346
+ }
347
+
348
+ self.docs = self.array ? [] : '';
349
+ self.docscount = 0;
350
+ self.fd = fd;
351
+ self.stats = stats;
352
+ self.position = self.start;
353
+ self.positionappend = self.stats.size;
354
+ self.positionupdate = self.start;
355
+ self.bufferstack = [];
356
+ self.bufferstacknew = [];
357
+ self.docsbuffer = [];
358
+ self.writehelpers();
359
+ self.readupdate();
360
+ });
361
+ });
362
+
363
+ return self;
364
+ };
365
+
366
+ // For e.g. files on URL address
367
+ NoSQLStream.prototype.openstream = function(stream) {
368
+
369
+ var self = this;
370
+
371
+ var close = function() {
372
+ if (self.docscount) {
373
+ self.ondocuments();
374
+ self.docscount = 0;
375
+ self.docs = self.array ? [] : '';
376
+ }
377
+ self.$callback && self.$callback();
378
+ self.$callback = null;
379
+ };
380
+
381
+ self.docs = self.array ? [] : '';
382
+ self.docscount = 0;
383
+ self.readhelpers();
384
+ self.stream = stream;
385
+ self.stream.on('error', close);
386
+ self.stream.on('end', close);
387
+ self.stream.on('data', self.cb_readstream);
388
+ return self;
389
+ };
390
+
391
+ NoSQLStream.prototype.open = function() {
392
+ var self = this;
393
+ F.Fs.open(self.filename, self.type, function(err, fd) {
394
+
395
+ if (err) {
396
+ self.$callback(err);
397
+ return;
398
+ }
399
+
400
+ F.Fs.fstat(fd, function(err, stats) {
401
+ self.docs = self.array ? [] : '';
402
+ self.docscount = 0;
403
+ self.fd = fd;
404
+ self.stats = stats;
405
+ self.position = self.start;
406
+
407
+ if (err) {
408
+ F.Fs.close(fd, NOOP);
409
+ self.$callback(err);
410
+ return;
411
+ }
412
+
413
+ self.readhelpers();
414
+
415
+ if (self.$reverse)
416
+ self.readreverse();
417
+ else
418
+ self.read();
419
+ });
420
+ });
421
+ };
422
+
423
+ NoSQLStream.prototype.close = function() {
424
+
425
+ var self = this;
426
+
427
+ if (self.fd) {
428
+
429
+ self.stream = null;
430
+
431
+ F.Fs.close(self.fd, function(err) {
432
+ err && F.error(err);
433
+ self.$callback && self.$callback();
434
+ });
435
+
436
+ if (self.buffer) {
437
+ self.buffer = null;
438
+ self.cache[0] = null;
439
+ self.cache[1] = null;
440
+ self.bytesread = 0;
441
+ }
442
+
443
+ self.canceled = false;
444
+ self.fd = null;
445
+ self.type = null;
446
+ self.docscache = null;
447
+ self.docs = null;
448
+
449
+ } else if (self.$callback)
450
+ self.$callback && self.$callback();
451
+
452
+ return self;
453
+ };
454
+
455
+ NoSQLStream.prototype.replace = function(index, value, divider) {
456
+
457
+ var self = this;
458
+ var rec = self.docsbuffer[index];
459
+
460
+ if (rec.doc === value)
461
+ return;
462
+
463
+ var was = true;
464
+ var sep = (divider || self.divider);
465
+
466
+ if (rec.doc.length === value.length) {
467
+ var b = Buffer.byteLength(value);
468
+ if (rec.length === b) {
469
+ self.write(value + sep, rec.position);
470
+ was = false;
471
+ }
472
+ }
473
+
474
+ if (was) {
475
+ var tmp = self.remchar + rec.doc.substring(1) + sep;
476
+ self.write(tmp, rec.position);
477
+ self.write2(value + sep);
478
+ }
479
+
480
+ return self;
481
+ };
482
+
483
+ NoSQLStream.prototype.write = function(doc, position) {
484
+ var self = this;
485
+ self.bufferstack.push({ position: position, data: doc });
486
+ !self.writing && self.$write();
487
+ return self;
488
+ };
489
+
490
+ NoSQLStream.prototype.write2 = function(doc) {
491
+ var self = this;
492
+ self.bufferstacknew.push(Buffer.from(doc));
493
+ !self.writing && self.$write();
494
+ return self;
495
+ };
496
+
497
+ NoSQLStream.prototype.$write = function() {
498
+ var self = this;
499
+ if (self.bufferstacknew.length && self.bufferstack.length) {
500
+ self.writing = true;
501
+ var buf = self.bufferstacknew.splice(0, 5);
502
+ buf = buf.length > 1 ? Buffer.concat(buf) : buf[0];
503
+ F.Fs.write(self.fd, buf, 0, buf.length, self.positionappend, self.cb_writeAddUpdAdd);
504
+ } else if (self.bufferstacknew.length) {
505
+ self.writing = true;
506
+ var buf = self.bufferstacknew.splice(0, 5);
507
+ buf = buf.length > 1 ? Buffer.concat(buf) : buf[0];
508
+ F.Fs.write(self.fd, buf, 0, buf.length, self.positionappend, self.cb_writeAdd);
509
+ } else if (self.bufferstack.length) {
510
+ self.writing = true;
511
+ var item = self.bufferstack.shift();
512
+ F.Fs.write(self.fd, item.data, item.position, 'utf8', self.cb_writeUpd);
513
+ }
514
+ };
515
+
516
+ NoSQLStream.prototype.flush = function() {
517
+ var self = this;
518
+ if (self.writing)
519
+ setTimeout(self.cb_flush, 100);
520
+ else
521
+ self.close();
522
+ return self;
523
+ };
524
+
525
+ NoSQLStream.prototype.read = function() {
526
+
527
+ var self = this;
528
+ var size = self.stats.size - self.position;
529
+
530
+
531
+ if (!self.fd || size <= 0 || self.canceled) {
532
+
533
+ if (!self.canceled && self.buffer && self.buffer.length) {
534
+ self.cb_readbuffer(null, 1, NEWLINEBUFFER);
535
+ self.buffer = Buffer.alloc(0);
536
+ return;
537
+ }
538
+
539
+ if (self.docscount) {
540
+ self.ondocuments();
541
+ self.docscount = 0;
542
+ self.docs = self.array ? [] : '';
543
+ }
544
+
545
+ self.close();
546
+
547
+ } else {
548
+ size = size < self.buffersize ? size : self.buffersize;
549
+ var buffer = Buffer.alloc(size);
550
+ F.Fs.read(self.fd, buffer, 0, size, self.position, self.cb_readbuffer);
551
+ }
552
+ };
553
+
554
+ NoSQLStream.prototype.readreverse = function() {
555
+ var self = this;
556
+ self.position = self.stats.size;
557
+ self.readreverse2();
558
+ return self;
559
+ };
560
+
561
+ NoSQLStream.prototype.readreverse2 = function() {
562
+ var self = this;
563
+
564
+ if (!self.fd || self.position <= self.start || self.canceled) {
565
+
566
+ if (!self.canceled && self.buffer && self.buffer.length) {
567
+ self.cb_readreversebuffer(null, 1, NEWLINEBUFFER);
568
+ self.buffer = Buffer.alloc(0);
569
+ return;
570
+ }
571
+
572
+ if (self.docscount) {
573
+ self.ondocuments();
574
+ self.docs = self.array ? [] : '';
575
+ self.docscount = 0;
576
+ }
577
+
578
+ self.close();
579
+
580
+ } else {
581
+ var size = self.stats.size - self.bytesread;
582
+ size = size < self.buffersize ? size : self.buffersize;
583
+ self.position -= size;
584
+ var buffer = Buffer.alloc(size);
585
+ F.Fs.read(self.fd, buffer, 0, size, self.position, self.cb_readreversebuffer);
586
+ }
587
+ };
588
+
589
+ NoSQLStream.prototype.readupdate = function() {
590
+
591
+ var self = this;
592
+ var size = self.stats.size - self.position;
593
+
594
+ if (!self.fd || size <= 0 || self.canceled) {
595
+
596
+ if (!self.canceled && self.buffer && self.buffer.length) {
597
+ self.positionappend++;
598
+ self.cb_readwritebuffer(null, 1, NEWLINEBUFFER);
599
+ self.buffer = Buffer.alloc(0);
600
+ return;
601
+ }
602
+
603
+ if (self.docsbuffer.length) {
604
+ self.ondocuments();
605
+ self.docsbuffer = [];
606
+ self.docs = self.array ? [] : '';
607
+ }
608
+
609
+ self.flush();
610
+ } else {
611
+ size = size < self.buffersize ? size : self.buffersize;
612
+ var buffer = Buffer.alloc(size);
613
+ F.Fs.read(self.fd, buffer, 0, size, self.position, self.cb_readwritebuffer);
614
+ }
615
+ };
616
+
617
+ module.exports = NoSQLStream;