@based/db 0.0.66 → 0.0.67
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/README.md +2 -2
- package/dist/lib/darwin_aarch64/include/selva/colvec.h +71 -0
- package/dist/lib/darwin_aarch64/include/selva/db.h +3 -0
- package/dist/lib/darwin_aarch64/include/selva/fields.h +1 -1
- package/dist/lib/darwin_aarch64/include/selva/types.h +7 -0
- package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
- package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
- package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/colvec.h +71 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +3 -0
- package/dist/lib/linux_aarch64/include/selva/fields.h +1 -1
- package/dist/lib/linux_aarch64/include/selva/types.h +7 -0
- package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/selva/colvec.h +71 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +3 -0
- package/dist/lib/linux_x86_64/include/selva/fields.h +1 -1
- package/dist/lib/linux_x86_64/include/selva/types.h +7 -0
- package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/flushModify.d.ts +2 -1
- package/dist/src/client/flushModify.js +12 -4
- package/dist/src/client/modify/create.js +11 -0
- package/dist/src/client/modify/delete.js +3 -0
- package/dist/src/client/modify/modify.js +2 -2
- package/dist/src/client/modify/setCursor.d.ts +2 -1
- package/dist/src/client/query/BasedDbQuery.d.ts +7 -2
- package/dist/src/client/query/BasedDbQuery.js +111 -14
- package/dist/src/client/query/aggregates/aggregation.js +24 -11
- package/dist/src/client/query/aggregates/types.d.ts +21 -2
- package/dist/src/client/query/aggregates/types.js +34 -1
- package/dist/src/client/query/display.js +8 -2
- package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -3
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +20 -7
- package/dist/src/client/query/filter/filter.js +13 -3
- package/dist/src/client/query/filter/primitiveFilter.d.ts +1 -2
- package/dist/src/client/query/include/props.js +18 -2
- package/dist/src/client/query/include/toBuffer.js +11 -3
- package/dist/src/client/query/include/walk.js +5 -1
- package/dist/src/client/query/queryDef.js +4 -1
- package/dist/src/client/query/read/read.js +50 -23
- package/dist/src/client/query/registerQuery.js +1 -0
- package/dist/src/client/query/search/index.d.ts +1 -1
- package/dist/src/client/query/search/index.js +21 -7
- package/dist/src/client/query/sort.d.ts +1 -1
- package/dist/src/client/query/toByteCode/default.d.ts +1 -1
- package/dist/src/client/query/toByteCode/default.js +0 -2
- package/dist/src/client/query/toByteCode/toBuffer.js +0 -7
- package/dist/src/client/query/types.d.ts +16 -5
- package/dist/src/client/query/validation.js +25 -2
- package/dist/src/client/xxHash64.d.ts +1 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -1
- package/dist/src/native.d.ts +2 -2
- package/dist/src/native.js +7 -8
- package/dist/src/server/IoWorker.d.ts +8 -0
- package/dist/src/server/IoWorker.js +39 -0
- package/dist/src/server/QueryWorker.d.ts +8 -0
- package/dist/src/server/QueryWorker.js +26 -0
- package/dist/src/server/blocks.d.ts +24 -0
- package/dist/src/server/blocks.js +112 -0
- package/dist/src/server/dbHash.d.ts +1 -1
- package/dist/src/server/index.d.ts +9 -16
- package/dist/src/server/index.js +37 -15
- package/dist/src/server/migrate/index.d.ts +5 -0
- package/dist/src/server/migrate/index.js +10 -7
- package/dist/src/server/save.d.ts +8 -6
- package/dist/src/server/save.js +34 -78
- package/dist/src/server/schema.js +6 -5
- package/dist/src/server/start.js +57 -60
- package/dist/src/server/tree.d.ts +24 -13
- package/dist/src/server/tree.js +95 -66
- package/dist/src/server/workers/DbWorker.d.ts +17 -0
- package/dist/src/server/{DbWorker.js → workers/DbWorker.js} +15 -17
- package/dist/src/server/workers/io_worker.js +39 -0
- package/dist/src/server/workers/io_worker_types.d.ts +12 -0
- package/dist/src/server/workers/io_worker_types.js +2 -0
- package/dist/src/server/workers/query_worker.d.ts +1 -0
- package/dist/src/server/workers/query_worker.js +4 -0
- package/dist/src/server/workers/worker.d.ts +1 -0
- package/dist/src/server/workers/worker.js +41 -0
- package/dist/src/shared/Emitter.d.ts +1 -0
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.js +1 -1
- package/package.json +3 -3
- package/dist/lib/darwin_aarch64/include/selva/history.h +0 -64
- package/dist/lib/linux_aarch64/include/selva/history.h +0 -64
- package/dist/lib/linux_x86_64/include/selva/history.h +0 -64
- package/dist/src/client/query/serialize.d.ts +0 -4
- package/dist/src/client/query/serialize.js +0 -26
- package/dist/src/server/DbWorker.d.ts +0 -13
- package/dist/src/server/csmt/draw-dot.d.ts +0 -4
- package/dist/src/server/csmt/draw-dot.js +0 -38
- package/dist/src/server/csmt/index.d.ts +0 -4
- package/dist/src/server/csmt/index.js +0 -5
- package/dist/src/server/csmt/match.d.ts +0 -7
- package/dist/src/server/csmt/match.js +0 -10
- package/dist/src/server/csmt/memebership-proof.d.ts +0 -7
- package/dist/src/server/csmt/memebership-proof.js +0 -122
- package/dist/src/server/csmt/tree-utils.d.ts +0 -6
- package/dist/src/server/csmt/tree-utils.js +0 -33
- package/dist/src/server/csmt/tree.d.ts +0 -3
- package/dist/src/server/csmt/tree.js +0 -270
- package/dist/src/server/csmt/types.d.ts +0 -46
- package/dist/src/server/csmt/types.js +0 -2
- package/dist/src/server/worker.js +0 -33
- /package/dist/src/server/{worker.d.ts → workers/io_worker.d.ts} +0 -0
|
@@ -11,7 +11,7 @@ import { langCodesMap } from '@based/schema';
|
|
|
11
11
|
import { convertFilter } from './filter/convertFilter.js';
|
|
12
12
|
import { validateLocale, validateRange } from './validation.js';
|
|
13
13
|
import { DEF_RANGE_PROP_LIMIT } from './thresholds.js';
|
|
14
|
-
import {
|
|
14
|
+
import { AggregateType } from './aggregates/types.js';
|
|
15
15
|
import { displayTarget } from './display.js';
|
|
16
16
|
import picocolors from 'picocolors';
|
|
17
17
|
export class QueryBranch {
|
|
@@ -152,7 +152,7 @@ export class QueryBranch {
|
|
|
152
152
|
}
|
|
153
153
|
else {
|
|
154
154
|
const p = field.split('.');
|
|
155
|
-
addAggregate(
|
|
155
|
+
addAggregate(AggregateType.COUNT, this.def, p);
|
|
156
156
|
}
|
|
157
157
|
// @ts-ignore
|
|
158
158
|
return this;
|
|
@@ -168,7 +168,7 @@ export class QueryBranch {
|
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
170
|
else {
|
|
171
|
-
addAggregate(
|
|
171
|
+
addAggregate(AggregateType.SUM, this.def, fields);
|
|
172
172
|
}
|
|
173
173
|
// @ts-ignore
|
|
174
174
|
return this;
|
|
@@ -184,7 +184,87 @@ export class QueryBranch {
|
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
186
|
else {
|
|
187
|
-
addAggregate(
|
|
187
|
+
addAggregate(AggregateType.CARDINALITY, this.def, fields);
|
|
188
|
+
}
|
|
189
|
+
// @ts-ignore
|
|
190
|
+
return this;
|
|
191
|
+
}
|
|
192
|
+
stddev(...fields) {
|
|
193
|
+
if (fields.length === 0) {
|
|
194
|
+
throw new Error('Empty standard deviation function called');
|
|
195
|
+
}
|
|
196
|
+
if (this.queryCommands) {
|
|
197
|
+
this.queryCommands.push({
|
|
198
|
+
method: 'stddev',
|
|
199
|
+
args: fields,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
addAggregate(AggregateType.STDDEV, this.def, fields);
|
|
204
|
+
}
|
|
205
|
+
// @ts-ignore
|
|
206
|
+
return this;
|
|
207
|
+
}
|
|
208
|
+
var(...fields) {
|
|
209
|
+
if (fields.length === 0) {
|
|
210
|
+
throw new Error('Empty variance function called');
|
|
211
|
+
}
|
|
212
|
+
if (this.queryCommands) {
|
|
213
|
+
this.queryCommands.push({
|
|
214
|
+
method: 'var',
|
|
215
|
+
args: fields,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
addAggregate(AggregateType.VARIANCE, this.def, fields);
|
|
220
|
+
}
|
|
221
|
+
// @ts-ignore
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
avg(...fields) {
|
|
225
|
+
if (fields.length === 0) {
|
|
226
|
+
throw new Error('Empty average function called');
|
|
227
|
+
}
|
|
228
|
+
if (this.queryCommands) {
|
|
229
|
+
this.queryCommands.push({
|
|
230
|
+
method: 'avg',
|
|
231
|
+
args: fields,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
addAggregate(AggregateType.AVERAGE, this.def, fields);
|
|
236
|
+
}
|
|
237
|
+
// @ts-ignore
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
max(...fields) {
|
|
241
|
+
if (fields.length === 0) {
|
|
242
|
+
throw new Error('Empty maximum function called');
|
|
243
|
+
}
|
|
244
|
+
if (this.queryCommands) {
|
|
245
|
+
this.queryCommands.push({
|
|
246
|
+
method: 'max',
|
|
247
|
+
args: fields,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
addAggregate(AggregateType.MAX, this.def, fields);
|
|
252
|
+
}
|
|
253
|
+
// @ts-ignore
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
min(...fields) {
|
|
257
|
+
if (fields.length === 0) {
|
|
258
|
+
throw new Error('Empty minimum function called');
|
|
259
|
+
}
|
|
260
|
+
if (this.queryCommands) {
|
|
261
|
+
this.queryCommands.push({
|
|
262
|
+
method: 'min',
|
|
263
|
+
args: fields,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
addAggregate(AggregateType.MIN, this.def, fields);
|
|
188
268
|
}
|
|
189
269
|
// @ts-ignore
|
|
190
270
|
return this;
|
|
@@ -354,13 +434,19 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
354
434
|
const res = await this.db.hooks.getQueryBuf(buf);
|
|
355
435
|
if (res.byteLength === 1) {
|
|
356
436
|
if (res[0] === 0) {
|
|
357
|
-
this.
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
437
|
+
if (this.def && this.def.schemaChecksum === this.db.schema?.hash) {
|
|
438
|
+
// my schema did not change since last time, wait for the schema to change
|
|
439
|
+
this.reset();
|
|
440
|
+
this.db.emit('info', 'query get schema mismatch - awaiting new schema');
|
|
441
|
+
await this.db.once('schema');
|
|
442
|
+
return this.#getInternal(resolve, reject);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
// its changed so lets send again
|
|
446
|
+
this.db.emit('info', 'query get schema mismatch - got the same already');
|
|
447
|
+
this.reset();
|
|
448
|
+
return this.#getInternal(resolve, reject);
|
|
362
449
|
}
|
|
363
|
-
return this.#getInternal(resolve, reject);
|
|
364
450
|
}
|
|
365
451
|
else {
|
|
366
452
|
reject(new Error('unexpected error'));
|
|
@@ -382,16 +468,28 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
382
468
|
register() {
|
|
383
469
|
registerQuery(this);
|
|
384
470
|
}
|
|
385
|
-
locale(locale) {
|
|
471
|
+
locale(locale, fallBack) {
|
|
386
472
|
if (this.queryCommands) {
|
|
387
|
-
this.queryCommands.
|
|
473
|
+
this.queryCommands.unshift({
|
|
388
474
|
method: 'locale',
|
|
389
475
|
args: [locale],
|
|
390
476
|
});
|
|
391
477
|
}
|
|
392
478
|
else {
|
|
479
|
+
if (fallBack === undefined) {
|
|
480
|
+
// Uses fallback from schema if available
|
|
481
|
+
const localeDescriptor = this.def.schema.locales[locale];
|
|
482
|
+
fallBack =
|
|
483
|
+
typeof localeDescriptor === 'object'
|
|
484
|
+
? localeDescriptor.fallback || false
|
|
485
|
+
: false;
|
|
486
|
+
}
|
|
393
487
|
validateLocale(this.def, locale);
|
|
394
|
-
|
|
488
|
+
const fallBackCode = fallBack === false ? [] : [langCodesMap.get(fallBack)];
|
|
489
|
+
this.def.lang = {
|
|
490
|
+
lang: langCodesMap.get(locale) ?? 0,
|
|
491
|
+
fallback: fallBackCode,
|
|
492
|
+
};
|
|
395
493
|
}
|
|
396
494
|
return this;
|
|
397
495
|
}
|
|
@@ -401,7 +499,6 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
401
499
|
onData(res);
|
|
402
500
|
}
|
|
403
501
|
catch (err) {
|
|
404
|
-
// const t = displayTarget(this.def)
|
|
405
502
|
const def = this.def;
|
|
406
503
|
let name = picocolors.red(`QueryError[${displayTarget(def)}]\n`);
|
|
407
504
|
name += ` Error executing onData handler in subscription\n`;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { writeUint16 } from '@saulx/utils';
|
|
2
2
|
import { QueryDefType } from '../types.js';
|
|
3
|
+
import { AggregateType } from './types.js';
|
|
3
4
|
import { UINT32 } from '@based/schema/def';
|
|
4
5
|
import { aggregationFieldDoesNotExist } from '../validation.js';
|
|
6
|
+
import { aggregateTypeMap } from '../aggregates/types.js';
|
|
5
7
|
export const aggregateToBuffer = (aggregates) => {
|
|
6
8
|
const aggBuffer = new Uint8Array(aggregates.size);
|
|
7
9
|
let i = 0;
|
|
@@ -21,7 +23,9 @@ export const aggregateToBuffer = (aggregates) => {
|
|
|
21
23
|
aggBuffer[i] = 0 /* GroupBy.NONE */;
|
|
22
24
|
i += 1;
|
|
23
25
|
}
|
|
24
|
-
writeUint16(aggBuffer, aggregates.
|
|
26
|
+
writeUint16(aggBuffer, aggregates.totalResultsSize, i);
|
|
27
|
+
i += 2;
|
|
28
|
+
writeUint16(aggBuffer, aggregates.totalAccumulatorSize, i);
|
|
25
29
|
i += 2;
|
|
26
30
|
for (const [prop, aggregatesArray] of aggregates.aggregates.entries()) {
|
|
27
31
|
aggBuffer[i] = prop;
|
|
@@ -39,6 +43,8 @@ export const aggregateToBuffer = (aggregates) => {
|
|
|
39
43
|
i += 2;
|
|
40
44
|
writeUint16(aggBuffer, agg.resultPos, i);
|
|
41
45
|
i += 2;
|
|
46
|
+
writeUint16(aggBuffer, agg.accumulatorPos, i);
|
|
47
|
+
i += 2;
|
|
42
48
|
size += i - startI;
|
|
43
49
|
}
|
|
44
50
|
writeUint16(aggBuffer, size, sizeIndex);
|
|
@@ -48,13 +54,13 @@ export const aggregateToBuffer = (aggregates) => {
|
|
|
48
54
|
const ensureAggregate = (def) => {
|
|
49
55
|
if (!def.aggregate) {
|
|
50
56
|
def.aggregate = {
|
|
51
|
-
size:
|
|
57
|
+
size: 5,
|
|
52
58
|
aggregates: new Map(),
|
|
53
|
-
|
|
59
|
+
totalResultsSize: 0,
|
|
60
|
+
totalAccumulatorSize: 0,
|
|
54
61
|
};
|
|
55
62
|
}
|
|
56
63
|
};
|
|
57
|
-
// Group by is great for normal stuff as well (do later)
|
|
58
64
|
export const groupBy = (def, field) => {
|
|
59
65
|
const fieldDef = def.schema.props[field];
|
|
60
66
|
if (!fieldDef) {
|
|
@@ -74,7 +80,7 @@ export const addAggregate = (type, def, fields) => {
|
|
|
74
80
|
addAggregate(type, def, field);
|
|
75
81
|
}
|
|
76
82
|
else {
|
|
77
|
-
const fieldDef = type ===
|
|
83
|
+
const fieldDef = type === AggregateType.COUNT
|
|
78
84
|
? {
|
|
79
85
|
prop: 255,
|
|
80
86
|
path: [field],
|
|
@@ -98,13 +104,20 @@ export const addAggregate = (type, def, fields) => {
|
|
|
98
104
|
aggregateField.push({
|
|
99
105
|
propDef: fieldDef,
|
|
100
106
|
type,
|
|
101
|
-
resultPos: def.aggregate.
|
|
107
|
+
resultPos: def.aggregate.totalResultsSize,
|
|
108
|
+
accumulatorPos: def.aggregate.totalAccumulatorSize,
|
|
102
109
|
});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
const specificSizes = aggregateTypeMap.get(type);
|
|
111
|
+
if (specificSizes) {
|
|
112
|
+
def.aggregate.totalResultsSize += specificSizes.resultsSize;
|
|
113
|
+
def.aggregate.totalAccumulatorSize += specificSizes.accumulatorSize;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
def.aggregate.totalResultsSize += 8;
|
|
117
|
+
def.aggregate.totalAccumulatorSize += 8;
|
|
118
|
+
}
|
|
106
119
|
// needs to add an extra field WRITE TO
|
|
107
|
-
def.aggregate.size +=
|
|
120
|
+
def.aggregate.size += 8;
|
|
108
121
|
}
|
|
109
122
|
}
|
|
110
123
|
};
|
|
@@ -128,7 +141,7 @@ export const isRootCountOnly = (def, filterSize) => {
|
|
|
128
141
|
if (aggs.length !== 1) {
|
|
129
142
|
return false;
|
|
130
143
|
}
|
|
131
|
-
if (aggs[0].type !==
|
|
144
|
+
if (aggs[0].type !== AggregateType.COUNT) {
|
|
132
145
|
return false;
|
|
133
146
|
}
|
|
134
147
|
if (def.filter && def.filter.size > 0) {
|
|
@@ -1,8 +1,27 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare enum AggregateType {
|
|
2
2
|
SUM = 1,
|
|
3
3
|
COUNT = 2,
|
|
4
|
-
CARDINALITY = 3
|
|
4
|
+
CARDINALITY = 3,
|
|
5
|
+
STDDEV = 4,
|
|
6
|
+
AVERAGE = 5,
|
|
7
|
+
VARIANCE = 6,
|
|
8
|
+
MAX = 7,
|
|
9
|
+
MIN = 8
|
|
5
10
|
}
|
|
11
|
+
export declare const enum AccumulatorSize {
|
|
12
|
+
SUM = 8,
|
|
13
|
+
COUNT = 4,
|
|
14
|
+
CARDINALITY = 254,// TODO: accordinly to sparse or dense modes
|
|
15
|
+
STDDEV = 24,// count (u64) + sum (f64) + sum_sq (f64) = 8 + 8 + 8 = 24
|
|
16
|
+
AVERAGE = 16,// count (u64) + sum (f64) = 16
|
|
17
|
+
VARIANCE = 24,// count (u64) + sum (f64) + sum_sq (f64) = 8 + 8 + 8 = 24
|
|
18
|
+
MAX = 8,
|
|
19
|
+
MIN = 8
|
|
20
|
+
}
|
|
21
|
+
export declare const aggregateTypeMap: Map<AggregateType, {
|
|
22
|
+
resultsSize: number;
|
|
23
|
+
accumulatorSize: number;
|
|
24
|
+
}>;
|
|
6
25
|
export declare const enum GroupBy {
|
|
7
26
|
NONE = 0,
|
|
8
27
|
HAS_GROUP = 255
|
|
@@ -1,2 +1,35 @@
|
|
|
1
|
-
export
|
|
1
|
+
export var AggregateType;
|
|
2
|
+
(function (AggregateType) {
|
|
3
|
+
AggregateType[AggregateType["SUM"] = 1] = "SUM";
|
|
4
|
+
AggregateType[AggregateType["COUNT"] = 2] = "COUNT";
|
|
5
|
+
AggregateType[AggregateType["CARDINALITY"] = 3] = "CARDINALITY";
|
|
6
|
+
AggregateType[AggregateType["STDDEV"] = 4] = "STDDEV";
|
|
7
|
+
AggregateType[AggregateType["AVERAGE"] = 5] = "AVERAGE";
|
|
8
|
+
AggregateType[AggregateType["VARIANCE"] = 6] = "VARIANCE";
|
|
9
|
+
AggregateType[AggregateType["MAX"] = 7] = "MAX";
|
|
10
|
+
AggregateType[AggregateType["MIN"] = 8] = "MIN";
|
|
11
|
+
})(AggregateType || (AggregateType = {}));
|
|
12
|
+
export const aggregateTypeMap = new Map([
|
|
13
|
+
[
|
|
14
|
+
AggregateType.CARDINALITY,
|
|
15
|
+
{ resultsSize: 4, accumulatorSize: 254 /* AccumulatorSize.CARDINALITY */ },
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
AggregateType.COUNT,
|
|
19
|
+
{ resultsSize: 4, accumulatorSize: 4 /* AccumulatorSize.COUNT */ },
|
|
20
|
+
],
|
|
21
|
+
[
|
|
22
|
+
AggregateType.STDDEV,
|
|
23
|
+
{ resultsSize: 8, accumulatorSize: 24 /* AccumulatorSize.STDDEV */ },
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
AggregateType.AVERAGE,
|
|
27
|
+
{ resultsSize: 8, accumulatorSize: 16 /* AccumulatorSize.AVERAGE */ },
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
AggregateType.VARIANCE,
|
|
31
|
+
{ resultsSize: 8, accumulatorSize: 24 /* AccumulatorSize.VARIANCE */ },
|
|
32
|
+
],
|
|
33
|
+
// Othe types like MAX, MIN, SUM fall in the else case in aggregation.ts 8/8
|
|
34
|
+
]);
|
|
2
35
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import picocolors from 'picocolors';
|
|
2
2
|
import { BINARY, CARDINALITY, NUMBER, REFERENCE, REFERENCES, STRING, TEXT, TIMESTAMP, } from '@based/schema/def';
|
|
3
3
|
import { ENCODER } from '@saulx/utils';
|
|
4
|
+
import { AggregateType } from './aggregates/types.js';
|
|
4
5
|
const decimals = (v) => ~~(v * 100) / 100;
|
|
5
6
|
const sizeCalc = (size) => {
|
|
6
7
|
if (size > 1e6) {
|
|
@@ -158,7 +159,10 @@ const inspectObject = (object, q, path, level, isLast, isFirst, isObject, depth)
|
|
|
158
159
|
if (typeof v === 'number') {
|
|
159
160
|
if (q.aggregate) {
|
|
160
161
|
str += printNumber(v);
|
|
161
|
-
|
|
162
|
+
// TBD: replace comptime const enum and reverse map it
|
|
163
|
+
const [[__, akv], _] = q.aggregate.aggregates;
|
|
164
|
+
const aggType = akv[0].type;
|
|
165
|
+
str += picocolors.italic(picocolors.dim(` ${AggregateType[aggType].toLowerCase()}`));
|
|
162
166
|
str += ',\n';
|
|
163
167
|
}
|
|
164
168
|
else {
|
|
@@ -219,7 +223,9 @@ const inspectObject = (object, q, path, level, isLast, isFirst, isObject, depth)
|
|
|
219
223
|
if (typeof v === 'number') {
|
|
220
224
|
if (q.aggregate) {
|
|
221
225
|
str += printNumber(v);
|
|
222
|
-
|
|
226
|
+
const [[__, akv], _] = q.aggregate.aggregates;
|
|
227
|
+
const aggType = akv[0].type;
|
|
228
|
+
str += picocolors.italic(picocolors.dim(` ${AggregateType[aggType].toLowerCase()}`));
|
|
223
229
|
}
|
|
224
230
|
else {
|
|
225
231
|
str += printNumber(v);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PropDef, PropDefEdge } from '@based/schema/def';
|
|
2
2
|
import { FilterCtx } from './types.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export declare const createVariableFilterBuffer: (value: any, prop: PropDef | PropDefEdge, ctx: FilterCtx, lang: LangCode) => FilterCondition;
|
|
3
|
+
import { FilterCondition, QueryDef } from '../types.js';
|
|
4
|
+
export declare const createVariableFilterBuffer: (value: any, prop: PropDef | PropDefEdge, ctx: FilterCtx, lang: QueryDef["lang"]) => FilterCondition;
|
|
@@ -33,9 +33,15 @@ const parseValue = (value, prop, ctx, lang) => {
|
|
|
33
33
|
val = ENCODER.encode(val.normalize('NFKD'));
|
|
34
34
|
}
|
|
35
35
|
if (prop.typeIndex === TEXT) {
|
|
36
|
-
|
|
36
|
+
// 1 + size
|
|
37
|
+
const fallbacksSize = lang.lang === 0 ? 0 : lang.fallback.length;
|
|
38
|
+
const tmp = new Uint8Array(val.byteLength + 2 + fallbacksSize);
|
|
37
39
|
tmp.set(val);
|
|
38
|
-
tmp[tmp.byteLength - 1] =
|
|
40
|
+
tmp[tmp.byteLength - 1] = fallbacksSize;
|
|
41
|
+
tmp[tmp.byteLength - 2] = lang.lang;
|
|
42
|
+
for (let i = 0; i < fallbacksSize; i++) {
|
|
43
|
+
tmp[tmp.byteLength - 2 - fallbacksSize + i] = lang.fallback[i];
|
|
44
|
+
}
|
|
39
45
|
val = tmp;
|
|
40
46
|
}
|
|
41
47
|
}
|
|
@@ -90,9 +96,10 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
|
90
96
|
prop.typeIndex !== ALIAS &&
|
|
91
97
|
prop.typeIndex !== VECTOR) {
|
|
92
98
|
if (prop.typeIndex === TEXT) {
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
99
|
+
const fbLen = 2 + val[val.byteLength - 1];
|
|
100
|
+
const crc = crc32(val.slice(0, -fbLen));
|
|
101
|
+
const len = val.byteLength - fbLen;
|
|
102
|
+
const v = new Uint8Array(8 + fbLen);
|
|
96
103
|
v[0] = crc;
|
|
97
104
|
v[1] = crc >>> 8;
|
|
98
105
|
v[2] = crc >>> 16;
|
|
@@ -101,11 +108,17 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
|
101
108
|
v[5] = len >>> 8;
|
|
102
109
|
v[6] = len >>> 16;
|
|
103
110
|
v[7] = len >>> 24;
|
|
104
|
-
|
|
111
|
+
for (let i = 0; i < fbLen; i++) {
|
|
112
|
+
v[v.byteLength - (i + 1)] = val[val.byteLength - (i + 1)];
|
|
113
|
+
}
|
|
105
114
|
parsedCondition = writeVarFilter(mode, v, ctx, prop, 0, 0);
|
|
106
115
|
}
|
|
107
116
|
else {
|
|
108
|
-
parsedCondition = createFixedFilterBuffer(prop, 8, {
|
|
117
|
+
parsedCondition = createFixedFilterBuffer(prop, 8, {
|
|
118
|
+
operation: EQUAL_CRC32,
|
|
119
|
+
type: ctx.type,
|
|
120
|
+
opts: ctx.opts,
|
|
121
|
+
}, val, false);
|
|
109
122
|
}
|
|
110
123
|
}
|
|
111
124
|
else {
|
|
@@ -22,7 +22,11 @@ const referencesFilter = (db, filter, schema, conditions, def) => {
|
|
|
22
22
|
if (edgeDef) {
|
|
23
23
|
conditions.edges ??= new Map();
|
|
24
24
|
size +=
|
|
25
|
-
3 +
|
|
25
|
+
3 +
|
|
26
|
+
primitiveFilter(def, edgeDef, filter, conditions, {
|
|
27
|
+
lang: def.lang.lang,
|
|
28
|
+
fallback: [],
|
|
29
|
+
});
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
}
|
|
@@ -71,12 +75,18 @@ export const filterRaw = (db, filter, schema, conditions, def) => {
|
|
|
71
75
|
filterInvalidLang(def, field);
|
|
72
76
|
return 0;
|
|
73
77
|
}
|
|
74
|
-
return primitiveFilter(def, fieldDef, filter, conditions,
|
|
78
|
+
return primitiveFilter(def, fieldDef, filter, conditions, {
|
|
79
|
+
lang: code,
|
|
80
|
+
fallback: [],
|
|
81
|
+
});
|
|
75
82
|
}
|
|
76
83
|
}
|
|
77
84
|
if (field === 'id') {
|
|
78
85
|
fieldDef = ID_FIELD_DEF;
|
|
79
|
-
return primitiveFilter(def, fieldDef, filter, conditions,
|
|
86
|
+
return primitiveFilter(def, fieldDef, filter, conditions, {
|
|
87
|
+
lang: def.lang.lang,
|
|
88
|
+
fallback: [], // only fallbacks for this
|
|
89
|
+
});
|
|
80
90
|
}
|
|
81
91
|
return referencesFilter(db, filter, schema, conditions, def);
|
|
82
92
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PropDef, PropDefEdge } from '@based/schema/def';
|
|
2
2
|
import { QueryDef, QueryDefFilter } from '../types.js';
|
|
3
3
|
import { Filter } from './types.js';
|
|
4
|
-
|
|
5
|
-
export declare const primitiveFilter: (def: QueryDef, prop: PropDef | PropDefEdge, filter: Filter, conditions: QueryDefFilter, lang: LangCode) => number;
|
|
4
|
+
export declare const primitiveFilter: (def: QueryDef, prop: PropDef | PropDefEdge, filter: Filter, conditions: QueryDefFilter, lang: QueryDef["lang"]) => number;
|
|
@@ -69,9 +69,25 @@ export const includeProp = (def, prop) => {
|
|
|
69
69
|
}
|
|
70
70
|
if (prop.typeIndex === TEXT) {
|
|
71
71
|
if (!def.include.langTextFields.has(prop.prop)) {
|
|
72
|
-
def.include.langTextFields.set(prop.prop, {
|
|
72
|
+
def.include.langTextFields.set(prop.prop, {
|
|
73
|
+
def: prop,
|
|
74
|
+
codes: new Set(),
|
|
75
|
+
fallBacks: [],
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const langs = def.include.langTextFields.get(prop.prop);
|
|
79
|
+
if (def.lang.fallback.length > 0) {
|
|
80
|
+
for (const fallback of def.lang.fallback) {
|
|
81
|
+
if (!langs.fallBacks.includes(fallback)) {
|
|
82
|
+
langs.fallBacks.push(fallback);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const langCode = def.lang.lang ?? 0;
|
|
87
|
+
langs.codes.add(langCode);
|
|
88
|
+
if (langCode === 0 || langs.codes.size > 1) {
|
|
89
|
+
langs.fallBacks = [];
|
|
73
90
|
}
|
|
74
|
-
def.include.langTextFields.get(prop.prop).codes.add(def.lang ?? 0);
|
|
75
91
|
}
|
|
76
92
|
else {
|
|
77
93
|
if (prop.separate) {
|
|
@@ -56,21 +56,29 @@ export const includeToBuffer = (db, def) => {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
if (def.include.langTextFields.size) {
|
|
59
|
-
for (const [prop, { codes, def: propDef },] of def.include.langTextFields.entries()) {
|
|
59
|
+
for (const [prop, { codes, def: propDef, fallBacks },] of def.include.langTextFields.entries()) {
|
|
60
60
|
def.include.propsRead[prop] = 0;
|
|
61
61
|
if (codes.has(0)) {
|
|
62
|
-
const b = new Uint8Array(
|
|
62
|
+
const b = new Uint8Array(4);
|
|
63
63
|
b[0] = prop;
|
|
64
64
|
b[1] = propDef.typeIndex;
|
|
65
65
|
b[2] = 0;
|
|
66
|
+
b[3] = 0;
|
|
66
67
|
result.push(b);
|
|
67
68
|
}
|
|
68
69
|
else {
|
|
69
70
|
for (const code of codes) {
|
|
70
|
-
const
|
|
71
|
+
const fallBackSize = fallBacks.length;
|
|
72
|
+
const b = new Uint8Array(4 + fallBackSize);
|
|
71
73
|
b[0] = prop;
|
|
72
74
|
b[1] = propDef.typeIndex;
|
|
73
75
|
b[2] = code;
|
|
76
|
+
b[3] = fallBackSize;
|
|
77
|
+
let i = 0;
|
|
78
|
+
for (const fallback of fallBacks) {
|
|
79
|
+
b[i + 4] = fallback;
|
|
80
|
+
i++;
|
|
81
|
+
}
|
|
74
82
|
result.push(b);
|
|
75
83
|
}
|
|
76
84
|
}
|
|
@@ -55,7 +55,11 @@ export const walkDefs = (db, def, f) => {
|
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
if (!def.include.langTextFields.has(t.prop)) {
|
|
58
|
-
def.include.langTextFields.set(t.prop, {
|
|
58
|
+
def.include.langTextFields.set(t.prop, {
|
|
59
|
+
def: t,
|
|
60
|
+
codes: new Set(),
|
|
61
|
+
fallBacks: [],
|
|
62
|
+
});
|
|
59
63
|
}
|
|
60
64
|
def.include.langTextFields.get(t.prop).codes.add(langCode);
|
|
61
65
|
return;
|
|
@@ -8,7 +8,10 @@ const createEmptySharedDef = (skipValidation) => {
|
|
|
8
8
|
skipValidation,
|
|
9
9
|
filter: { conditions: new Map(), size: 0 },
|
|
10
10
|
range: { offset: 0, limit: 0 },
|
|
11
|
-
lang:
|
|
11
|
+
lang: {
|
|
12
|
+
lang: langCodesMap.get('none'),
|
|
13
|
+
fallback: [],
|
|
14
|
+
},
|
|
12
15
|
include: {
|
|
13
16
|
langTextFields: new Map(),
|
|
14
17
|
stringFields: new Set(),
|