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.
- package/LICENSE +211 -0
- package/README.md +32 -0
- package/api.js +297 -0
- package/bin/flow5 +142 -0
- package/bin/total5 +245 -0
- package/builders.js +1770 -0
- package/bundles.js +447 -0
- package/cache.js +58 -0
- package/changelog.txt +5 -0
- package/cluster.js +320 -0
- package/cms.js +759 -0
- package/controller.js +1640 -0
- package/cron.js +99 -0
- package/debug.js +546 -0
- package/edit.js +462 -0
- package/error.html +49 -0
- package/filestorage.js +1109 -0
- package/flow-flowstream.js +3352 -0
- package/flow.js +238 -0
- package/flowstream.js +2061 -0
- package/global.js +274 -0
- package/htmlparser.js +662 -0
- package/http.js +83 -0
- package/image.js +777 -0
- package/images.js +747 -0
- package/index.js +2851 -0
- package/jsonschema.js +699 -0
- package/ldap.js +792 -0
- package/macros.js +222 -0
- package/mail.js +922 -0
- package/markdown.js +762 -0
- package/minificators.js +858 -0
- package/nosql-builder.js +440 -0
- package/nosql-querybuilder.js +320 -0
- package/nosql-reader.js +353 -0
- package/nosql-stream.js +617 -0
- package/nosql.js +782 -0
- package/openclient.js +219 -0
- package/package.json +14 -5
- package/pause.html +67 -0
- package/querybuilder.js +1220 -0
- package/release.js +167 -0
- package/routing.js +1028 -0
- package/sourcemap.js +163 -0
- package/tangular.js +409 -0
- package/templates.js +145 -0
- package/test.js +51 -0
- package/tms.js +380 -0
- package/uibuilder.js +242 -0
- package/utils.js +6432 -0
- package/viewengine.js +891 -0
- package/websocket.js +1944 -0
- package/workers.js +129 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
// Total.js NoSQL QueryBuilder
|
|
2
|
+
// The MIT License
|
|
3
|
+
// Copyright 2020-2023 (c) Peter Širka <petersirka@gmail.com>
|
|
4
|
+
|
|
5
|
+
const REG_NULLABLE = /\./g;
|
|
6
|
+
const REG_LANGUAGE = /[a-z0-9]+§/gi;
|
|
7
|
+
const REG_ABSOLUTE = /\/|\\/;
|
|
8
|
+
const LOGGER = '-- NoSQL -->';
|
|
9
|
+
const FILTER = { find: 1, read: 1, count: 1, scalar: 1, check: 1, list: 1, update: 1, remove: 1, query: 1 };
|
|
10
|
+
const Open = {};
|
|
11
|
+
|
|
12
|
+
function db_where(where, opt, filter, operator, args) {
|
|
13
|
+
|
|
14
|
+
var tmp;
|
|
15
|
+
|
|
16
|
+
for (var item of filter) {
|
|
17
|
+
|
|
18
|
+
if (item.comparer) {
|
|
19
|
+
switch (item.comparer) {
|
|
20
|
+
case '=':
|
|
21
|
+
item.comparer = '==';
|
|
22
|
+
break;
|
|
23
|
+
case '<>':
|
|
24
|
+
item.comparer = '!=';
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (opt.language != null && item.name && item.name[item.name.length - 1] === '§')
|
|
30
|
+
item.name = item.name.substring(0, item.name.length - 1) + opt.language;
|
|
31
|
+
|
|
32
|
+
switch (item.type) {
|
|
33
|
+
case 'or':
|
|
34
|
+
tmp = [];
|
|
35
|
+
db_where(tmp, opt, item.value, '||', args);
|
|
36
|
+
where.length && where.push(operator);
|
|
37
|
+
where.push('(' + tmp.join(' ') + ')');
|
|
38
|
+
break;
|
|
39
|
+
case 'in':
|
|
40
|
+
case 'notin':
|
|
41
|
+
where.length && where.push(operator);
|
|
42
|
+
where.push((item.type === 'notin' ? '!' : '') + 'func.in(doc.' + item.name.replace(REG_NULLABLE, '?.') + ',arg.params[' + args(item.value) + '])');
|
|
43
|
+
break;
|
|
44
|
+
case 'query':
|
|
45
|
+
where.length && where.push(operator);
|
|
46
|
+
where.push('(' + item.value + ')');
|
|
47
|
+
break;
|
|
48
|
+
case 'where':
|
|
49
|
+
where.length && where.push(operator);
|
|
50
|
+
where.push('doc.' + item.name.replace(REG_NULLABLE, '?.') + item.comparer + 'arg.params[' + args(item.value) + ']');
|
|
51
|
+
break;
|
|
52
|
+
case 'contains':
|
|
53
|
+
where.length && where.push(operator);
|
|
54
|
+
where.push('(doc.{0} instanceof Array?!!doc.{0}.length:!!doc.{0})'.format(item.name.replace(REG_NULLABLE, '?.')));
|
|
55
|
+
break;
|
|
56
|
+
case 'search':
|
|
57
|
+
var paramindex = args(item.value.replace(/%/g, ''));
|
|
58
|
+
where.length && where.push(operator);
|
|
59
|
+
where.push('func.search(doc.' + item.name.replace(REG_NULLABLE, '?.') + ',arg.params[' + paramindex + ']' + (item.comparer == 'beg' ? ',1' : item.comparer == 'end' ? ',2' : '') + ')');
|
|
60
|
+
break;
|
|
61
|
+
case 'month':
|
|
62
|
+
case 'year':
|
|
63
|
+
case 'day':
|
|
64
|
+
case 'hour':
|
|
65
|
+
case 'minute':
|
|
66
|
+
where.length && where.push(operator);
|
|
67
|
+
where.push(compare_datetype(item.type, item.name, args(item.value), item.comparer));
|
|
68
|
+
break;
|
|
69
|
+
case 'empty':
|
|
70
|
+
where.length && where.push(operator);
|
|
71
|
+
where.push('(doc.{0} instanceof Array?!doc.{0}.length:!doc.{0})'.format(item.name.replace(REG_NULLABLE, '?.')));
|
|
72
|
+
break;
|
|
73
|
+
case 'between':
|
|
74
|
+
var ia = args(item.a);
|
|
75
|
+
var ib = args(item.b);
|
|
76
|
+
where.length && where.push(operator);
|
|
77
|
+
where.push('(doc.' + item.name.replace(REG_NULLABLE, '?.') + '>=arg.params[' + ia + ']&&doc.' + item.name + '<=arg.params[' + ib + '])');
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function db_insertupdate(filter, insert) {
|
|
84
|
+
|
|
85
|
+
var query = insert ? null : [];
|
|
86
|
+
var params = {};
|
|
87
|
+
|
|
88
|
+
for (var key in filter.payload) {
|
|
89
|
+
var val = filter.payload[key];
|
|
90
|
+
var c = key[0];
|
|
91
|
+
|
|
92
|
+
switch (c) {
|
|
93
|
+
case '-':
|
|
94
|
+
case '+':
|
|
95
|
+
case '*':
|
|
96
|
+
case '/':
|
|
97
|
+
key = key.substring(1);
|
|
98
|
+
params[key] = val ? val : 0;
|
|
99
|
+
if (!insert)
|
|
100
|
+
query.push('doc.{0}=(doc.{0}==null?0:doc.{0})+arg.{0}'.format(key));
|
|
101
|
+
break;
|
|
102
|
+
case '>':
|
|
103
|
+
case '<':
|
|
104
|
+
key = key.substring(1);
|
|
105
|
+
params[key] = val ? val : 0;
|
|
106
|
+
if (!insert)
|
|
107
|
+
query.push('doc.{0}=(doc.{0}==null?arg.{0}:doc.{0}' + (c === '>' ? '<' : '>') + 'arg.{0}?arg.{0}:doc.{0})'.format(key));
|
|
108
|
+
break;
|
|
109
|
+
case '!':
|
|
110
|
+
// toggle
|
|
111
|
+
key = key.substring(1);
|
|
112
|
+
if (insert)
|
|
113
|
+
params[key] = true;
|
|
114
|
+
else
|
|
115
|
+
query.push('doc.{0}=!doc.{0}'.format(key));
|
|
116
|
+
break;
|
|
117
|
+
case '=':
|
|
118
|
+
case '#':
|
|
119
|
+
// raw
|
|
120
|
+
key = key.substring(1);
|
|
121
|
+
if (insert)
|
|
122
|
+
params[key] = val;
|
|
123
|
+
else
|
|
124
|
+
query.push('doc.' + key + '=' + val);
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
params[key] = val;
|
|
128
|
+
if (!insert)
|
|
129
|
+
query.push('doc.{0}=arg.{0}'.format(key));
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return { query, params };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function makefilter(db, opt, callback) {
|
|
138
|
+
|
|
139
|
+
var where = [];
|
|
140
|
+
var model = {};
|
|
141
|
+
var isread = false;
|
|
142
|
+
var args = [];
|
|
143
|
+
var exec = opt.exec;
|
|
144
|
+
|
|
145
|
+
db_where(where, opt, opt.filter, '&&', val => args.push(val) - 1);
|
|
146
|
+
|
|
147
|
+
var builder = {};
|
|
148
|
+
var insert = exec === 'insert';
|
|
149
|
+
|
|
150
|
+
if (insert || exec === 'update') {
|
|
151
|
+
var iu = db_insertupdate(opt, insert);
|
|
152
|
+
if (iu) {
|
|
153
|
+
if (insert) {
|
|
154
|
+
builder.payload = iu.params;
|
|
155
|
+
} else {
|
|
156
|
+
builder.modify = iu.query ? iu.query.join(';') : null;
|
|
157
|
+
builder.modifyarg = iu.params;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (FILTER[exec]) {
|
|
163
|
+
builder.filter = where.join('') || 'true';
|
|
164
|
+
builder.filterarg = { params: args };
|
|
165
|
+
builder.take = opt.take;
|
|
166
|
+
builder.skip = opt.skip;
|
|
167
|
+
builder.first = opt.first;
|
|
168
|
+
if (opt.sort && opt.sort.length) {
|
|
169
|
+
builder.sort = opt.sort.join(',');
|
|
170
|
+
if (opt.language != null)
|
|
171
|
+
builder.sort = builder.sort.replace(REG_LANGUAGE, val => (val.substring(0, val.length - 1) + opt.language));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (opt.fields) {
|
|
176
|
+
builder.fields = opt.fields.join(',');
|
|
177
|
+
if (opt.language != null && builder.fields) {
|
|
178
|
+
builder.fields = builder.fields.replace(REG_LANGUAGE, function(val) {
|
|
179
|
+
val = val.substring(0, val.length - 1);
|
|
180
|
+
return val + (opt.language ? (opt.language + ' as ' + val) : '');
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
switch (exec) {
|
|
186
|
+
case 'find':
|
|
187
|
+
isread = true;
|
|
188
|
+
db.find2().assign(builder).$callback = callback;
|
|
189
|
+
break;
|
|
190
|
+
case 'count':
|
|
191
|
+
isread = true;
|
|
192
|
+
builder.scalar = 'arg.count+=1';
|
|
193
|
+
builder.scalararg = { count: 0 };
|
|
194
|
+
db.find().assign(builder).$callback = callback;
|
|
195
|
+
break;
|
|
196
|
+
case 'check':
|
|
197
|
+
builder.first = true;
|
|
198
|
+
isread = true;
|
|
199
|
+
db.find().assign(builder).$callback = (err, response) => callback(err, !!response);
|
|
200
|
+
break;
|
|
201
|
+
case 'list':
|
|
202
|
+
db.find().assign(builder).$callback = (err, response, meta) => callback(err, err ? null : { items: response, count: meta.count });
|
|
203
|
+
isread = true;
|
|
204
|
+
break;
|
|
205
|
+
case 'read':
|
|
206
|
+
db.find2().assign(builder).$callback = callback;
|
|
207
|
+
isread = true;
|
|
208
|
+
break;
|
|
209
|
+
case 'insert':
|
|
210
|
+
db.insert().assign(builder).$callback = callback;
|
|
211
|
+
break;
|
|
212
|
+
case 'update':
|
|
213
|
+
db.update().assign(builder).$callback = callback;
|
|
214
|
+
break;
|
|
215
|
+
case 'remove':
|
|
216
|
+
db.remove().assign(builder).$callback = callback;
|
|
217
|
+
break;
|
|
218
|
+
case 'truncate':
|
|
219
|
+
db.clear(callback);
|
|
220
|
+
break;
|
|
221
|
+
case 'drop':
|
|
222
|
+
db.drop(callback);
|
|
223
|
+
delete Open[db.$qbkey];
|
|
224
|
+
break;
|
|
225
|
+
case 'scalar':
|
|
226
|
+
switch (opt.scalar.type) {
|
|
227
|
+
case 'avg':
|
|
228
|
+
case 'min':
|
|
229
|
+
case 'sum':
|
|
230
|
+
case 'max':
|
|
231
|
+
case 'count':
|
|
232
|
+
if (opt.scalar.key2) {
|
|
233
|
+
builder.scalar = 'var k=doc.' + opt.scalar.key + '+\'\';if (arg[k]){tmp.bk=doc.' + opt.scalar.key2 + '||0;' + (opt.scalar.type === 'max' ? 'if(tmp.bk>arg[k])arg[k]=tmp.bk' : opt.scalar.type === 'min' ? 'if(tmp.bk<arg[k])arg[k]=tmp.bk' : 'arg[k]+=tmp.bk') + '}else{arg[k]=doc.' + opt.scalar.key2 + '||0}';
|
|
234
|
+
} else {
|
|
235
|
+
builder.scalar = 'if (doc.{0}!=null){tmp.val=doc.{0};arg.count+=1;arg.min=arg.min==null?tmp.val:arg.min>tmp.val?tmp.val:arg.min;arg.max=arg.max==null?tmp.val:arg.max<tmp.val?tmp.val:arg.max;if(!(tmp.val instanceof Date))arg.sum+=tmp.val}'.format(opt.scalar.key);
|
|
236
|
+
builder.scalararg = { count: 0, sum: 0 };
|
|
237
|
+
}
|
|
238
|
+
db.find().assign(builder).$callback = function(err, response) {
|
|
239
|
+
var output = {};
|
|
240
|
+
if (response)
|
|
241
|
+
output.value = opt.scalar.type === 'avg' ? ((response.min + response.max) / 2) : response[opt.scalar.type];
|
|
242
|
+
callback(err, output);
|
|
243
|
+
};
|
|
244
|
+
break;
|
|
245
|
+
case 'group':
|
|
246
|
+
builder.scalar = opt.scalar.key2 ? 'if (doc.{0}!=null){tmp.val=doc.{0};arg[tmp.val]=(arg[tmp.val]||0)+(doc.{1}||0)}'.format(opt.scalar.key, opt.scalar.key2) : 'if (doc.{0}!=null){tmp.val=doc.{0};arg[tmp.val]=(arg[tmp.val]||0)+1}'.format(opt.scalar.key);
|
|
247
|
+
builder.scalararg = {};
|
|
248
|
+
db.find().assign(builder).$callback = function(err, response) {
|
|
249
|
+
var output = [];
|
|
250
|
+
for (var key in response) {
|
|
251
|
+
var val = response[key];
|
|
252
|
+
var mod = {};
|
|
253
|
+
mod[opt.scalar.key] = key;
|
|
254
|
+
mod.value = val;
|
|
255
|
+
output.push(mod);
|
|
256
|
+
}
|
|
257
|
+
callback(err, output);
|
|
258
|
+
};
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
isread = true;
|
|
262
|
+
break;
|
|
263
|
+
case 'command':
|
|
264
|
+
if (opt.command === 'clean')
|
|
265
|
+
db.clean(callback);
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (opt.debug)
|
|
270
|
+
console.log(LOGGER, db.filename, exec, builder);
|
|
271
|
+
|
|
272
|
+
if (isread)
|
|
273
|
+
F.stats.performance.dbrm++;
|
|
274
|
+
else
|
|
275
|
+
F.stats.performance.dbwm++;
|
|
276
|
+
|
|
277
|
+
return model;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function compare_datetype(type, key, paramindex, operator) {
|
|
281
|
+
switch (operator) {
|
|
282
|
+
case '=':
|
|
283
|
+
operator = '==';
|
|
284
|
+
break;
|
|
285
|
+
case '<>':
|
|
286
|
+
operator = '!=';
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
switch (type) {
|
|
290
|
+
case 'day':
|
|
291
|
+
type = 'getDate()';
|
|
292
|
+
break;
|
|
293
|
+
case 'month':
|
|
294
|
+
type = 'getMonth()+1';
|
|
295
|
+
break;
|
|
296
|
+
case 'year':
|
|
297
|
+
type = 'getFullYear()';
|
|
298
|
+
break;
|
|
299
|
+
case 'hour':
|
|
300
|
+
type = 'getHour()';
|
|
301
|
+
break;
|
|
302
|
+
case 'minute':
|
|
303
|
+
type = 'getMinute()';
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
return 'doc.{0}&&doc.{0}.getTime?doc.{0}.{3}{2}arg.params[{1}]:false'.format(key.replace(REG_NULLABLE, '?.'), paramindex, operator, type);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
F.TQueryBuilder.create('nosql', function($, next) {
|
|
310
|
+
|
|
311
|
+
let key = 'nosql_' + $.table;
|
|
312
|
+
|
|
313
|
+
if (!Open[key]) {
|
|
314
|
+
let filename = REG_ABSOLUTE.test($.table) ? $.table : F.path.databases($.table + '.nosql');
|
|
315
|
+
Open[key] = F.TNoSQL.create(filename);
|
|
316
|
+
Open[key].$qbkey = key;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
makefilter(Open[key], $, next);
|
|
320
|
+
});
|
package/nosql-reader.js
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
// Total.js NoSQL Data reader
|
|
2
|
+
// The MIT License
|
|
3
|
+
// Copyright 2020-2023 (c) Peter Širka <petersirka@gmail.com>
|
|
4
|
+
|
|
5
|
+
function NoSQLReader(builder) {
|
|
6
|
+
var self = this;
|
|
7
|
+
self.ts = Date.now();
|
|
8
|
+
self.cancelable = true;
|
|
9
|
+
self.builders = [];
|
|
10
|
+
self.canceled = 0;
|
|
11
|
+
self.total = 0;
|
|
12
|
+
|
|
13
|
+
if (builder) {
|
|
14
|
+
self.add(builder);
|
|
15
|
+
self.prepare();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
NoSQLReader.prototype.add = function(builder) {
|
|
20
|
+
var self = this;
|
|
21
|
+
if (builder instanceof Array) {
|
|
22
|
+
for (var i = 0; i < builder.length; i++)
|
|
23
|
+
self.add(builder[i]);
|
|
24
|
+
} else {
|
|
25
|
+
builder.$NoSQLReader = self;
|
|
26
|
+
if (builder.$sort)
|
|
27
|
+
self.cancelable = false;
|
|
28
|
+
self.builders.push(builder);
|
|
29
|
+
}
|
|
30
|
+
return self;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
NoSQLReader.prototype.compare2 = function(docs, custom, done) {
|
|
34
|
+
|
|
35
|
+
var self = this;
|
|
36
|
+
|
|
37
|
+
for (var i = 0; i < docs.length; i++) {
|
|
38
|
+
|
|
39
|
+
var doc = docs[i];
|
|
40
|
+
if (doc === EMPTYOBJECT)
|
|
41
|
+
continue;
|
|
42
|
+
|
|
43
|
+
if (self.builders.length === self.canceled) {
|
|
44
|
+
self.total = 0;
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
self.total++;
|
|
49
|
+
var is = false;
|
|
50
|
+
|
|
51
|
+
for (var j = 0; j < self.builders.length; j++) {
|
|
52
|
+
|
|
53
|
+
var builder = self.builders[j];
|
|
54
|
+
if (builder.canceled)
|
|
55
|
+
continue;
|
|
56
|
+
|
|
57
|
+
builder.scanned++;
|
|
58
|
+
|
|
59
|
+
var can = false;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
can = builder.filterrule(doc, builder.filterarg, builder.tmp, builder.func);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
can = false;
|
|
65
|
+
builder.canceled = true;
|
|
66
|
+
builder.error = e + '';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (can) {
|
|
70
|
+
|
|
71
|
+
builder.count++;
|
|
72
|
+
|
|
73
|
+
if (!builder.$sort && ((builder.$skip && builder.$skip >= builder.count) || (builder.$take && builder.$take <= builder.counter)))
|
|
74
|
+
continue;
|
|
75
|
+
|
|
76
|
+
if (!is)
|
|
77
|
+
is = true;
|
|
78
|
+
|
|
79
|
+
builder.counter++;
|
|
80
|
+
|
|
81
|
+
var canceled = builder.canceled;
|
|
82
|
+
var c = custom(docs, doc, i, builder, j);
|
|
83
|
+
|
|
84
|
+
if (builder.$take === 1) {
|
|
85
|
+
builder.canceled = true;
|
|
86
|
+
self.canceled++;
|
|
87
|
+
} else if (!canceled && builder.canceled)
|
|
88
|
+
self.canceled++;
|
|
89
|
+
|
|
90
|
+
if (c === 1)
|
|
91
|
+
break;
|
|
92
|
+
else
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
is && done && done(docs, doc, i, self.builders);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// For FILEDB
|
|
102
|
+
NoSQLReader.prototype.compare3 = function(docs, custom) {
|
|
103
|
+
|
|
104
|
+
var self = this;
|
|
105
|
+
var changed = false;
|
|
106
|
+
|
|
107
|
+
for (var i = 0; i < docs.length; i++) {
|
|
108
|
+
|
|
109
|
+
var doc = docs[i];
|
|
110
|
+
if (doc === EMPTYOBJECT)
|
|
111
|
+
continue;
|
|
112
|
+
|
|
113
|
+
if (self.builders.length === self.canceled) {
|
|
114
|
+
self.total = 0;
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
self.total++;
|
|
119
|
+
|
|
120
|
+
for (var j = 0; j < self.builders.length; j++) {
|
|
121
|
+
|
|
122
|
+
var builder = self.builders[j];
|
|
123
|
+
if (builder.canceled)
|
|
124
|
+
continue;
|
|
125
|
+
|
|
126
|
+
builder.scanned++;
|
|
127
|
+
|
|
128
|
+
var can = false;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
can = builder.filterrule(doc, builder.filterarg, builder.tmp, builder.func);
|
|
132
|
+
} catch (e) {
|
|
133
|
+
can = false;
|
|
134
|
+
builder.canceled = true;
|
|
135
|
+
builder.error = e + '';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (can) {
|
|
139
|
+
|
|
140
|
+
builder.count++;
|
|
141
|
+
|
|
142
|
+
if (!builder.$sort && ((builder.$skip && builder.$skip >= builder.count) || (builder.$take && builder.$take <= builder.counter)))
|
|
143
|
+
continue;
|
|
144
|
+
|
|
145
|
+
if (!changed)
|
|
146
|
+
changed = true;
|
|
147
|
+
|
|
148
|
+
builder.counter++;
|
|
149
|
+
|
|
150
|
+
var canceled = builder.canceled;
|
|
151
|
+
var c = custom(docs, doc, i, builder, j);
|
|
152
|
+
|
|
153
|
+
if (builder.$take === 1) {
|
|
154
|
+
builder.canceled = true;
|
|
155
|
+
self.canceled++;
|
|
156
|
+
} else if (!canceled && builder.canceled)
|
|
157
|
+
self.canceled++;
|
|
158
|
+
|
|
159
|
+
if (c === 1)
|
|
160
|
+
break;
|
|
161
|
+
else
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return changed ? 2 : 1;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
NoSQLReader.prototype.compare = function(docs) {
|
|
171
|
+
|
|
172
|
+
var self = this;
|
|
173
|
+
self.total += docs.length;
|
|
174
|
+
|
|
175
|
+
for (var i = 0; i < docs.length; i++) {
|
|
176
|
+
var doc = docs[i];
|
|
177
|
+
|
|
178
|
+
if (self.builders.length === self.canceled) {
|
|
179
|
+
self.total = 0;
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
for (var j = 0; j < self.builders.length; j++) {
|
|
184
|
+
|
|
185
|
+
var builder = self.builders[j];
|
|
186
|
+
if (builder.canceled)
|
|
187
|
+
continue;
|
|
188
|
+
|
|
189
|
+
builder.scanned++;
|
|
190
|
+
|
|
191
|
+
var is = false;
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
is = builder.filterrule(doc, builder.filterarg, builder.tmp, builder.func);
|
|
195
|
+
} catch (e) {
|
|
196
|
+
is = false;
|
|
197
|
+
builder.canceled = true;
|
|
198
|
+
builder.error = e + '';
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (is) {
|
|
202
|
+
|
|
203
|
+
builder.count++;
|
|
204
|
+
|
|
205
|
+
if (builder.scalarrule) {
|
|
206
|
+
builder.counter++;
|
|
207
|
+
try {
|
|
208
|
+
builder.scalarrule(doc, builder.scalararg, builder.tmp, builder.func);
|
|
209
|
+
} catch (e) {
|
|
210
|
+
builder.canceled = true;
|
|
211
|
+
builder.error = e + '';
|
|
212
|
+
}
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (!builder.$sort && ((builder.$skip && builder.$skip >= builder.count) || (builder.$take && builder.$take <= builder.counter)))
|
|
217
|
+
continue;
|
|
218
|
+
|
|
219
|
+
builder.counter++;
|
|
220
|
+
builder.push(doc);
|
|
221
|
+
|
|
222
|
+
if (self.cancelable && !builder.$sort && !builder.$paginate && builder.response.length === builder.$take) {
|
|
223
|
+
builder.canceled = true;
|
|
224
|
+
self.canceled++;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
NoSQLReader.prototype.comparereverse = function(docs) {
|
|
232
|
+
|
|
233
|
+
var self = this;
|
|
234
|
+
|
|
235
|
+
self.total += docs.length;
|
|
236
|
+
|
|
237
|
+
for (var i = docs.length - 1; i > -1; i--) {
|
|
238
|
+
|
|
239
|
+
var doc = docs[i];
|
|
240
|
+
|
|
241
|
+
if (self.builders.length === self.canceled) {
|
|
242
|
+
self.total = 0;
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
for (var j = 0; j < self.builders.length; j++) {
|
|
247
|
+
|
|
248
|
+
var builder = self.builders[j];
|
|
249
|
+
if (builder.canceled)
|
|
250
|
+
continue;
|
|
251
|
+
|
|
252
|
+
builder.scanned++;
|
|
253
|
+
|
|
254
|
+
var is = false;
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
is = builder.filterrule(doc, builder.filterarg, builder.tmp, builder.func);
|
|
258
|
+
} catch (e) {
|
|
259
|
+
is = false;
|
|
260
|
+
builder.canceled = true;
|
|
261
|
+
builder.error = e + '';
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (is) {
|
|
265
|
+
|
|
266
|
+
builder.count++;
|
|
267
|
+
|
|
268
|
+
if (builder.scalarrule) {
|
|
269
|
+
builder.counter++;
|
|
270
|
+
try {
|
|
271
|
+
builder.scalarrule(doc, builder.scalararg, builder.tmp, builder.func);
|
|
272
|
+
} catch (e) {
|
|
273
|
+
builder.canceled = true;
|
|
274
|
+
builder.error = e + '';
|
|
275
|
+
}
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (!builder.$sort && ((builder.$skip && builder.$skip >= builder.count) || (builder.$take && builder.$take <= builder.counter)))
|
|
280
|
+
continue;
|
|
281
|
+
|
|
282
|
+
builder.counter++;
|
|
283
|
+
builder.push(doc);
|
|
284
|
+
|
|
285
|
+
if (self.cancelable && !builder.$sort && builder.response.length === builder.$take) {
|
|
286
|
+
builder.canceled = true;
|
|
287
|
+
self.canceled++;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
NoSQLReader.prototype.callback = function(builder) {
|
|
295
|
+
var self = this;
|
|
296
|
+
|
|
297
|
+
if (builder.$sort && !builder.$sorted)
|
|
298
|
+
sortfinal(builder);
|
|
299
|
+
|
|
300
|
+
if (builder.$sort && builder.$take2 && builder.response.length >= builder.$take)
|
|
301
|
+
builder.response = builder.$skip ? builder.response.splice(builder.$skip, builder.$take) : builder.response.splice(0, builder.$take);
|
|
302
|
+
|
|
303
|
+
for (var i = 0; i < builder.response.length; i++)
|
|
304
|
+
builder.response[i] = builder.prepare(builder.response[i]);
|
|
305
|
+
|
|
306
|
+
builder.logrule && builder.logrule();
|
|
307
|
+
builder.done();
|
|
308
|
+
return self;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
NoSQLReader.prototype.prepare = function() {
|
|
312
|
+
var self = this;
|
|
313
|
+
for (var i = 0; i < self.builders.length; i++) {
|
|
314
|
+
var builder = self.builders[i];
|
|
315
|
+
if (builder.$take)
|
|
316
|
+
builder.$take2 = builder.$sort ? ((builder.$skip || 1) + builder.$take) : builder.$take;
|
|
317
|
+
else
|
|
318
|
+
builder.$take2 = 0;
|
|
319
|
+
}
|
|
320
|
+
return self;
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
NoSQLReader.prototype.done = function() {
|
|
324
|
+
|
|
325
|
+
var self = this;
|
|
326
|
+
var diff = Date.now() - self.ts;
|
|
327
|
+
|
|
328
|
+
if (self.db && self.db.duration) {
|
|
329
|
+
if (self.total > 0)
|
|
330
|
+
self.db.total = self.total;
|
|
331
|
+
if (self.db.duration.push({ type: self.type, duration: diff }) > 20)
|
|
332
|
+
self.db.duration.shift();
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
for (var i = 0; i < self.builders.length; i++) {
|
|
336
|
+
var builder = self.builders[i];
|
|
337
|
+
builder.duration = diff;
|
|
338
|
+
builder.inmemory = self.inmemory;
|
|
339
|
+
self.callback(builder);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
self.diff = diff;
|
|
343
|
+
self.canceled = 0;
|
|
344
|
+
return self;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
function sortfinal(builder) {
|
|
348
|
+
builder.response.sort(builder.$sort);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
exports.make = function(builder) {
|
|
352
|
+
return new NoSQLReader(builder);
|
|
353
|
+
};
|