@based/db 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/darwin_aarch64/include/cdefs.h +4 -0
- package/dist/lib/darwin_aarch64/include/selva/db.h +25 -5
- package/dist/lib/darwin_aarch64/include/selva/fields.h +34 -72
- package/dist/lib/darwin_aarch64/include/selva/selva_lang.h +7 -0
- package/dist/lib/darwin_aarch64/include/selva/types.h +9 -13
- 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-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/libnode-v25.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/include/cdefs.h +4 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +25 -5
- package/dist/lib/linux_aarch64/include/selva/fields.h +34 -72
- package/dist/lib/linux_aarch64/include/selva/selva_lang.h +7 -0
- package/dist/lib/linux_aarch64/include/selva/types.h +9 -13
- package/dist/lib/linux_aarch64/libdeflate.so +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/libnode-v25.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/cdefs.h +4 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +25 -5
- package/dist/lib/linux_x86_64/include/selva/fields.h +34 -72
- package/dist/lib/linux_x86_64/include/selva/selva_lang.h +7 -0
- package/dist/lib/linux_x86_64/include/selva/types.h +9 -13
- package/dist/lib/linux_x86_64/libdeflate.so +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/libnode-v25.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/modify/Tmp.d.ts +0 -1
- package/dist/src/client/modify/Tmp.js +14 -9
- package/dist/src/client/modify/create/index.js +6 -5
- package/dist/src/client/modify/drain.js +6 -2
- package/dist/src/client/modify/edges/binary.js +3 -2
- package/dist/src/client/modify/edges/reference.js +2 -3
- package/dist/src/client/modify/edges/references.js +2 -3
- package/dist/src/client/modify/edges/separate.js +4 -1
- package/dist/src/client/modify/edges/string.js +2 -3
- package/dist/src/client/modify/error.d.ts +29 -0
- package/dist/src/client/modify/error.js +10 -0
- package/dist/src/client/modify/props/alias.js +1 -1
- package/dist/src/client/modify/props/binary.js +1 -1
- package/dist/src/client/modify/props/cardinality.js +1 -1
- package/dist/src/client/modify/props/fixed.js +13 -14
- package/dist/src/client/modify/props/reference.js +2 -2
- package/dist/src/client/modify/props/references.js +7 -7
- package/dist/src/client/modify/props/string.js +1 -1
- package/dist/src/client/modify/props/vector.js +1 -11
- package/dist/src/client/modify/types.d.ts +1 -0
- package/dist/src/client/modify/types.js +1 -0
- package/dist/src/client/modify/validate.d.ts +1 -1
- package/dist/src/client/modify/validate.js +4 -3
- package/dist/src/client/query/BasedDbQuery.d.ts +4 -4
- package/dist/src/client/query/BasedDbQuery.js +23 -12
- package/dist/src/client/query/BasedQueryResponse.d.ts +0 -1
- package/dist/src/client/query/BasedQueryResponse.js +0 -3
- package/dist/src/client/query/aggregates/aggregation.d.ts +1 -1
- package/dist/src/client/query/aggregates/aggregation.js +123 -51
- package/dist/src/client/query/display.js +14 -8
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +59 -22
- package/dist/src/client/query/filter/createReferenceFilter.js +13 -13
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +6 -3
- package/dist/src/client/query/filter/filter.js +8 -0
- package/dist/src/client/query/filter/primitiveFilter.js +4 -1
- package/dist/src/client/query/filter/{toBuffer.d.ts → toByteCode.d.ts} +3 -2
- package/dist/src/client/query/filter/{toBuffer.js → toByteCode.js} +46 -12
- package/dist/src/client/query/filter/types.d.ts +1 -0
- package/dist/src/client/query/filter/types.js +33 -5
- package/dist/src/client/query/include/toByteCode.d.ts +2 -2
- package/dist/src/client/query/include/toByteCode.js +1 -1
- package/dist/src/client/query/query.d.ts +1 -1
- package/dist/src/client/query/query.js +1 -1
- package/dist/src/client/query/queryDef.js +6 -2
- package/dist/src/client/query/registerQuery.js +5 -9
- package/dist/src/client/query/subscription/index.js +5 -0
- package/dist/src/client/query/subscription/toByteCode.d.ts +6 -0
- package/dist/src/client/query/subscription/toByteCode.js +139 -0
- package/dist/src/client/query/subscription/types.d.ts +6 -0
- package/dist/src/client/query/subscription/types.js +7 -9
- package/dist/src/client/query/toByteCode/aggregates.d.ts +2 -0
- package/dist/src/client/query/toByteCode/aggregates.js +60 -0
- package/dist/src/client/query/toByteCode/alias.d.ts +2 -0
- package/dist/src/client/query/toByteCode/alias.js +24 -0
- package/dist/src/client/query/toByteCode/default.d.ts +2 -2
- package/dist/src/client/query/toByteCode/default.js +21 -24
- package/dist/src/client/query/toByteCode/id.d.ts +2 -0
- package/dist/src/client/query/toByteCode/id.js +17 -0
- package/dist/src/client/query/toByteCode/ids.d.ts +2 -0
- package/dist/src/client/query/toByteCode/ids.js +52 -0
- package/dist/src/client/query/toByteCode/offsets.d.ts +35 -0
- package/dist/src/client/query/toByteCode/offsets.js +36 -0
- package/dist/src/client/query/toByteCode/reference.d.ts +2 -0
- package/dist/src/client/query/toByteCode/reference.js +12 -0
- package/dist/src/client/query/toByteCode/references.d.ts +2 -0
- package/dist/src/client/query/toByteCode/references.js +35 -0
- package/dist/src/client/query/toByteCode/toByteCode.d.ts +4 -2
- package/dist/src/client/query/toByteCode/toByteCode.js +62 -189
- package/dist/src/client/query/types.d.ts +24 -5
- package/dist/src/client/query/validation.d.ts +5 -1
- package/dist/src/client/query/validation.js +15 -3
- package/dist/src/client/string.js +1 -1
- package/dist/src/hooks.js +2 -29
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/native.d.ts +8 -1
- package/dist/src/native.js +23 -2
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/server/index.js +11 -2
- package/dist/src/server/schema.js +3 -2
- package/dist/src/server/schemaSelvaBuffer.d.ts +4 -0
- package/dist/src/server/schemaSelvaBuffer.js +182 -0
- package/dist/src/server/subscription.d.ts +32 -0
- package/dist/src/server/subscription.js +275 -0
- package/dist/src/utils.js +2 -3
- package/package.json +5 -6
|
@@ -63,4 +63,14 @@ export const handleError = (db, ctx, fn, args, e) => {
|
|
|
63
63
|
}
|
|
64
64
|
throw e;
|
|
65
65
|
};
|
|
66
|
+
export const errors = {
|
|
67
|
+
NotExists: class extends Error {
|
|
68
|
+
constructor(id, schema) {
|
|
69
|
+
super(`Target ${schema.type}:${id} does not exist`);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
export const errorMap = {
|
|
74
|
+
1: errors.NotExists,
|
|
75
|
+
};
|
|
66
76
|
//# sourceMappingURL=error.js.map
|
|
@@ -10,7 +10,7 @@ import { writeBinary } from './binary.js';
|
|
|
10
10
|
export const writeCardinalityRaw = (ctx, def, val, sizeFixBecauseEdgeIsDifferent = val.length) => {
|
|
11
11
|
writeU32(ctx, sizeFixBecauseEdgeIsDifferent);
|
|
12
12
|
for (const item of val) {
|
|
13
|
-
validate(
|
|
13
|
+
validate(item, def);
|
|
14
14
|
if (typeof item === 'string') {
|
|
15
15
|
xxHash64(ENCODER.encode(item), ctx.array, ctx.index);
|
|
16
16
|
ctx.index += 8;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TIMESTAMP, UINT16, UINT32, UINT8, } from '@based/schema/def';
|
|
2
|
-
import { convertToTimestamp, ENCODER } from '@based/utils';
|
|
2
|
+
import { convertToTimestamp, ENCODER, writeDoubleLE } from '@based/utils';
|
|
3
3
|
import { getBuffer } from './binary.js';
|
|
4
4
|
import { reserve } from '../resize.js';
|
|
5
5
|
import { writeU16, writeU32, writeU64, writeU8, writeU8Array } from '../uint.js';
|
|
@@ -7,7 +7,7 @@ import { validate } from '../validate.js';
|
|
|
7
7
|
const map = {};
|
|
8
8
|
map[BINARY] = (ctx, val, def) => {
|
|
9
9
|
val = getBuffer(val);
|
|
10
|
-
validate(
|
|
10
|
+
validate(val, def);
|
|
11
11
|
reserve(ctx, val.byteLength + 1);
|
|
12
12
|
writeU8(ctx, val.byteLength);
|
|
13
13
|
writeU8Array(ctx, val);
|
|
@@ -18,7 +18,7 @@ map[STRING] = (ctx, val, def) => {
|
|
|
18
18
|
if (size + 1 > def.len) {
|
|
19
19
|
throw [def, val, `max length of ${def.len - 1},`];
|
|
20
20
|
}
|
|
21
|
-
validate(
|
|
21
|
+
validate(val, def);
|
|
22
22
|
reserve(ctx, size + 1);
|
|
23
23
|
const fullSize = def.len - 1;
|
|
24
24
|
ctx.array[ctx.index] = size;
|
|
@@ -30,12 +30,12 @@ map[STRING] = (ctx, val, def) => {
|
|
|
30
30
|
};
|
|
31
31
|
map[BOOLEAN] = (ctx, val, def) => {
|
|
32
32
|
val ??= def.default;
|
|
33
|
-
validate(
|
|
33
|
+
validate(val, def);
|
|
34
34
|
reserve(ctx, 1);
|
|
35
35
|
writeU8(ctx, val ? 1 : 0);
|
|
36
36
|
};
|
|
37
37
|
map[ENUM] = (ctx, val, def) => {
|
|
38
|
-
validate(
|
|
38
|
+
validate(val, def);
|
|
39
39
|
if (val === null) {
|
|
40
40
|
reserve(ctx, 1);
|
|
41
41
|
writeU8(ctx, def.default);
|
|
@@ -50,46 +50,45 @@ map[ENUM] = (ctx, val, def) => {
|
|
|
50
50
|
};
|
|
51
51
|
map[NUMBER] = (ctx, val, def) => {
|
|
52
52
|
val ??= def.default;
|
|
53
|
-
validate(
|
|
54
|
-
const view = new DataView(ctx.array.buffer, ctx.array.byteOffset + ctx.index, 8);
|
|
53
|
+
validate(val, def);
|
|
55
54
|
reserve(ctx, 8);
|
|
56
|
-
|
|
55
|
+
writeDoubleLE(ctx.array, val, ctx.array.byteOffset + ctx.index);
|
|
57
56
|
ctx.index += 8;
|
|
58
57
|
};
|
|
59
58
|
map[TIMESTAMP] = (ctx, val, def) => {
|
|
60
59
|
val ??= def.default;
|
|
61
60
|
const parsedValue = convertToTimestamp(val);
|
|
62
|
-
validate(
|
|
61
|
+
validate(parsedValue, def);
|
|
63
62
|
reserve(ctx, 8);
|
|
64
63
|
writeU64(ctx, parsedValue);
|
|
65
64
|
};
|
|
66
65
|
map[UINT32] = (ctx, val, def) => {
|
|
67
66
|
val ??= def.default;
|
|
68
|
-
validate(
|
|
67
|
+
validate(val, def);
|
|
69
68
|
reserve(ctx, 4);
|
|
70
69
|
writeU32(ctx, val);
|
|
71
70
|
};
|
|
72
71
|
map[UINT16] = (ctx, val, def) => {
|
|
73
72
|
val ??= def.default;
|
|
74
|
-
validate(
|
|
73
|
+
validate(val, def);
|
|
75
74
|
reserve(ctx, 2);
|
|
76
75
|
writeU16(ctx, val);
|
|
77
76
|
};
|
|
78
77
|
map[UINT8] = map[INT8] = (ctx, val, def) => {
|
|
79
78
|
val ??= def.default;
|
|
80
|
-
validate(
|
|
79
|
+
validate(val, def);
|
|
81
80
|
reserve(ctx, 1);
|
|
82
81
|
writeU8(ctx, val);
|
|
83
82
|
};
|
|
84
83
|
map[INT32] = (ctx, val, def) => {
|
|
85
84
|
val ??= def.default;
|
|
86
|
-
validate(
|
|
85
|
+
validate(val, def);
|
|
87
86
|
reserve(ctx, 4);
|
|
88
87
|
writeU32(ctx, val);
|
|
89
88
|
};
|
|
90
89
|
map[INT16] = (ctx, val, def) => {
|
|
91
90
|
val ??= def.default;
|
|
92
|
-
validate(
|
|
91
|
+
validate(val, def);
|
|
93
92
|
reserve(ctx, 2);
|
|
94
93
|
writeU16(ctx, val);
|
|
95
94
|
};
|
|
@@ -19,7 +19,7 @@ export const writeReference = (ctx, def, val) => {
|
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
if (typeof val === 'number') {
|
|
22
|
-
validate(
|
|
22
|
+
validate(val, def);
|
|
23
23
|
if (def.hasDefaultEdges) {
|
|
24
24
|
writeReferenceId(ctx, def, val, EDGE_NOINDEX_REALID);
|
|
25
25
|
writeEdges(ctx, def, {}, true);
|
|
@@ -44,7 +44,7 @@ export const writeReference = (ctx, def, val) => {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
if (typeof val.id === 'number') {
|
|
47
|
-
validate(
|
|
47
|
+
validate(val.id, def);
|
|
48
48
|
if (!def.edges || val instanceof Tmp || val instanceof Promise) {
|
|
49
49
|
writeReferenceId(ctx, def, val.id, NOEDGE_NOINDEX_REALID);
|
|
50
50
|
}
|
|
@@ -41,7 +41,7 @@ const putReferences = (ctx, def, val, refOp) => {
|
|
|
41
41
|
let index = 0;
|
|
42
42
|
for (const id of val) {
|
|
43
43
|
if (typeof id === 'number') {
|
|
44
|
-
validate(
|
|
44
|
+
validate(id, def);
|
|
45
45
|
writeU32(ctx, id);
|
|
46
46
|
index++;
|
|
47
47
|
continue;
|
|
@@ -50,7 +50,7 @@ const putReferences = (ctx, def, val, refOp) => {
|
|
|
50
50
|
if (hasEdgeOrIndex(def, id)) {
|
|
51
51
|
return index;
|
|
52
52
|
}
|
|
53
|
-
validate(
|
|
53
|
+
validate(id.id, def);
|
|
54
54
|
writeU32(ctx, id.id);
|
|
55
55
|
index++;
|
|
56
56
|
continue;
|
|
@@ -78,7 +78,7 @@ const updateReferences = (ctx, def, val, index, length, refOp) => {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
if (typeof id === 'number') {
|
|
81
|
-
validate(
|
|
81
|
+
validate(id, def);
|
|
82
82
|
writeU8(ctx, NOEDGE_NOINDEX_REALID);
|
|
83
83
|
writeU32(ctx, id);
|
|
84
84
|
continue;
|
|
@@ -88,7 +88,7 @@ const updateReferences = (ctx, def, val, index, length, refOp) => {
|
|
|
88
88
|
}
|
|
89
89
|
if (typeof id.then === 'function') {
|
|
90
90
|
if (id.id) {
|
|
91
|
-
validate(
|
|
91
|
+
validate(id.id, def);
|
|
92
92
|
writeU8(ctx, NOEDGE_NOINDEX_REALID);
|
|
93
93
|
writeU32(ctx, id.id);
|
|
94
94
|
continue;
|
|
@@ -101,7 +101,7 @@ const updateReferences = (ctx, def, val, index, length, refOp) => {
|
|
|
101
101
|
throw id;
|
|
102
102
|
}
|
|
103
103
|
if (typeof id.id === 'number') {
|
|
104
|
-
validate(
|
|
104
|
+
validate(id.id, def);
|
|
105
105
|
writeReferenceObj(ctx, def, id.id, id, false);
|
|
106
106
|
continue;
|
|
107
107
|
}
|
|
@@ -110,7 +110,7 @@ const updateReferences = (ctx, def, val, index, length, refOp) => {
|
|
|
110
110
|
}
|
|
111
111
|
if (typeof id.id.then === 'function') {
|
|
112
112
|
if (id.id.id) {
|
|
113
|
-
validate(
|
|
113
|
+
validate(id.id.id, def);
|
|
114
114
|
writeReferenceObj(ctx, def, id.id.id, id, false);
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
@@ -185,7 +185,7 @@ const deleteReferences = (ctx, def, val) => {
|
|
|
185
185
|
writeU8(ctx, REF_OP_DELETE);
|
|
186
186
|
for (const id of val) {
|
|
187
187
|
if (typeof id === 'number') {
|
|
188
|
-
validate(
|
|
188
|
+
validate(id, def);
|
|
189
189
|
writeU32(ctx, id);
|
|
190
190
|
continue;
|
|
191
191
|
}
|
|
@@ -28,7 +28,7 @@ export const writeString = (ctx, def, val, lang) => {
|
|
|
28
28
|
deleteString(ctx, def, lang);
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
|
-
validate(
|
|
31
|
+
validate(val, def);
|
|
32
32
|
let size = isUint8 ? val.byteLength : ENCODER.encode(val).byteLength + 6;
|
|
33
33
|
reserve(ctx, FULL_CURSOR_SIZE + 11 + size);
|
|
34
34
|
writePropCursor(ctx, def);
|
|
@@ -8,7 +8,7 @@ export const writeVector = (ctx, def, val) => {
|
|
|
8
8
|
deleteProp(ctx, def);
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
validate(
|
|
11
|
+
validate(val, def);
|
|
12
12
|
if (val.byteLength === 0) {
|
|
13
13
|
deleteProp(ctx, def);
|
|
14
14
|
return;
|
|
@@ -34,15 +34,5 @@ export const writeVector = (ctx, def, val) => {
|
|
|
34
34
|
ctx.array[ctx.index++] = 0;
|
|
35
35
|
ctx.array.set(new Uint8Array(val.buffer).subarray(0, size), ctx.index - padding);
|
|
36
36
|
ctx.index += size;
|
|
37
|
-
// let size = Math.min(val.byteLength, def.len)
|
|
38
|
-
// let padding = 0
|
|
39
|
-
// if (ctx.index % 4 !== 0) {
|
|
40
|
-
// padding = ctx.index % 4
|
|
41
|
-
// size -= padding
|
|
42
|
-
// }
|
|
43
|
-
// writeU32(ctx, size + 4)
|
|
44
|
-
// writeU8(ctx, padding)
|
|
45
|
-
// writePadding(ctx, 3 - padding)
|
|
46
|
-
// writeU8Array(ctx, new Uint8Array(val.buffer).subarray(0, size))
|
|
47
37
|
};
|
|
48
38
|
//# sourceMappingURL=vector.js.map
|
|
@@ -16,6 +16,7 @@ export declare const PADDING = 255;
|
|
|
16
16
|
export declare const SWITCH_TYPE = 2;
|
|
17
17
|
export declare const SWITCH_FIELD = 0;
|
|
18
18
|
export declare const SWITCH_ID_CREATE = 9;
|
|
19
|
+
export declare const SWITCH_ID_CREATE_RING = 19;
|
|
19
20
|
export declare const SWITCH_ID_CREATE_UNSAFE = 8;
|
|
20
21
|
export declare const SWITCH_ID_UPDATE = 1;
|
|
21
22
|
export declare const UPSERT = 17;
|
|
@@ -15,6 +15,7 @@ export const PADDING = 255;
|
|
|
15
15
|
export const SWITCH_TYPE = 2;
|
|
16
16
|
export const SWITCH_FIELD = 0;
|
|
17
17
|
export const SWITCH_ID_CREATE = 9;
|
|
18
|
+
export const SWITCH_ID_CREATE_RING = 19;
|
|
18
19
|
export const SWITCH_ID_CREATE_UNSAFE = 8;
|
|
19
20
|
export const SWITCH_ID_UPDATE = 1;
|
|
20
21
|
export const UPSERT = 17;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PropDef, PropDefEdge } from '@based/schema/def';
|
|
2
2
|
import { DbClient } from '../../index.js';
|
|
3
|
-
export declare const validate: (def: PropDef | PropDefEdge
|
|
3
|
+
export declare const validate: (val: any, def: PropDef | PropDefEdge) => void;
|
|
4
4
|
export declare const validatePayload: (payload: any) => void;
|
|
5
5
|
export declare const validateId: (id: number) => void;
|
|
6
6
|
export declare const getValidSchema: (db: DbClient, type: string) => import("@based/schema/def").SchemaTypeDef;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { isValidId } from '@based/schema/def';
|
|
2
|
-
export const validate = (
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export const validate = (val, def) => {
|
|
3
|
+
const msg = def.validation(val, def.schema);
|
|
4
|
+
if (msg !== true) {
|
|
5
|
+
throw [def, val, msg];
|
|
5
6
|
}
|
|
6
7
|
};
|
|
7
8
|
export const validatePayload = (payload) => {
|
|
@@ -24,9 +24,9 @@ export declare class QueryBranch<T> {
|
|
|
24
24
|
search(query: string, ...fields: Search[]): T;
|
|
25
25
|
search(query: ArrayBufferView, field: string, opts?: Omit<FilterOpts, 'lowerCase'>): T;
|
|
26
26
|
groupBy(field: string, step?: StepInput): T;
|
|
27
|
-
count(
|
|
27
|
+
count(): T;
|
|
28
28
|
sum(...fields: string[]): T;
|
|
29
|
-
cardinality(
|
|
29
|
+
cardinality(...fields: string[]): T;
|
|
30
30
|
stddev(...args: (string | aggFnOptions)[]): T;
|
|
31
31
|
var(...args: (string | aggFnOptions)[]): T;
|
|
32
32
|
avg(...fields: string[]): T;
|
|
@@ -52,9 +52,9 @@ export declare class BasedDbQuery extends QueryBranch<BasedDbQuery> {
|
|
|
52
52
|
readSchema: ReaderSchema;
|
|
53
53
|
constructor(db: DbClient, type: string, rawTarget?: QueryByAliasObj | number | Promise<number> | Uint32Array | (QueryByAliasObj | number)[], skipValidation?: boolean);
|
|
54
54
|
reset(): void;
|
|
55
|
-
id: number;
|
|
56
55
|
get(): GetPromise;
|
|
57
|
-
buffer
|
|
56
|
+
buffer?: Uint8Array;
|
|
57
|
+
subscriptionBuffer?: Uint8Array;
|
|
58
58
|
register(): void;
|
|
59
59
|
locale(locale: LangName, fallBack?: LangFallback): this;
|
|
60
60
|
subscribe(onData: OnData, onError?: OnError): import("./subscription/types.js").OnClose;
|
|
@@ -129,16 +129,16 @@ export class QueryBranch {
|
|
|
129
129
|
// @ts-ignore
|
|
130
130
|
return this;
|
|
131
131
|
}
|
|
132
|
-
count(
|
|
132
|
+
count() {
|
|
133
|
+
const fields = ['count'];
|
|
133
134
|
if (this.queryCommands) {
|
|
134
135
|
this.queryCommands.push({
|
|
135
136
|
method: 'count',
|
|
136
|
-
args:
|
|
137
|
+
args: fields,
|
|
137
138
|
});
|
|
138
139
|
}
|
|
139
140
|
else {
|
|
140
|
-
|
|
141
|
-
addAggregate(this, AggregateType.COUNT, p);
|
|
141
|
+
addAggregate(this, AggregateType.COUNT, fields);
|
|
142
142
|
}
|
|
143
143
|
// @ts-ignore
|
|
144
144
|
return this;
|
|
@@ -159,18 +159,18 @@ export class QueryBranch {
|
|
|
159
159
|
// @ts-ignore
|
|
160
160
|
return this;
|
|
161
161
|
}
|
|
162
|
-
cardinality(
|
|
163
|
-
if (
|
|
162
|
+
cardinality(...fields) {
|
|
163
|
+
if (fields.length === 0) {
|
|
164
164
|
throw new Error('Empty cardinality() called');
|
|
165
165
|
}
|
|
166
166
|
if (this.queryCommands) {
|
|
167
167
|
this.queryCommands.push({
|
|
168
168
|
method: 'cardinality',
|
|
169
|
-
args:
|
|
169
|
+
args: fields,
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
else {
|
|
173
|
-
addAggregate(this, AggregateType.CARDINALITY,
|
|
173
|
+
addAggregate(this, AggregateType.CARDINALITY, fields);
|
|
174
174
|
}
|
|
175
175
|
// @ts-ignore
|
|
176
176
|
return this;
|
|
@@ -335,6 +335,18 @@ export class QueryBranch {
|
|
|
335
335
|
// @ts-ignore
|
|
336
336
|
return this;
|
|
337
337
|
}
|
|
338
|
+
// first() {
|
|
339
|
+
// if (this.queryCommands) {
|
|
340
|
+
// this.queryCommands.push({ method: 'first', args: [] })
|
|
341
|
+
// } else {
|
|
342
|
+
// const offset = 0
|
|
343
|
+
// const limit = 1
|
|
344
|
+
// this.def.range.offset = offset
|
|
345
|
+
// this.def.range.limit = limit
|
|
346
|
+
// }
|
|
347
|
+
// // @ts-ignore
|
|
348
|
+
// return this
|
|
349
|
+
// }
|
|
338
350
|
include(...fields) {
|
|
339
351
|
if (this.queryCommands) {
|
|
340
352
|
this.queryCommands.push({ method: 'include', args: fields });
|
|
@@ -408,7 +420,7 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
408
420
|
this.target = target;
|
|
409
421
|
}
|
|
410
422
|
reset() {
|
|
411
|
-
this.
|
|
423
|
+
this.subscriptionBuffer = undefined;
|
|
412
424
|
this.buffer = undefined;
|
|
413
425
|
this.def = undefined;
|
|
414
426
|
}
|
|
@@ -427,12 +439,12 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
427
439
|
reject(err);
|
|
428
440
|
return;
|
|
429
441
|
}
|
|
430
|
-
const d = performance.now();
|
|
431
442
|
await this.db.isModified();
|
|
432
443
|
if (this.db.schema?.hash !== this.def.schemaChecksum) {
|
|
433
444
|
this.reset();
|
|
434
445
|
return this.#getInternal(resolve, reject);
|
|
435
446
|
}
|
|
447
|
+
const d = performance.now();
|
|
436
448
|
const res = await this.db.hooks.getQueryBuf(buf);
|
|
437
449
|
if (res.byteLength === 1) {
|
|
438
450
|
if (res[0] === 0) {
|
|
@@ -461,12 +473,11 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
461
473
|
resolve(new BasedQueryResponse(this.def, res, performance.now() - d));
|
|
462
474
|
}
|
|
463
475
|
};
|
|
464
|
-
// if !id not initialized yet
|
|
465
|
-
id;
|
|
466
476
|
get() {
|
|
467
477
|
return new GetPromise(this.#getInternal);
|
|
468
478
|
}
|
|
469
479
|
buffer;
|
|
480
|
+
subscriptionBuffer;
|
|
470
481
|
register() {
|
|
471
482
|
registerQuery(this);
|
|
472
483
|
}
|
|
@@ -10,7 +10,6 @@ export declare class BasedQueryResponse {
|
|
|
10
10
|
end: number;
|
|
11
11
|
constructor(def: QueryDef, result: Uint8Array, execTime: number, end?: number);
|
|
12
12
|
get id(): number;
|
|
13
|
-
get queryId(): number;
|
|
14
13
|
get version(): number;
|
|
15
14
|
get size(): number;
|
|
16
15
|
[inspect.custom](depth: number): string;
|
|
@@ -4,5 +4,5 @@ import { QueryBranch } from '../BasedDbQuery.js';
|
|
|
4
4
|
import { AggregateType } from '@based/protocol/db-read';
|
|
5
5
|
export declare const aggregateToBuffer: (aggregates: QueryDefAggregation) => Uint8Array;
|
|
6
6
|
export declare const groupBy: (q: QueryBranch<any>, field: string, StepInput: StepInput) => void;
|
|
7
|
-
export declare const addAggregate: (query: QueryBranch<any>, type: AggregateType,
|
|
7
|
+
export declare const addAggregate: (query: QueryBranch<any>, type: AggregateType, propNames: string[], option?: aggFnOptions) => void;
|
|
8
8
|
export declare const isRootCountOnly: (def: QueryDef, filterSize: number) => boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { writeUint16, writeInt16, writeUint32 } from '@based/utils';
|
|
2
2
|
import { QueryDefType } from '../types.js';
|
|
3
3
|
import { setMode } from './types.js';
|
|
4
|
-
import {
|
|
5
|
-
import { aggregationFieldDoesNotExist, validateStepRange, } from '../validation.js';
|
|
4
|
+
import { REFERENCE, REFERENCES, isPropDef, } from '@based/schema/def';
|
|
5
|
+
import { aggregationFieldDoesNotExist, validateStepRange, edgeNotImplemented, } from '../validation.js';
|
|
6
6
|
import { aggregateTypeMap, Interval, } from '../aggregates/types.js';
|
|
7
7
|
import { AggregateType } from '@based/protocol/db-read';
|
|
8
8
|
export const aggregateToBuffer = (aggregates) => {
|
|
@@ -54,16 +54,19 @@ export const aggregateToBuffer = (aggregates) => {
|
|
|
54
54
|
i += 2;
|
|
55
55
|
writeUint16(aggBuffer, agg.accumulatorPos, i);
|
|
56
56
|
i += 2;
|
|
57
|
+
aggBuffer[i] = agg.propDef.__isEdge ? 1 : 0;
|
|
58
|
+
i += 1;
|
|
57
59
|
size += i - startI;
|
|
58
60
|
}
|
|
59
61
|
writeUint16(aggBuffer, size, sizeIndex);
|
|
60
62
|
}
|
|
63
|
+
// console.log('aggBuffer', aggBuffer)
|
|
61
64
|
return aggBuffer;
|
|
62
65
|
};
|
|
63
66
|
const ensureAggregate = (def) => {
|
|
64
67
|
if (!def.aggregate) {
|
|
65
68
|
def.aggregate = {
|
|
66
|
-
size:
|
|
69
|
+
size: 6, // groupBy + resultSize, accumulatorSize, mode,
|
|
67
70
|
aggregates: new Map(),
|
|
68
71
|
totalResultsSize: 0,
|
|
69
72
|
totalAccumulatorSize: 0,
|
|
@@ -88,9 +91,11 @@ export const groupBy = (q, field, StepInput) => {
|
|
|
88
91
|
groupByHook(q, field);
|
|
89
92
|
def.schema.hooks.groupBy = groupByHook;
|
|
90
93
|
}
|
|
91
|
-
|
|
94
|
+
if (!def.aggregate) {
|
|
95
|
+
ensureAggregate(def);
|
|
96
|
+
}
|
|
92
97
|
if (!def.aggregate.groupBy) {
|
|
93
|
-
def.aggregate.size +=
|
|
98
|
+
def.aggregate.size += 13; // field, srcPropType, start, len, stepType, stepRange, timezone
|
|
94
99
|
}
|
|
95
100
|
def.aggregate.groupBy = fieldDef;
|
|
96
101
|
def.aggregate.groupBy.stepRange = undefined;
|
|
@@ -124,60 +129,127 @@ export const groupBy = (q, field, StepInput) => {
|
|
|
124
129
|
def.aggregate.groupBy.display = StepInput?.display;
|
|
125
130
|
}
|
|
126
131
|
};
|
|
127
|
-
|
|
128
|
-
const def = query.def;
|
|
129
|
-
let hookFields;
|
|
130
|
-
ensureAggregate(def);
|
|
131
|
-
if (option?.mode) {
|
|
132
|
-
def.aggregate.option = option;
|
|
133
|
-
}
|
|
132
|
+
const updateAggregateDefs = (def, propDef, aggType) => {
|
|
134
133
|
const aggregates = def.aggregate.aggregates;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
134
|
+
if (!aggregates.get(propDef.prop)) {
|
|
135
|
+
aggregates.set(propDef.prop, []);
|
|
136
|
+
def.aggregate.size += 3; // field + fieldAggSize
|
|
137
|
+
}
|
|
138
|
+
const aggregateField = aggregates.get(propDef.prop);
|
|
139
|
+
aggregateField.push({
|
|
140
|
+
type: aggType,
|
|
141
|
+
propDef: propDef,
|
|
142
|
+
resultPos: def.aggregate.totalResultsSize,
|
|
143
|
+
accumulatorPos: def.aggregate.totalAccumulatorSize,
|
|
144
|
+
isEdge: isEdge(propDef.path[0]),
|
|
145
|
+
});
|
|
146
|
+
const specificSizes = aggregateTypeMap.get(aggType);
|
|
147
|
+
if (specificSizes) {
|
|
148
|
+
def.aggregate.totalResultsSize += specificSizes.resultsSize;
|
|
149
|
+
def.aggregate.totalAccumulatorSize += specificSizes.accumulatorSize;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
def.aggregate.totalResultsSize += 8;
|
|
153
|
+
def.aggregate.totalAccumulatorSize += 8;
|
|
154
|
+
}
|
|
155
|
+
// needs to add an extra field WRITE TO
|
|
156
|
+
def.aggregate.size += 9; // aggType + propType + start + resultPos + accumulatorPos + isEdge
|
|
157
|
+
};
|
|
158
|
+
const isCount = (propString, aggType) => {
|
|
159
|
+
return propString === 'count' || aggType === AggregateType.COUNT;
|
|
160
|
+
};
|
|
161
|
+
const isEdge = (propString) => {
|
|
162
|
+
return propString.startsWith('$');
|
|
163
|
+
};
|
|
164
|
+
const isReferenceOrReferences = (typeIndex) => {
|
|
165
|
+
return typeIndex === REFERENCE || typeIndex === REFERENCES;
|
|
166
|
+
};
|
|
167
|
+
const getPropDefinition = (def, propName, type, resolvedPropDef) => {
|
|
168
|
+
if (isCount(propName, type)) {
|
|
169
|
+
return {
|
|
170
|
+
schema: null,
|
|
171
|
+
prop: 255,
|
|
172
|
+
path: [propName],
|
|
173
|
+
__isPropDef: true,
|
|
174
|
+
len: 4,
|
|
175
|
+
start: 0,
|
|
176
|
+
typeIndex: 1,
|
|
177
|
+
separate: true,
|
|
178
|
+
validation: () => true,
|
|
179
|
+
default: 0,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return resolvedPropDef || def.schema.props[propName];
|
|
183
|
+
};
|
|
184
|
+
const IN_RECURSION = Symbol('IN_RECURSION');
|
|
185
|
+
// process references, nested, edges
|
|
186
|
+
// return undefined if skip to recursive call (refs)
|
|
187
|
+
const processPropPath = (query, path, originalPropName, type) => {
|
|
188
|
+
let t = query.def.schema.tree;
|
|
189
|
+
for (let i = 0; i < path.length; i++) {
|
|
190
|
+
const propName = path[i];
|
|
191
|
+
if (isEdge(propName)) {
|
|
192
|
+
// @ts-ignore
|
|
193
|
+
const edgePropDef = query.def.target?.propDef?.edges[propName];
|
|
194
|
+
if (edgePropDef) {
|
|
195
|
+
return edgePropDef;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
edgeNotImplemented(query.def, propName);
|
|
199
|
+
return undefined;
|
|
147
200
|
}
|
|
148
|
-
: def.schema.props[field];
|
|
149
|
-
if (!fieldDef) {
|
|
150
|
-
aggregationFieldDoesNotExist(def, field);
|
|
151
201
|
}
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
fieldDef.hooks.aggregate(query, hookFields);
|
|
202
|
+
if (!t) {
|
|
203
|
+
return undefined; // end
|
|
155
204
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
205
|
+
t = t[propName];
|
|
206
|
+
if (!t) {
|
|
207
|
+
return undefined; // path nor exist
|
|
159
208
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
209
|
+
if (isPropDef(t) && isReferenceOrReferences(t.typeIndex)) {
|
|
210
|
+
const remainingPath = path.slice(i + 1).join('.');
|
|
211
|
+
if (isEdge(remainingPath)) {
|
|
212
|
+
return t; // let the calling handle it
|
|
213
|
+
}
|
|
214
|
+
if (remainingPath) {
|
|
215
|
+
addAggregate(query, type, [remainingPath], query.def.aggregate.option);
|
|
216
|
+
}
|
|
217
|
+
return IN_RECURSION;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return isPropDef(t) ? t : undefined;
|
|
221
|
+
};
|
|
222
|
+
export const addAggregate = (query, type, propNames, option) => {
|
|
223
|
+
const def = query.def;
|
|
224
|
+
let hookPropNames;
|
|
225
|
+
ensureAggregate(def);
|
|
226
|
+
if (option?.mode) {
|
|
227
|
+
def.aggregate.option = option;
|
|
228
|
+
}
|
|
229
|
+
for (const propName of propNames) {
|
|
230
|
+
if (Array.isArray(propName)) {
|
|
231
|
+
addAggregate(query, type, propName, option);
|
|
171
232
|
}
|
|
172
233
|
else {
|
|
173
|
-
|
|
174
|
-
|
|
234
|
+
const path = propName.split('.');
|
|
235
|
+
let resolvedPropDef = processPropPath(query, path, propName, type);
|
|
236
|
+
if (resolvedPropDef === IN_RECURSION) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
let propDef = getPropDefinition(def, propName, type, resolvedPropDef);
|
|
240
|
+
if (!propDef) {
|
|
241
|
+
aggregationFieldDoesNotExist(def, propName);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (propDef.hooks?.aggregate) {
|
|
245
|
+
hookPropNames ??= new Set(propNames);
|
|
246
|
+
propDef.hooks.aggregate(query, hookPropNames);
|
|
247
|
+
}
|
|
248
|
+
updateAggregateDefs(def, propDef, type);
|
|
249
|
+
if (def.schema.hooks?.aggregate) {
|
|
250
|
+
def.schema.hooks.aggregate(query, hookPropNames || new Set(propNames));
|
|
251
|
+
}
|
|
175
252
|
}
|
|
176
|
-
// needs to add an extra field WRITE TO
|
|
177
|
-
def.aggregate.size += 8;
|
|
178
|
-
}
|
|
179
|
-
if (def.schema.hooks?.aggregate) {
|
|
180
|
-
def.schema.hooks.aggregate(query, hookFields || new Set(fields));
|
|
181
253
|
}
|
|
182
254
|
};
|
|
183
255
|
export const isRootCountOnly = (def, filterSize) => {
|