@based/db 0.0.8 → 0.0.9
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 +425 -8
- package/dist/lib/darwin_aarch64/include/selva/db.h +12 -3
- package/dist/lib/darwin_aarch64/include/selva/fields.h +22 -11
- package/dist/lib/darwin_aarch64/include/selva/history.h +49 -0
- package/dist/lib/darwin_aarch64/include/selva/hll.h +21 -0
- package/dist/lib/darwin_aarch64/include/selva/sort.h +14 -0
- package/dist/lib/darwin_aarch64/include/selva/types.h +9 -2
- package/dist/lib/darwin_aarch64/include/selva/vector.h +22 -1
- package/dist/lib/darwin_aarch64/include/selva/xxhash64.h +23 -0
- package/dist/lib/darwin_aarch64/libnode-v20.11.1.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v20.18.1.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.13.0.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.8.0.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +12 -3
- package/dist/lib/linux_aarch64/include/selva/fields.h +22 -11
- package/dist/lib/linux_aarch64/include/selva/history.h +49 -0
- package/dist/lib/linux_aarch64/include/selva/hll.h +21 -0
- package/dist/lib/linux_aarch64/include/selva/sort.h +14 -0
- package/dist/lib/linux_aarch64/include/selva/types.h +9 -2
- package/dist/lib/linux_aarch64/include/selva/vector.h +22 -1
- package/dist/lib/linux_aarch64/include/selva/xxhash64.h +23 -0
- package/dist/lib/linux_aarch64/libnode-v20.11.1.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v20.18.1.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v22.13.0.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +12 -3
- package/dist/lib/linux_x86_64/include/selva/fields.h +22 -11
- package/dist/lib/linux_x86_64/include/selva/history.h +49 -0
- package/dist/lib/linux_x86_64/include/selva/hll.h +21 -0
- package/dist/lib/linux_x86_64/include/selva/sort.h +14 -0
- package/dist/lib/linux_x86_64/include/selva/types.h +9 -2
- package/dist/lib/linux_x86_64/include/selva/vector.h +22 -1
- package/dist/lib/linux_x86_64/include/selva/xxhash64.h +23 -0
- package/dist/lib/linux_x86_64/libnode-v20.11.1.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v20.18.1.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v22.13.0.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/bitWise.js +21 -1
- package/dist/src/client/index.d.ts +11 -5
- package/dist/src/client/index.js +57 -11
- package/dist/src/client/modify/ModifyRes.d.ts +4 -1
- package/dist/src/client/modify/ModifyRes.js +8 -1
- package/dist/src/client/modify/alias.js +3 -3
- package/dist/src/client/modify/binary.js +5 -2
- package/dist/src/client/modify/cardinality.d.ts +4 -0
- package/dist/src/client/modify/cardinality.js +50 -0
- package/dist/src/client/modify/create copy.d.ts +5 -0
- package/dist/src/client/modify/create copy.js +112 -0
- package/dist/src/client/modify/create.d.ts +2 -1
- package/dist/src/client/modify/create.js +11 -7
- package/dist/src/client/modify/delete.d.ts +2 -0
- package/dist/src/client/modify/delete.js +37 -0
- package/dist/src/client/modify/expire.d.ts +3 -0
- package/dist/src/client/modify/expire.js +25 -0
- package/dist/src/client/modify/fixed.js +11 -1
- package/dist/src/client/modify/index.d.ts +1 -1
- package/dist/src/client/modify/index.js +1 -1
- package/dist/src/client/modify/json.d.ts +4 -0
- package/dist/src/client/modify/json.js +5 -0
- package/dist/src/client/modify/modify.js +11 -7
- package/dist/src/client/modify/references/edge.js +21 -6
- package/dist/src/client/modify/references/reference.js +2 -2
- package/dist/src/client/modify/references/references.d.ts +0 -1
- package/dist/src/client/modify/references/references.js +4 -4
- package/dist/src/client/modify/remove.d.ts +1 -2
- package/dist/src/client/modify/remove.js +9 -6
- package/dist/src/client/modify/setCursor.d.ts +1 -1
- package/dist/src/client/modify/setCursor.js +4 -1
- package/dist/src/client/modify/string.js +2 -2
- package/dist/src/client/modify/text.d.ts +2 -1
- package/dist/src/client/modify/text.js +13 -7
- package/dist/src/client/modify/types.d.ts +8 -1
- package/dist/src/client/modify/types.js +1 -0
- package/dist/src/client/modify/update.d.ts +2 -1
- package/dist/src/client/modify/update.js +9 -5
- package/dist/src/client/modify/upsert.d.ts +2 -1
- package/dist/src/client/modify/upsert.js +3 -3
- package/dist/src/client/modify/vector copy.d.ts +4 -0
- package/dist/src/client/modify/vector copy.js +46 -0
- package/dist/src/client/modify/vector.js +6 -4
- package/dist/src/client/query/BasedDbQuery.d.ts +4 -3
- package/dist/src/client/query/BasedDbQuery.js +39 -16
- package/dist/src/client/query/BasedIterable.js +3 -3
- package/dist/src/client/query/filter/FilterBranch.d.ts +2 -2
- package/dist/src/client/query/filter/FilterBranch.js +2 -2
- package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +3 -2
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +14 -11
- package/dist/src/client/query/filter/createReferenceFilter.d.ts +2 -1
- package/dist/src/client/query/filter/createReferenceFilter.js +6 -5
- package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -1
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +61 -30
- package/dist/src/client/query/filter/filter.d.ts +2 -2
- package/dist/src/client/query/filter/filter.js +23 -21
- package/dist/src/client/query/filter/parseFilterValue.js +9 -64
- package/dist/src/client/query/filter/primitiveFilter.js +7 -11
- package/dist/src/client/query/filter/toBuffer.js +5 -7
- package/dist/src/client/query/filter/types.d.ts +51 -2
- package/dist/src/client/query/filter/types.js +114 -0
- package/dist/src/client/query/include/props.d.ts +2 -0
- package/dist/src/client/query/include/props.js +25 -6
- package/dist/src/client/query/include/toBuffer.js +21 -1
- package/dist/src/client/query/include/walk.js +17 -2
- package/dist/src/client/query/queryDef.js +1 -0
- package/dist/src/client/query/read/read.js +85 -21
- package/dist/src/client/query/search/index.d.ts +2 -0
- package/dist/src/client/query/search/index.js +79 -23
- package/dist/src/client/query/subscription/index.js +2 -2
- package/dist/src/client/query/subscription/markers.d.ts +1 -1
- package/dist/src/client/query/subscription/markers.js +2 -2
- package/dist/src/client/query/toBuffer.js +0 -4
- package/dist/src/client/query/types.d.ts +10 -0
- package/dist/src/client/query/validation.d.ts +3 -2
- package/dist/src/client/query/validation.js +17 -2
- package/dist/src/client/timestamp.d.ts +1 -0
- package/dist/src/client/timestamp.js +68 -0
- package/dist/src/client/xxHash64.d.ts +1 -0
- package/dist/src/client/xxHash64.js +5 -0
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.js +13 -3
- package/dist/src/native.d.ts +1 -0
- package/dist/src/native.js +4 -1
- package/dist/src/server/csmt/tree.js +12 -2
- package/dist/src/server/index.d.ts +12 -4
- package/dist/src/server/index.js +63 -17
- package/dist/src/server/migrate/worker.js +3 -3
- package/dist/src/server/schema/selvaBuffer.js +20 -11
- package/dist/src/server/schema/typeDef.d.ts +2 -2
- package/dist/src/server/schema/typeDef.js +14 -5
- package/dist/src/server/schema/types.d.ts +7 -2
- package/dist/src/server/schema/types.js +6 -3
- package/package.json +1 -1
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { REFERENCE, REFERENCES, REVERSE_SIZE_MAP, } from '../../../server/schema/types.js';
|
|
2
|
-
import {
|
|
2
|
+
import { EQUAL, isNumerical } from './types.js';
|
|
3
3
|
import { createVariableFilterBuffer } from './createVariableFilterBuffer.js';
|
|
4
4
|
import { createFixedFilterBuffer } from './createFixedFilterBuffer.js';
|
|
5
5
|
import { createReferenceFilter } from './createReferenceFilter.js';
|
|
6
|
-
import { checkOperator, checkValue } from '../validation.js';
|
|
7
6
|
export const primitiveFilter = (prop, filter, conditions, lang) => {
|
|
8
|
-
let [,
|
|
9
|
-
checkOperator(operator);
|
|
10
|
-
checkValue(value, operator);
|
|
7
|
+
let [, ctx, value] = filter;
|
|
11
8
|
const fieldIndexChar = prop.prop;
|
|
12
9
|
let buf;
|
|
13
|
-
const op = operationToByte(operator);
|
|
14
10
|
let size = 0;
|
|
15
11
|
const bufferMap = prop.__isEdge ? conditions.edges : conditions.conditions;
|
|
16
12
|
const isArray = Array.isArray(value);
|
|
@@ -19,19 +15,19 @@ export const primitiveFilter = (prop, filter, conditions, lang) => {
|
|
|
19
15
|
}
|
|
20
16
|
const propSize = REVERSE_SIZE_MAP[prop.typeIndex];
|
|
21
17
|
if (prop.typeIndex === REFERENCE) {
|
|
22
|
-
buf = createReferenceFilter(prop,
|
|
18
|
+
buf = createReferenceFilter(prop, ctx, value);
|
|
23
19
|
}
|
|
24
20
|
else if (prop.typeIndex === REFERENCES) {
|
|
25
|
-
if (
|
|
21
|
+
if (ctx.operation === EQUAL && !isArray) {
|
|
26
22
|
value = [value];
|
|
27
23
|
}
|
|
28
|
-
buf = createFixedFilterBuffer(prop, 4,
|
|
24
|
+
buf = createFixedFilterBuffer(prop, 4, ctx, value, !isNumerical(ctx.operation));
|
|
29
25
|
}
|
|
30
26
|
else if (propSize) {
|
|
31
|
-
buf = createFixedFilterBuffer(prop, propSize,
|
|
27
|
+
buf = createFixedFilterBuffer(prop, propSize, ctx, value, false);
|
|
32
28
|
}
|
|
33
29
|
else {
|
|
34
|
-
buf = createVariableFilterBuffer(value, prop,
|
|
30
|
+
buf = createVariableFilterBuffer(value, prop, ctx, lang);
|
|
35
31
|
}
|
|
36
32
|
// ADD OR if array for value
|
|
37
33
|
let arr = bufferMap.get(fieldIndexChar);
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// and
|
|
3
|
-
// [meta = 255] [size 2]
|
|
4
|
-
// -------------------------------------------
|
|
1
|
+
import { META_EDGE, META_OR_BRANCH, META_REFERENCE } from './types.js';
|
|
5
2
|
// or
|
|
6
3
|
// [meta = 253] [size 2] [next 4]
|
|
7
4
|
// -------------------------------------------
|
|
@@ -43,7 +40,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
|
|
|
43
40
|
let lastWritten = offset;
|
|
44
41
|
let orJumpIndex = 0;
|
|
45
42
|
if (conditions.or) {
|
|
46
|
-
result[lastWritten] =
|
|
43
|
+
result[lastWritten] = META_OR_BRANCH;
|
|
47
44
|
lastWritten++;
|
|
48
45
|
orJumpIndex = lastWritten;
|
|
49
46
|
lastWritten += 2;
|
|
@@ -54,7 +51,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
|
|
|
54
51
|
});
|
|
55
52
|
if (conditions.references) {
|
|
56
53
|
for (const [refField, refConditions] of conditions.references) {
|
|
57
|
-
result[lastWritten] =
|
|
54
|
+
result[lastWritten] = META_REFERENCE;
|
|
58
55
|
lastWritten++;
|
|
59
56
|
result[lastWritten] = refField;
|
|
60
57
|
lastWritten++;
|
|
@@ -69,7 +66,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
|
|
|
69
66
|
}
|
|
70
67
|
if (conditions.edges) {
|
|
71
68
|
conditions.edges.forEach((v, k) => {
|
|
72
|
-
result[lastWritten] =
|
|
69
|
+
result[lastWritten] = META_EDGE;
|
|
73
70
|
lastWritten++;
|
|
74
71
|
let sizeIndex = lastWritten;
|
|
75
72
|
lastWritten += 2;
|
|
@@ -86,6 +83,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
|
|
|
86
83
|
}
|
|
87
84
|
return lastWritten - offset;
|
|
88
85
|
};
|
|
86
|
+
// TODO convert to UINT8ARRAY
|
|
89
87
|
export const filterToBuffer = (conditions) => {
|
|
90
88
|
let result;
|
|
91
89
|
if (conditions.size > 0) {
|
|
@@ -1,6 +1,55 @@
|
|
|
1
|
-
import { Operator } from './operators.js';
|
|
2
1
|
import { FilterBranch } from './FilterBranch.js';
|
|
3
|
-
export type Filter = [fieldStr: string,
|
|
2
|
+
export type Filter = [fieldStr: string, ctx: FilterCtx, value: any];
|
|
4
3
|
export type FilterBranchFn = (filterBranch: FilterBranch) => void;
|
|
5
4
|
export type FilterAst = (Filter | FilterAst)[];
|
|
6
5
|
export declare const IsFilter: (f: FilterAst) => f is Filter;
|
|
6
|
+
export declare const validOperators: readonly ["=", "has", "!has", "<", ">", "!=", "like", ">=", "<=", "..", "!.."];
|
|
7
|
+
export type Operator = '=' | 'has' | '!has' | '<' | '>' | '!=' | 'like' | '>=' | '<=' | '..' | '!..' | 'like';
|
|
8
|
+
export type FilterOpts<O = Operator> = {
|
|
9
|
+
lowerCase?: boolean;
|
|
10
|
+
fn?: 'dotProduct' | 'manhattanDistance' | 'cosineSimilarity' | 'euclideanDistance';
|
|
11
|
+
score?: number;
|
|
12
|
+
};
|
|
13
|
+
export declare const EQUAL = 1;
|
|
14
|
+
export declare const HAS = 2;
|
|
15
|
+
export declare const ENDS_WITH = 4;
|
|
16
|
+
export declare const STARTS_WITH = 5;
|
|
17
|
+
export declare const EQUAL_CRC32 = 17;
|
|
18
|
+
export declare const GREATER_THAN = 6;
|
|
19
|
+
export declare const SMALLER_THAN = 7;
|
|
20
|
+
export declare const GREATER_THAN_INCLUSIVE = 8;
|
|
21
|
+
export declare const SMALLER_THAN_INCLUSIVE = 9;
|
|
22
|
+
export declare const RANGE = 10;
|
|
23
|
+
export declare const RANGE_EXCLUDE = 11;
|
|
24
|
+
export declare const EQUAL_LOWER_CASE = 12;
|
|
25
|
+
export declare const HAS_TO_LOWER_CASE = 13;
|
|
26
|
+
export declare const STARTS_WITH_LOWER_CASE = 14;
|
|
27
|
+
export declare const ENDS_WITH_LOWER_CASE = 15;
|
|
28
|
+
export declare const LIKE = 18;
|
|
29
|
+
export type OPERATOR = typeof EQUAL | typeof HAS | typeof ENDS_WITH | typeof STARTS_WITH | typeof GREATER_THAN | typeof SMALLER_THAN | typeof GREATER_THAN_INCLUSIVE | typeof SMALLER_THAN_INCLUSIVE | typeof RANGE | typeof RANGE_EXCLUDE | typeof EQUAL_LOWER_CASE | typeof HAS_TO_LOWER_CASE | typeof STARTS_WITH_LOWER_CASE | typeof ENDS_WITH_LOWER_CASE | typeof LIKE | typeof EQUAL_CRC32;
|
|
30
|
+
export declare const isNumerical: (op: OPERATOR) => boolean;
|
|
31
|
+
export declare const TYPE_NEGATE = 1;
|
|
32
|
+
export declare const TYPE_DEFAULT = 2;
|
|
33
|
+
export type FILTER_TYPE = typeof TYPE_NEGATE | typeof TYPE_DEFAULT;
|
|
34
|
+
export declare const MODE_DEFAULT = 0;
|
|
35
|
+
export declare const MODE_OR_FIXED = 1;
|
|
36
|
+
export declare const MODE_OR_VAR = 2;
|
|
37
|
+
export declare const MODE_AND_FIXED = 3;
|
|
38
|
+
export declare const MODE_DEFAULT_VAR = 4;
|
|
39
|
+
export declare const MODE_REFERENCE = 5;
|
|
40
|
+
export type FILTER_MODE = typeof MODE_DEFAULT | typeof MODE_OR_FIXED | typeof MODE_OR_VAR | typeof MODE_AND_FIXED | typeof MODE_DEFAULT_VAR | typeof MODE_REFERENCE;
|
|
41
|
+
export declare const META_EDGE = 252;
|
|
42
|
+
export declare const META_OR_BRANCH = 253;
|
|
43
|
+
export declare const META_REFERENCE = 254;
|
|
44
|
+
export type FILTER_META = typeof META_EDGE | typeof META_OR_BRANCH | typeof META_REFERENCE;
|
|
45
|
+
export type FilterCtx = {
|
|
46
|
+
operation: OPERATOR;
|
|
47
|
+
type: FILTER_TYPE;
|
|
48
|
+
opts: FilterOpts;
|
|
49
|
+
};
|
|
50
|
+
export declare const VECTOR_DOT_PRODUCT = 0;
|
|
51
|
+
export declare const VECTOR_MANHATTAN_DIST = 1;
|
|
52
|
+
export declare const VECTOR_COSTINE_SIMILARITY = 2;
|
|
53
|
+
export declare const VECTOR_EUCLIDEAN_DIST = 3;
|
|
54
|
+
export declare const getVectorFn: (optsFn?: FilterOpts["fn"]) => 1 | 2 | 3 | 0;
|
|
55
|
+
export declare const toFilterCtx: (op: Operator, opts?: FilterOpts) => FilterCtx;
|
|
@@ -4,4 +4,118 @@ export const IsFilter = (f) => {
|
|
|
4
4
|
}
|
|
5
5
|
return false;
|
|
6
6
|
};
|
|
7
|
+
export const validOperators = [
|
|
8
|
+
'=',
|
|
9
|
+
'has',
|
|
10
|
+
'!has',
|
|
11
|
+
'<',
|
|
12
|
+
'>',
|
|
13
|
+
'!=',
|
|
14
|
+
'like',
|
|
15
|
+
'>=',
|
|
16
|
+
'<=',
|
|
17
|
+
'..',
|
|
18
|
+
'!..',
|
|
19
|
+
];
|
|
20
|
+
// -------------------------------------------
|
|
21
|
+
// operations shared
|
|
22
|
+
export const EQUAL = 1;
|
|
23
|
+
export const HAS = 2;
|
|
24
|
+
export const ENDS_WITH = 4;
|
|
25
|
+
export const STARTS_WITH = 5;
|
|
26
|
+
export const EQUAL_CRC32 = 17;
|
|
27
|
+
// -------------------------------------------
|
|
28
|
+
// operations numbers
|
|
29
|
+
export const GREATER_THAN = 6;
|
|
30
|
+
export const SMALLER_THAN = 7;
|
|
31
|
+
export const GREATER_THAN_INCLUSIVE = 8;
|
|
32
|
+
export const SMALLER_THAN_INCLUSIVE = 9;
|
|
33
|
+
export const RANGE = 10;
|
|
34
|
+
export const RANGE_EXCLUDE = 11;
|
|
35
|
+
// -------------------------------------------
|
|
36
|
+
// operations strings
|
|
37
|
+
export const EQUAL_LOWER_CASE = 12;
|
|
38
|
+
export const HAS_TO_LOWER_CASE = 13;
|
|
39
|
+
export const STARTS_WITH_LOWER_CASE = 14;
|
|
40
|
+
export const ENDS_WITH_LOWER_CASE = 15;
|
|
41
|
+
export const LIKE = 18;
|
|
42
|
+
// -------------------------------------------
|
|
43
|
+
export const isNumerical = (op) => {
|
|
44
|
+
if (op === GREATER_THAN ||
|
|
45
|
+
op === SMALLER_THAN ||
|
|
46
|
+
op === SMALLER_THAN_INCLUSIVE ||
|
|
47
|
+
op === GREATER_THAN_INCLUSIVE ||
|
|
48
|
+
op === RANGE ||
|
|
49
|
+
op === RANGE_EXCLUDE) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
};
|
|
54
|
+
// -------------------------------------------
|
|
55
|
+
// Types
|
|
56
|
+
export const TYPE_NEGATE = 1;
|
|
57
|
+
export const TYPE_DEFAULT = 2;
|
|
58
|
+
// -------------------------------------------
|
|
59
|
+
// Modes
|
|
60
|
+
export const MODE_DEFAULT = 0;
|
|
61
|
+
export const MODE_OR_FIXED = 1;
|
|
62
|
+
export const MODE_OR_VAR = 2;
|
|
63
|
+
export const MODE_AND_FIXED = 3;
|
|
64
|
+
export const MODE_DEFAULT_VAR = 4;
|
|
65
|
+
export const MODE_REFERENCE = 5;
|
|
66
|
+
// -------------------------------------------
|
|
67
|
+
// Meta
|
|
68
|
+
export const META_EDGE = 252;
|
|
69
|
+
export const META_OR_BRANCH = 253;
|
|
70
|
+
export const META_REFERENCE = 254;
|
|
71
|
+
export const VECTOR_DOT_PRODUCT = 0;
|
|
72
|
+
export const VECTOR_MANHATTAN_DIST = 1;
|
|
73
|
+
export const VECTOR_COSTINE_SIMILARITY = 2;
|
|
74
|
+
export const VECTOR_EUCLIDEAN_DIST = 3;
|
|
75
|
+
export const getVectorFn = (optsFn) => {
|
|
76
|
+
if (!optsFn) {
|
|
77
|
+
return VECTOR_COSTINE_SIMILARITY;
|
|
78
|
+
}
|
|
79
|
+
if (optsFn === 'dotProduct') {
|
|
80
|
+
return VECTOR_DOT_PRODUCT;
|
|
81
|
+
}
|
|
82
|
+
else if (optsFn === 'euclideanDistance') {
|
|
83
|
+
return VECTOR_EUCLIDEAN_DIST;
|
|
84
|
+
}
|
|
85
|
+
else if (optsFn === 'manhattanDistance') {
|
|
86
|
+
return VECTOR_MANHATTAN_DIST;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
export const toFilterCtx = (op, opts = {}) => {
|
|
90
|
+
if (op === '=' || op === '!=') {
|
|
91
|
+
return {
|
|
92
|
+
operation: EQUAL,
|
|
93
|
+
type: op === '!=' ? TYPE_NEGATE : TYPE_DEFAULT,
|
|
94
|
+
opts,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (op === 'has' || op === '!has') {
|
|
98
|
+
return {
|
|
99
|
+
operation: opts.lowerCase ? HAS_TO_LOWER_CASE : HAS,
|
|
100
|
+
type: op === '!has' ? TYPE_NEGATE : TYPE_DEFAULT,
|
|
101
|
+
opts,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (op === '>') {
|
|
105
|
+
return { operation: GREATER_THAN, opts, type: TYPE_DEFAULT };
|
|
106
|
+
}
|
|
107
|
+
if (op === '<') {
|
|
108
|
+
return { operation: SMALLER_THAN, opts, type: TYPE_DEFAULT };
|
|
109
|
+
}
|
|
110
|
+
if (op === '>=') {
|
|
111
|
+
return { operation: GREATER_THAN_INCLUSIVE, opts, type: TYPE_DEFAULT };
|
|
112
|
+
}
|
|
113
|
+
if (op === '<=') {
|
|
114
|
+
return { operation: SMALLER_THAN_INCLUSIVE, opts, type: TYPE_DEFAULT };
|
|
115
|
+
}
|
|
116
|
+
if (op === 'like') {
|
|
117
|
+
return { operation: LIKE, opts, type: TYPE_DEFAULT };
|
|
118
|
+
}
|
|
119
|
+
throw new Error('Invalid filter operator');
|
|
120
|
+
};
|
|
7
121
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { PropDef, PropDefEdge } from '../../../server/schema/types.js';
|
|
2
2
|
import { QueryDef } from '../types.js';
|
|
3
3
|
export declare const getAll: (props: QueryDef["props"]) => string[];
|
|
4
|
+
export declare const getAllRefs: (props: QueryDef["props"], affix?: string) => string[];
|
|
5
|
+
export declare const includeField: (def: QueryDef, field: string) => void;
|
|
4
6
|
export declare const includeFields: (def: QueryDef, fields: string[]) => void;
|
|
5
7
|
export declare const includeAllProps: (def: QueryDef) => void;
|
|
6
8
|
export declare const includeProp: (def: QueryDef, prop: PropDef | PropDefEdge) => boolean;
|
|
@@ -9,14 +9,33 @@ export const getAll = (props) => {
|
|
|
9
9
|
}
|
|
10
10
|
return fields;
|
|
11
11
|
};
|
|
12
|
+
export const getAllRefs = (props, affix = '') => {
|
|
13
|
+
const fields = [];
|
|
14
|
+
for (const key in props) {
|
|
15
|
+
const prop = props[key];
|
|
16
|
+
if (prop.typeIndex === REFERENCE || prop.typeIndex === REFERENCES) {
|
|
17
|
+
fields.push(prop.path.join('.') + affix);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return fields;
|
|
21
|
+
};
|
|
22
|
+
export const includeField = (def, field) => {
|
|
23
|
+
if (field === '*') {
|
|
24
|
+
includeFields(def, getAll(def.props));
|
|
25
|
+
}
|
|
26
|
+
else if (field === '**') {
|
|
27
|
+
includeFields(def, getAllRefs(def.props));
|
|
28
|
+
}
|
|
29
|
+
else if (field.startsWith('**.')) {
|
|
30
|
+
includeFields(def, getAllRefs(def.props, field.substring(2)));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
def.include.stringFields.add(field);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
12
36
|
export const includeFields = (def, fields) => {
|
|
13
37
|
for (const field of fields) {
|
|
14
|
-
|
|
15
|
-
includeFields(def, getAll(def.props));
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
def.include.stringFields.add(field);
|
|
19
|
-
}
|
|
38
|
+
includeField(def, field);
|
|
20
39
|
}
|
|
21
40
|
};
|
|
22
41
|
export const includeAllProps = (def) => {
|
|
@@ -5,7 +5,8 @@ export const includeToBuffer = (db, def) => {
|
|
|
5
5
|
if (!def.include.stringFields.size &&
|
|
6
6
|
!def.include.props.size &&
|
|
7
7
|
!def.references.size &&
|
|
8
|
-
!def.include.main.len
|
|
8
|
+
!def.include.main.len &&
|
|
9
|
+
!def.include.langTextFields.size) {
|
|
9
10
|
return result;
|
|
10
11
|
}
|
|
11
12
|
let mainBuffer;
|
|
@@ -46,6 +47,25 @@ export const includeToBuffer = (db, def) => {
|
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
}
|
|
50
|
+
if (def.include.langTextFields.size) {
|
|
51
|
+
for (const [prop, langCode] of def.include.langTextFields.entries()) {
|
|
52
|
+
def.include.propsRead[prop] = 0;
|
|
53
|
+
if (langCode.has(0)) {
|
|
54
|
+
const b = Buffer.allocUnsafe(2);
|
|
55
|
+
b[0] = prop;
|
|
56
|
+
b[1] = 0;
|
|
57
|
+
result.push(b);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
for (const code of langCode) {
|
|
61
|
+
const b = Buffer.allocUnsafe(2);
|
|
62
|
+
b[0] = prop;
|
|
63
|
+
b[1] = code;
|
|
64
|
+
result.push(b);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
49
69
|
const propSize = def.include.props.size ?? 0;
|
|
50
70
|
if (mainBuffer) {
|
|
51
71
|
len = mainBuffer.byteLength + 3 + propSize;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { isPropDef, REFERENCE, REFERENCES, } from '../../../server/schema/types.js';
|
|
1
|
+
import { isPropDef, REFERENCE, REFERENCES, TEXT, } from '../../../server/schema/types.js';
|
|
2
2
|
import { createQueryDef } from '../queryDef.js';
|
|
3
3
|
import { isRefDef, QueryDefType } from '../types.js';
|
|
4
4
|
import { getAllFieldFromObject, createOrGetRefQueryDef } from './utils.js';
|
|
5
5
|
import { includeFields, includeProp, includeAllProps } from './props.js';
|
|
6
|
+
import { langCodesMap } from '@based/schema';
|
|
6
7
|
export const walkDefs = (db, def, f) => {
|
|
7
8
|
const prop = def.props[f];
|
|
8
9
|
const path = f.split('.');
|
|
@@ -41,7 +42,15 @@ export const walkDefs = (db, def, f) => {
|
|
|
41
42
|
if (!t) {
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
44
|
-
if (isPropDef(t) &&
|
|
45
|
+
if (isPropDef(t) && t.typeIndex === TEXT) {
|
|
46
|
+
const langCode = langCodesMap.get(path[path.length - 1]);
|
|
47
|
+
if (!def.include.langTextFields.has(t.prop)) {
|
|
48
|
+
def.include.langTextFields.set(t.prop, new Set());
|
|
49
|
+
}
|
|
50
|
+
def.include.langTextFields.get(t.prop).add(langCode);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
else if (isPropDef(t) &&
|
|
45
54
|
(t.typeIndex === REFERENCE || t.typeIndex === REFERENCES)) {
|
|
46
55
|
const refDef = createOrGetRefQueryDef(db, def, t);
|
|
47
56
|
const f = path.slice(i + 1).join('.');
|
|
@@ -64,6 +73,12 @@ export const walkDefs = (db, def, f) => {
|
|
|
64
73
|
includeAllProps(refDef);
|
|
65
74
|
return;
|
|
66
75
|
}
|
|
76
|
+
else if (prop.typeIndex === TEXT) {
|
|
77
|
+
if (!def.include.langTextFields.has(prop.prop)) {
|
|
78
|
+
def.include.langTextFields.set(prop.prop, new Set());
|
|
79
|
+
}
|
|
80
|
+
def.include.langTextFields.get(prop.prop).add(def.lang ?? 0);
|
|
81
|
+
}
|
|
67
82
|
else {
|
|
68
83
|
includeProp(def, prop);
|
|
69
84
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ALIAS, ALIASES, BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TEXT, TIMESTAMP, UINT16, UINT32, UINT8, VECTOR, } from '../../../server/schema/types.js';
|
|
1
|
+
import { ALIAS, ALIASES, BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TEXT, TIMESTAMP, UINT16, UINT32, UINT8, VECTOR, JSON, } from '../../../server/schema/types.js';
|
|
2
2
|
import { read, readUtf8 } from '../../string.js';
|
|
3
3
|
import { readDoubleLE, readFloatLE, readInt16, readInt32, readUint16, readUint32, } from '../../bitWise.js';
|
|
4
|
-
import { inverseLangMap
|
|
4
|
+
import { inverseLangMap } from '@based/schema';
|
|
5
5
|
const addField = (p, value, item, defaultOnly = false, lang = 0) => {
|
|
6
6
|
let i = p.__isEdge === true ? 1 : 0;
|
|
7
7
|
// TODO OPTMIZE
|
|
@@ -28,6 +28,35 @@ const addField = (p, value, item, defaultOnly = false, lang = 0) => {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
+
const getEmptyField = (p, item) => {
|
|
32
|
+
let i = p.__isEdge === true ? 1 : 0;
|
|
33
|
+
const path = p.path;
|
|
34
|
+
const len = path.length;
|
|
35
|
+
let select = item;
|
|
36
|
+
if (len - i === 1) {
|
|
37
|
+
const field = path[i];
|
|
38
|
+
if (!(field in item)) {
|
|
39
|
+
select = item[field] = {};
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return item[field];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
for (; i < len; i++) {
|
|
47
|
+
const field = path[i];
|
|
48
|
+
if (i === len - 1) {
|
|
49
|
+
if (!(field in select)) {
|
|
50
|
+
select = select[field] = {};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
select = select[field] ?? (select[field] = {});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return select;
|
|
59
|
+
};
|
|
31
60
|
const readMainValue = (prop, result, index, item) => {
|
|
32
61
|
// 1: timestamp, 4: number
|
|
33
62
|
if (prop.typeIndex === TIMESTAMP || prop.typeIndex === NUMBER) {
|
|
@@ -52,7 +81,7 @@ const readMainValue = (prop, result, index, item) => {
|
|
|
52
81
|
}
|
|
53
82
|
// 11: string
|
|
54
83
|
else if (prop.typeIndex === STRING) {
|
|
55
|
-
// Also
|
|
84
|
+
// Also delete this default then (same as other string)
|
|
56
85
|
const len = result[index];
|
|
57
86
|
if (len !== 0) {
|
|
58
87
|
const str = readUtf8(result, index + 1, len);
|
|
@@ -62,6 +91,10 @@ const readMainValue = (prop, result, index, item) => {
|
|
|
62
91
|
addField(prop, '', item);
|
|
63
92
|
}
|
|
64
93
|
}
|
|
94
|
+
// ?: json
|
|
95
|
+
else if (prop.typeIndex === JSON) {
|
|
96
|
+
addField(prop, global.JSON.parse(Buffer.from(result.subarray(index + 1, index + 1 + result[index])).toString()), item);
|
|
97
|
+
}
|
|
65
98
|
// 25: binary
|
|
66
99
|
else if (prop.typeIndex === BINARY) {
|
|
67
100
|
addField(prop, result.subarray(index + 1, index + 1 + result[index]), item);
|
|
@@ -109,7 +142,29 @@ const readMain = (q, result, offset, item) => {
|
|
|
109
142
|
const handleUndefinedProps = (id, q, item) => {
|
|
110
143
|
for (const k in q.include.propsRead) {
|
|
111
144
|
if (q.include.propsRead[k] !== id) {
|
|
112
|
-
|
|
145
|
+
const prop = q.schema.reverseProps[k];
|
|
146
|
+
if (prop.typeIndex === TEXT && q.lang == 0) {
|
|
147
|
+
const lan = getEmptyField(prop, item);
|
|
148
|
+
const lang = q.include.langTextFields.get(prop.prop);
|
|
149
|
+
if (lang.has(0)) {
|
|
150
|
+
for (const locale in q.schema.locales) {
|
|
151
|
+
if (!lan[locale]) {
|
|
152
|
+
lan[locale] = '';
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
for (const code of lang) {
|
|
158
|
+
const locale = inverseLangMap.get(code);
|
|
159
|
+
if (!lan[locale]) {
|
|
160
|
+
lan[locale] = '';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
addField(prop, prop.typeIndex === JSON ? null : '', item);
|
|
167
|
+
}
|
|
113
168
|
}
|
|
114
169
|
}
|
|
115
170
|
};
|
|
@@ -118,12 +173,15 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
118
173
|
while (i < end) {
|
|
119
174
|
const index = result[i];
|
|
120
175
|
i++;
|
|
176
|
+
// index:255 id
|
|
121
177
|
if (index === 255) {
|
|
122
178
|
handleUndefinedProps(id, q, item);
|
|
123
179
|
return i - offset;
|
|
124
180
|
}
|
|
181
|
+
// index:252 edge
|
|
125
182
|
if (index === 252) {
|
|
126
183
|
let prop = result[i];
|
|
184
|
+
// index:254 ref
|
|
127
185
|
if (prop === 254) {
|
|
128
186
|
i++;
|
|
129
187
|
const field = result[i];
|
|
@@ -148,6 +206,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
148
206
|
addField(ref.target.propDef, refItem, item);
|
|
149
207
|
i += size - 5;
|
|
150
208
|
}
|
|
209
|
+
// index:253 refs
|
|
151
210
|
}
|
|
152
211
|
else if (prop === 253) {
|
|
153
212
|
i++;
|
|
@@ -165,7 +224,13 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
165
224
|
else {
|
|
166
225
|
const edgeDef = q.edges.reverseProps[prop];
|
|
167
226
|
const t = edgeDef.typeIndex;
|
|
168
|
-
if (t ===
|
|
227
|
+
if (t === JSON) {
|
|
228
|
+
i++;
|
|
229
|
+
const size = readUint32(result, i);
|
|
230
|
+
addField(edgeDef, global.JSON.parse(Buffer.from(result.subarray(i + 6, size + i)).toString()), item);
|
|
231
|
+
i += size + 4;
|
|
232
|
+
}
|
|
233
|
+
else if (t === BINARY) {
|
|
169
234
|
i++;
|
|
170
235
|
const size = readUint32(result, i);
|
|
171
236
|
addField(edgeDef, result.subarray(i + 6, size + i), item);
|
|
@@ -188,6 +253,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
188
253
|
i += edgeDef.len;
|
|
189
254
|
}
|
|
190
255
|
}
|
|
256
|
+
// index:254 ref
|
|
191
257
|
}
|
|
192
258
|
else if (index === 254) {
|
|
193
259
|
const field = result[i];
|
|
@@ -212,6 +278,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
212
278
|
addField(ref.target.propDef, refItem, item);
|
|
213
279
|
i += size - 5;
|
|
214
280
|
}
|
|
281
|
+
// index:253 refs
|
|
215
282
|
}
|
|
216
283
|
else if (index === 253) {
|
|
217
284
|
const field = result[i];
|
|
@@ -229,7 +296,13 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
229
296
|
}
|
|
230
297
|
else {
|
|
231
298
|
const prop = q.schema.reverseProps[index];
|
|
232
|
-
if (prop.typeIndex ===
|
|
299
|
+
if (prop.typeIndex === JSON) {
|
|
300
|
+
q.include.propsRead[index] = id;
|
|
301
|
+
const size = readUint32(result, i);
|
|
302
|
+
addField(prop, global.JSON.parse(Buffer.from(result.subarray(i + 6, i + size)).toString()), item);
|
|
303
|
+
i += size + 4;
|
|
304
|
+
}
|
|
305
|
+
else if (prop.typeIndex === BINARY) {
|
|
233
306
|
q.include.propsRead[index] = id;
|
|
234
307
|
const size = readUint32(result, i);
|
|
235
308
|
addField(prop, result.subarray(i + 6, i + size), item);
|
|
@@ -247,29 +320,20 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
247
320
|
i += size + 4;
|
|
248
321
|
}
|
|
249
322
|
else if (prop.typeIndex == TEXT) {
|
|
250
|
-
q.include.propsRead[index] = id;
|
|
251
323
|
const size = readUint32(result, i);
|
|
252
|
-
// if queryDef.LANG do different
|
|
253
324
|
if (size === 0) {
|
|
254
|
-
// LATER
|
|
255
|
-
// addField(prop, '', item)
|
|
256
325
|
}
|
|
257
326
|
else {
|
|
258
|
-
if (q.lang !=
|
|
327
|
+
if (q.lang != 0) {
|
|
328
|
+
q.include.propsRead[index] = id;
|
|
259
329
|
addField(prop, read(result, i + 4, size), item);
|
|
260
330
|
}
|
|
261
331
|
else {
|
|
332
|
+
// q.include.propsRead[index] = id
|
|
262
333
|
addField(prop, read(result, i + 4, size), item, false, result[i + 4]);
|
|
263
334
|
}
|
|
264
335
|
}
|
|
265
|
-
|
|
266
|
-
// TODO Read text
|
|
267
|
-
//if (size === 0) {
|
|
268
|
-
// addField(prop, '', item)
|
|
269
|
-
//} else {
|
|
270
|
-
// addField(prop, read(result, i + 4, size), item)
|
|
271
|
-
//}
|
|
272
|
-
(i += size + 4);
|
|
336
|
+
i += size + 4;
|
|
273
337
|
}
|
|
274
338
|
else if (prop.typeIndex === ALIAS) {
|
|
275
339
|
q.include.propsRead[index] = id;
|
|
@@ -314,8 +378,8 @@ export const resultToObject = (q, result, end, offset = 0) => {
|
|
|
314
378
|
id,
|
|
315
379
|
};
|
|
316
380
|
if (q.search) {
|
|
317
|
-
item.$searchScore = result
|
|
318
|
-
i +=
|
|
381
|
+
item.$searchScore = readFloatLE(result, i);
|
|
382
|
+
i += 4;
|
|
319
383
|
}
|
|
320
384
|
const l = readAllFields(q, result, i, end, item, id);
|
|
321
385
|
i += l;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { QueryDefSearch, QueryDef } from '../types.js';
|
|
2
|
+
import { FilterOpts } from '../filter/types.js';
|
|
2
3
|
export type Search = string[] | {
|
|
3
4
|
[field: string]: number;
|
|
4
5
|
} | string;
|
|
6
|
+
export declare const vectorSearch: (def: QueryDef, q: ArrayBufferView, field: string, opts: Omit<FilterOpts, "lowerCase">) => void;
|
|
5
7
|
export declare const search: (def: QueryDef, q: string, s?: Search) => void;
|
|
6
8
|
export declare const searchToBuffer: (search: QueryDefSearch) => Buffer;
|