@based/db 0.0.15 → 0.0.17
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/selva/db.h +3 -0
- package/dist/lib/darwin_aarch64/include/selva/fields.h +1 -2
- package/dist/lib/darwin_aarch64/include/selva/history.h +16 -1
- package/dist/lib/darwin_aarch64/include/selva/hll.h +2 -1
- package/dist/lib/darwin_aarch64/include/selva/types.h +4 -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/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +3 -0
- package/dist/lib/linux_aarch64/include/selva/fields.h +1 -2
- package/dist/lib/linux_aarch64/include/selva/history.h +16 -1
- package/dist/lib/linux_aarch64/include/selva/hll.h +2 -1
- package/dist/lib/linux_aarch64/include/selva/types.h +4 -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 +3 -0
- package/dist/lib/linux_x86_64/include/selva/fields.h +1 -2
- package/dist/lib/linux_x86_64/include/selva/history.h +16 -1
- package/dist/lib/linux_x86_64/include/selva/hll.h +2 -1
- package/dist/lib/linux_x86_64/include/selva/types.h +4 -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 +1 -0
- package/dist/src/client/crc32.js +0 -276
- package/dist/src/client/modify/ModifyRes.d.ts +4 -2
- package/dist/src/client/modify/ModifyRes.js +11 -6
- package/dist/src/client/modify/alias.js +2 -2
- package/dist/src/client/modify/cardinality.js +14 -10
- package/dist/src/client/modify/create.js +8 -9
- package/dist/src/client/modify/references/reference.js +14 -7
- package/dist/src/client/modify/references/references.js +10 -4
- package/dist/src/client/modify/string.js +2 -2
- package/dist/src/client/modify/text.js +1 -1
- package/dist/src/client/modify/types.d.ts +3 -1
- package/dist/src/client/modify/types.js +2 -0
- package/dist/src/client/modify/update.js +1 -1
- package/dist/src/client/operations.d.ts +2 -2
- package/dist/src/client/operations.js +19 -3
- package/dist/src/client/query/BasedDbQuery.d.ts +5 -4
- package/dist/src/client/query/BasedDbQuery.js +28 -13
- package/dist/src/client/query/BasedIterable.js +3 -10
- package/dist/src/client/query/display.d.ts +6 -0
- package/dist/src/client/query/display.js +63 -4
- package/dist/src/client/query/filter/FilterBranch.js +8 -3
- package/dist/src/client/query/filter/convertFilter.d.ts +4 -0
- package/dist/src/client/query/filter/convertFilter.js +56 -0
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +9 -8
- package/dist/src/client/query/filter/createReferenceFilter.js +5 -4
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +6 -10
- package/dist/src/client/query/filter/filter.d.ts +1 -2
- package/dist/src/client/query/filter/filter.js +5 -56
- package/dist/src/client/query/filter/primitiveFilter.d.ts +2 -2
- package/dist/src/client/query/filter/primitiveFilter.js +5 -1
- package/dist/src/client/query/filter/toBuffer.js +1 -6
- package/dist/src/client/query/filter/types.d.ts +2 -1
- package/dist/src/client/query/filter/types.js +23 -12
- package/dist/src/client/query/include/props.js +14 -6
- package/dist/src/client/query/include/utils.js +2 -2
- package/dist/src/client/query/include/walk.js +1 -7
- package/dist/src/client/query/queryDef.d.ts +1 -1
- package/dist/src/client/query/queryDef.js +4 -3
- package/dist/src/client/query/read/read.js +21 -32
- package/dist/src/client/query/read/types.d.ts +4 -0
- package/dist/src/client/query/read/types.js +5 -0
- package/dist/src/client/query/registerQuery.js +1 -0
- package/dist/src/client/query/search/index.js +12 -6
- package/dist/src/client/query/sort.js +7 -6
- package/dist/src/client/query/thresholds.d.ts +0 -1
- package/dist/src/client/query/thresholds.js +0 -8
- package/dist/src/client/query/toBuffer.js +0 -3
- package/dist/src/client/query/types.d.ts +2 -0
- package/dist/src/client/query/validation.d.ts +39 -1
- package/dist/src/client/query/validation.js +299 -93
- package/dist/src/client/xxHash64.d.ts +1 -1
- package/dist/src/client/xxHash64.js +7 -2
- package/dist/src/index.d.ts +6 -1
- package/dist/src/index.js +31 -1
- package/dist/src/native.d.ts +3 -1
- package/dist/src/native.js +8 -2
- package/dist/src/server/index.d.ts +8 -6
- package/dist/src/server/index.js +56 -30
- package/dist/src/server/migrate/index.js +10 -2
- package/dist/src/server/migrate/worker.js +1 -1
- package/dist/src/server/schema/typeDef.js +35 -25
- package/dist/src/server/schema/types.d.ts +10 -5
- package/dist/src/server/schema/types.js +1 -1
- package/dist/src/server/schema/utils.d.ts +1 -0
- package/dist/src/server/schema/utils.js +18 -5
- package/package.json +5 -3
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { QueryDef } from '../types.js';
|
|
2
|
+
import { Operator } from './filter.js';
|
|
3
|
+
import { FilterOpts, FilterAst } from './types.js';
|
|
4
|
+
export declare const convertFilter: (def: QueryDef, field: string, operator?: Operator | boolean, value?: any, opts?: FilterOpts | undefined) => FilterAst;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { toFilterCtx } from './types.js';
|
|
2
|
+
const normalizeNeedle = (s) => {
|
|
3
|
+
return s
|
|
4
|
+
.normalize('NFKD')
|
|
5
|
+
.split('')
|
|
6
|
+
.filter((ch) => ch.charCodeAt(0) <= 127)
|
|
7
|
+
.join('');
|
|
8
|
+
};
|
|
9
|
+
export const convertFilter = (def, field, operator, value, opts) => {
|
|
10
|
+
if (operator === undefined) {
|
|
11
|
+
operator = '=';
|
|
12
|
+
value = true;
|
|
13
|
+
}
|
|
14
|
+
else if (typeof operator === 'boolean') {
|
|
15
|
+
value = operator;
|
|
16
|
+
operator = '=';
|
|
17
|
+
}
|
|
18
|
+
if (value === '' || value === undefined) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (operator === '!..') {
|
|
22
|
+
return [
|
|
23
|
+
[field, toFilterCtx(def, '>', opts), value[1]],
|
|
24
|
+
[field, toFilterCtx(def, '<', opts), value[0]],
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
else if (operator === '..') {
|
|
28
|
+
return [
|
|
29
|
+
[field, toFilterCtx(def, '>', opts), value[0]],
|
|
30
|
+
[field, toFilterCtx(def, '<', opts), value[1]],
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (operator == 'like') {
|
|
35
|
+
if (value == null) {
|
|
36
|
+
throw new Error('Value is required');
|
|
37
|
+
}
|
|
38
|
+
if (value?.normalize) {
|
|
39
|
+
value = normalizeNeedle(value);
|
|
40
|
+
}
|
|
41
|
+
else if (Array.isArray(value)) {
|
|
42
|
+
if (value[0]?.normalize) {
|
|
43
|
+
value = value.map(normalizeNeedle);
|
|
44
|
+
}
|
|
45
|
+
else if (value[0]?.BYTES_PER_ELEMENT > 1) {
|
|
46
|
+
value = value.map((v) => v.buffer);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (value?.BYTES_PER_ELEMENT > 1) {
|
|
50
|
+
value = value.buffer;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return [[field, toFilterCtx(def, operator, opts), value]];
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=convertFilter.js.map
|
|
@@ -70,10 +70,11 @@ export const createFixedFilterBuffer = (prop, size, ctx, value, sort) => {
|
|
|
70
70
|
prop.typeIndex === REFERENCES && ctx.operation === EQUAL
|
|
71
71
|
? MODE_AND_FIXED
|
|
72
72
|
: MODE_OR_FIXED;
|
|
73
|
-
buf.
|
|
74
|
-
buf.writeUInt16LE(
|
|
75
|
-
buf
|
|
76
|
-
buf[7] =
|
|
73
|
+
buf[2] = prop.typeIndex;
|
|
74
|
+
buf.writeUInt16LE(size, 3);
|
|
75
|
+
buf.writeUInt16LE(start, 5);
|
|
76
|
+
buf[7] = ctx.operation;
|
|
77
|
+
// buf[7] = prop.typeIndex
|
|
77
78
|
buf.writeUInt16LE(len, 8);
|
|
78
79
|
if (sort) {
|
|
79
80
|
value = new Uint32Array(value.map((v) => parseFilterValue(prop, v)));
|
|
@@ -93,10 +94,10 @@ export const createFixedFilterBuffer = (prop, size, ctx, value, sort) => {
|
|
|
93
94
|
buf = Buffer.allocUnsafe(8 + size);
|
|
94
95
|
buf[0] = ctx.type;
|
|
95
96
|
buf[1] = MODE_DEFAULT;
|
|
96
|
-
buf.
|
|
97
|
-
buf.writeUInt16LE(
|
|
98
|
-
buf
|
|
99
|
-
buf[7] =
|
|
97
|
+
buf[2] = prop.typeIndex;
|
|
98
|
+
buf.writeUInt16LE(size, 3);
|
|
99
|
+
buf.writeUInt16LE(start, 5);
|
|
100
|
+
buf[7] = ctx.operation;
|
|
100
101
|
writeFixed(prop, buf, parseFilterValue(prop, value), size, 8);
|
|
101
102
|
}
|
|
102
103
|
return buf;
|
|
@@ -5,10 +5,11 @@ export const createReferenceFilter = (prop, ctx, value) => {
|
|
|
5
5
|
buf = Buffer.allocUnsafe(11 + len * 8);
|
|
6
6
|
buf[0] = ctx.type;
|
|
7
7
|
buf[1] = MODE_REFERENCE;
|
|
8
|
-
buf.
|
|
9
|
-
buf.writeUInt16LE(
|
|
10
|
-
buf
|
|
11
|
-
buf[7] =
|
|
8
|
+
buf[2] = prop.typeIndex;
|
|
9
|
+
buf.writeUInt16LE(8, 3);
|
|
10
|
+
buf.writeUInt16LE(len, 5);
|
|
11
|
+
buf[7] = ctx.operation;
|
|
12
|
+
// buf[7] = prop.typeIndex
|
|
12
13
|
// REF TYPE (only 1 exists now...)
|
|
13
14
|
buf[8] = 0;
|
|
14
15
|
buf.writeUInt16LE(prop.inverseTypeId, 9);
|
|
@@ -40,7 +40,7 @@ const parseValue = (value, prop, ctx, lang) => {
|
|
|
40
40
|
// @ts-ignore
|
|
41
41
|
val = Buffer.concat([val, Buffer.from([ctx.opts.score ?? 2])]);
|
|
42
42
|
}
|
|
43
|
-
// @ts-ignore
|
|
43
|
+
// @ts-ignore
|
|
44
44
|
return val;
|
|
45
45
|
};
|
|
46
46
|
export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
@@ -70,7 +70,6 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
|
70
70
|
else {
|
|
71
71
|
val = parseValue(value, prop, ctx, lang);
|
|
72
72
|
}
|
|
73
|
-
// -------------------- PUT VARIABLES HERE
|
|
74
73
|
if (ctx.operation === EQUAL ||
|
|
75
74
|
ctx.operation === HAS ||
|
|
76
75
|
ctx.operation === LIKE ||
|
|
@@ -98,9 +97,6 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
|
|
|
98
97
|
buf = writeVarFilter(mode, val, ctx, prop, prop.start, prop.len);
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
|
-
else {
|
|
102
|
-
console.log('OP NOT SUPPORTED YET =>', ctx);
|
|
103
|
-
}
|
|
104
100
|
return buf;
|
|
105
101
|
};
|
|
106
102
|
function writeVarFilter(mode, val, ctx, prop, start, len) {
|
|
@@ -108,11 +104,11 @@ function writeVarFilter(mode, val, ctx, prop, start, len) {
|
|
|
108
104
|
const buf = Buffer.allocUnsafe(12 + size);
|
|
109
105
|
buf[0] = ctx.type;
|
|
110
106
|
buf[1] = mode;
|
|
111
|
-
buf.
|
|
112
|
-
buf.
|
|
113
|
-
buf.
|
|
114
|
-
buf
|
|
115
|
-
buf[11] =
|
|
107
|
+
buf[2] = prop.typeIndex;
|
|
108
|
+
buf.writeUInt16LE(start, 3);
|
|
109
|
+
buf.writeUint16LE(len, 5);
|
|
110
|
+
buf.writeUint32LE(size, 7);
|
|
111
|
+
buf[11] = ctx.operation;
|
|
116
112
|
// need to pas LANG FROM QUERY
|
|
117
113
|
// need to set on 12 if TEXT
|
|
118
114
|
buf.set(Buffer.from(val), 12);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { QueryDef, QueryDefFilter } from '../types.js';
|
|
2
2
|
import { SchemaTypeDef } from '../../../server/schema/schema.js';
|
|
3
|
-
import {
|
|
3
|
+
import { Operator } from './types.js';
|
|
4
4
|
import { Filter, FilterAst } from './types.js';
|
|
5
5
|
import { DbClient } from '../../index.js';
|
|
6
6
|
export { Operator, Filter };
|
|
7
7
|
export declare const filterRaw: (db: DbClient, filter: Filter, schema: SchemaTypeDef, conditions: QueryDefFilter, def: QueryDef) => number;
|
|
8
8
|
export declare const filter: (db: DbClient, def: QueryDef, filterAst: FilterAst, conditions: QueryDefFilter) => void;
|
|
9
9
|
export declare const filterOr: (db: DbClient, def: QueryDef, filterAst: FilterAst[], conditions: QueryDefFilter) => QueryDefFilter;
|
|
10
|
-
export declare const convertFilter: (def: QueryDef, field: string, operator?: Operator | boolean, value?: any, opts?: FilterOpts) => FilterAst;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isPropDef, ID_FIELD_DEF, TEXT, REFERENCE, } from '../../../server/schema/schema.js';
|
|
2
2
|
import { primitiveFilter } from './primitiveFilter.js';
|
|
3
|
-
import { toFilterCtx } from './types.js';
|
|
4
3
|
import { IsFilter } from './types.js';
|
|
5
4
|
import { langCodesMap } from '@based/schema';
|
|
6
5
|
import { filterFieldDoesNotExist, filterInvalidLang } from '../validation.js';
|
|
@@ -22,7 +21,8 @@ const referencesFilter = (db, filter, schema, conditions, def) => {
|
|
|
22
21
|
const edgeDef = edges[p];
|
|
23
22
|
if (edgeDef) {
|
|
24
23
|
conditions.edges ??= new Map();
|
|
25
|
-
size +=
|
|
24
|
+
size +=
|
|
25
|
+
3 + primitiveFilter(def, edgeDef, filter, conditions, def.lang);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -71,16 +71,16 @@ export const filterRaw = (db, filter, schema, conditions, def) => {
|
|
|
71
71
|
filterInvalidLang(def, field);
|
|
72
72
|
return 0;
|
|
73
73
|
}
|
|
74
|
-
return primitiveFilter(fieldDef, filter, conditions, code);
|
|
74
|
+
return primitiveFilter(def, fieldDef, filter, conditions, code);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
if (field === 'id') {
|
|
78
78
|
fieldDef = ID_FIELD_DEF;
|
|
79
|
-
return primitiveFilter(fieldDef, filter, conditions, def.lang);
|
|
79
|
+
return primitiveFilter(def, fieldDef, filter, conditions, def.lang);
|
|
80
80
|
}
|
|
81
81
|
return referencesFilter(db, filter, schema, conditions, def);
|
|
82
82
|
}
|
|
83
|
-
return primitiveFilter(fieldDef, filter, conditions, def.lang);
|
|
83
|
+
return primitiveFilter(def, fieldDef, filter, conditions, def.lang);
|
|
84
84
|
};
|
|
85
85
|
export const filter = (db, def, filterAst, conditions) => {
|
|
86
86
|
for (const f of filterAst) {
|
|
@@ -104,55 +104,4 @@ export const filterOr = (db, def, filterAst, conditions) => {
|
|
|
104
104
|
conditions.size += conditions.or.size;
|
|
105
105
|
return conditions.or;
|
|
106
106
|
};
|
|
107
|
-
const normalizeNeedle = (s) => {
|
|
108
|
-
return s
|
|
109
|
-
.normalize('NFKD')
|
|
110
|
-
.split('')
|
|
111
|
-
.filter((ch) => ch.charCodeAt(0) <= 127)
|
|
112
|
-
.join('');
|
|
113
|
-
};
|
|
114
|
-
export const convertFilter = (def, field, operator, value, opts) => {
|
|
115
|
-
if (operator === undefined) {
|
|
116
|
-
operator = '=';
|
|
117
|
-
value = true;
|
|
118
|
-
}
|
|
119
|
-
else if (typeof operator === 'boolean') {
|
|
120
|
-
value = operator;
|
|
121
|
-
operator = '=';
|
|
122
|
-
}
|
|
123
|
-
if (operator === '!..') {
|
|
124
|
-
return [
|
|
125
|
-
[field, toFilterCtx(def, '>', opts), value[1]],
|
|
126
|
-
[field, toFilterCtx(def, '<', opts), value[0]],
|
|
127
|
-
];
|
|
128
|
-
}
|
|
129
|
-
else if (operator === '..') {
|
|
130
|
-
return [
|
|
131
|
-
[field, toFilterCtx(def, '>', opts), value[0]],
|
|
132
|
-
[field, toFilterCtx(def, '<', opts), value[1]],
|
|
133
|
-
];
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
if (operator == 'like') {
|
|
137
|
-
if (value == null) {
|
|
138
|
-
throw new Error('Value is required');
|
|
139
|
-
}
|
|
140
|
-
if (value?.normalize) {
|
|
141
|
-
value = normalizeNeedle(value);
|
|
142
|
-
}
|
|
143
|
-
else if (Array.isArray(value)) {
|
|
144
|
-
if (value[0]?.normalize) {
|
|
145
|
-
value = value.map(normalizeNeedle);
|
|
146
|
-
}
|
|
147
|
-
else if (value[0]?.BYTES_PER_ELEMENT > 1) {
|
|
148
|
-
value = value.map((v) => v.buffer);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
else if (value?.BYTES_PER_ELEMENT > 1) {
|
|
152
|
-
value = value.buffer;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return [[field, toFilterCtx(def, operator, opts), value]];
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
107
|
//# sourceMappingURL=filter.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PropDef, PropDefEdge } from '../../../server/schema/types.js';
|
|
2
|
-
import { QueryDefFilter } from '../types.js';
|
|
2
|
+
import { QueryDef, QueryDefFilter } from '../types.js';
|
|
3
3
|
import { Filter } from './types.js';
|
|
4
4
|
import { LangCode } from '@based/schema';
|
|
5
|
-
export declare const primitiveFilter: (prop: PropDef | PropDefEdge, filter: Filter, conditions: QueryDefFilter, lang: LangCode) => number;
|
|
5
|
+
export declare const primitiveFilter: (def: QueryDef, prop: PropDef | PropDefEdge, filter: Filter, conditions: QueryDefFilter, lang: LangCode) => number;
|
|
@@ -3,7 +3,11 @@ 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
|
-
|
|
6
|
+
import { validateFilter } from '../validation.js';
|
|
7
|
+
export const primitiveFilter = (def, prop, filter, conditions, lang) => {
|
|
8
|
+
if (validateFilter(def, prop, filter)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
7
11
|
let [, ctx, value] = filter;
|
|
8
12
|
const fieldIndexChar = prop.prop;
|
|
9
13
|
let buf;
|
|
@@ -9,20 +9,15 @@ import { META_EDGE, META_OR_BRANCH, META_REFERENCE } from './types.js';
|
|
|
9
9
|
// [meta = 254] [field] [typeId 2] [size 2]
|
|
10
10
|
// -------------------------------------------
|
|
11
11
|
// conditions normal
|
|
12
|
-
// field, [size 2]
|
|
13
|
-
// [or = 0] [size 2] [start 2], [op] [typeIndex], value[size]
|
|
14
12
|
// -------------------------------------------
|
|
15
13
|
// conditions or fixed
|
|
16
|
-
// field, [size 2]
|
|
17
|
-
// [or = 1] [size 2] [start 2] [op] [typeIndex], [repeat 2], value[size] value[size] value[size]
|
|
18
14
|
// -------------------------------------------
|
|
19
15
|
// conditions or variable
|
|
20
|
-
// field, [size 2]
|
|
21
|
-
// [or = 2] [size 2] [start 2], [op] [typeIndex], [size 2], value[size], [size 2], value[size]
|
|
22
16
|
// -------------------------------------------
|
|
23
17
|
const writeConditions = (result, k, offset, conditions) => {
|
|
24
18
|
let lastWritten = offset;
|
|
25
19
|
result[lastWritten] = k;
|
|
20
|
+
// result[lasWritten + 1] = typeIndex
|
|
26
21
|
lastWritten++;
|
|
27
22
|
const sizeIndex = lastWritten;
|
|
28
23
|
lastWritten += 2;
|
|
@@ -4,8 +4,8 @@ export type Filter = [fieldStr: string, ctx: FilterCtx, value: any];
|
|
|
4
4
|
export type FilterBranchFn = (filterBranch: FilterBranch) => void;
|
|
5
5
|
export type FilterAst = (Filter | FilterAst)[];
|
|
6
6
|
export declare const IsFilter: (f: FilterAst) => f is Filter;
|
|
7
|
-
export declare const validOperators: readonly ["=", "has", "!has", "<", ">", "!=", "like", ">=", "<=", "..", "!.."];
|
|
8
7
|
export type Operator = '=' | 'has' | '!has' | '<' | '>' | '!=' | 'like' | '>=' | '<=' | '..' | '!..' | 'like';
|
|
8
|
+
export declare const VECTOR_FNS: string[];
|
|
9
9
|
export type FilterOpts<O = Operator> = {
|
|
10
10
|
lowerCase?: boolean;
|
|
11
11
|
fn?: 'dotProduct' | 'manhattanDistance' | 'cosineSimilarity' | 'euclideanDistance';
|
|
@@ -54,3 +54,4 @@ export declare const VECTOR_COSTINE_SIMILARITY = 2;
|
|
|
54
54
|
export declare const VECTOR_EUCLIDEAN_DIST = 3;
|
|
55
55
|
export declare const getVectorFn: (optsFn?: FilterOpts["fn"]) => 0 | 1 | 2 | 3;
|
|
56
56
|
export declare const toFilterCtx: (def: QueryDef, op: Operator, opts?: FilterOpts) => FilterCtx;
|
|
57
|
+
export declare const operatorReverseMap: Record<OPERATOR, string>;
|
|
@@ -5,18 +5,11 @@ export const IsFilter = (f) => {
|
|
|
5
5
|
}
|
|
6
6
|
return false;
|
|
7
7
|
};
|
|
8
|
-
export const
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'>',
|
|
14
|
-
'!=',
|
|
15
|
-
'like',
|
|
16
|
-
'>=',
|
|
17
|
-
'<=',
|
|
18
|
-
'..',
|
|
19
|
-
'!..',
|
|
8
|
+
export const VECTOR_FNS = [
|
|
9
|
+
'dotProduct',
|
|
10
|
+
'manhattanDistance',
|
|
11
|
+
'cosineSimilarity',
|
|
12
|
+
'euclideanDistance',
|
|
20
13
|
];
|
|
21
14
|
// -------------------------------------------
|
|
22
15
|
// operations shared
|
|
@@ -119,4 +112,22 @@ export const toFilterCtx = (def, op, opts = {}) => {
|
|
|
119
112
|
}
|
|
120
113
|
filterOperatorDoesNotExist(def, op);
|
|
121
114
|
};
|
|
115
|
+
export const operatorReverseMap = {
|
|
116
|
+
[EQUAL]: '=',
|
|
117
|
+
[HAS]: 'has',
|
|
118
|
+
[ENDS_WITH]: 'endsWith',
|
|
119
|
+
[STARTS_WITH]: 'startsWith',
|
|
120
|
+
[GREATER_THAN]: '>',
|
|
121
|
+
[SMALLER_THAN]: '<',
|
|
122
|
+
[GREATER_THAN_INCLUSIVE]: '>=',
|
|
123
|
+
[SMALLER_THAN_INCLUSIVE]: '<=',
|
|
124
|
+
[RANGE]: '..',
|
|
125
|
+
[RANGE_EXCLUDE]: '!..',
|
|
126
|
+
[EQUAL_LOWER_CASE]: '= (lowerCase)',
|
|
127
|
+
[HAS_TO_LOWER_CASE]: 'has (lowerCase)',
|
|
128
|
+
[STARTS_WITH_LOWER_CASE]: 'startsWith (lowerCase)',
|
|
129
|
+
[ENDS_WITH_LOWER_CASE]: 'endsWith (lowerCase)',
|
|
130
|
+
[LIKE]: 'like',
|
|
131
|
+
[EQUAL_CRC32]: '= (crc32)',
|
|
132
|
+
};
|
|
122
133
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { REFERENCE, REFERENCES, } from '../../../server/schema/types.js';
|
|
1
|
+
import { REFERENCE, REFERENCES, TEXT, } from '../../../server/schema/types.js';
|
|
2
2
|
export const getAll = (props) => {
|
|
3
3
|
const fields = [];
|
|
4
4
|
for (const key in props) {
|
|
@@ -50,13 +50,21 @@ export const includeProp = (def, prop) => {
|
|
|
50
50
|
if (!prop || prop.typeIndex === REFERENCE || prop.typeIndex === REFERENCES) {
|
|
51
51
|
return false;
|
|
52
52
|
}
|
|
53
|
-
if (prop.
|
|
54
|
-
def.include.
|
|
53
|
+
if (prop.typeIndex === TEXT) {
|
|
54
|
+
if (!def.include.langTextFields.has(prop.prop)) {
|
|
55
|
+
def.include.langTextFields.set(prop.prop, { def: prop, codes: new Set() });
|
|
56
|
+
}
|
|
57
|
+
def.include.langTextFields.get(prop.prop).codes.add(def.lang ?? 0);
|
|
55
58
|
}
|
|
56
59
|
else {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
if (prop.separate) {
|
|
61
|
+
def.include.props.set(prop.prop, prop);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
def.include.main.len += prop.len;
|
|
65
|
+
def.include.main.include[prop.start] = [0, prop];
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
60
68
|
}
|
|
61
69
|
return false;
|
|
62
70
|
};
|
|
@@ -19,7 +19,7 @@ const createRefQueryDef = (db, def, t) => {
|
|
|
19
19
|
: QueryDefType.References, {
|
|
20
20
|
type: t.inverseTypeName,
|
|
21
21
|
propDef: t,
|
|
22
|
-
});
|
|
22
|
+
}, def.skipValidation);
|
|
23
23
|
defRef.lang = def.lang;
|
|
24
24
|
def.references.set(t.prop, defRef);
|
|
25
25
|
return defRef;
|
|
@@ -33,7 +33,7 @@ export const createOrGetRefQueryDef = (db, def, t) => {
|
|
|
33
33
|
export const createOrGetEdgeRefQueryDef = (db, def, t) => {
|
|
34
34
|
def.edges ??= createQueryDef(db, QueryDefType.Edge, {
|
|
35
35
|
ref: t,
|
|
36
|
-
});
|
|
36
|
+
}, def.skipValidation);
|
|
37
37
|
def.edges.props ??= {};
|
|
38
38
|
def.edges.props[t.name] = t;
|
|
39
39
|
const refDef = createOrGetRefQueryDef(db, def.edges, t);
|
|
@@ -16,7 +16,7 @@ export const walkDefs = (db, def, f) => {
|
|
|
16
16
|
if (!def.edges) {
|
|
17
17
|
def.edges = createQueryDef(db, QueryDefType.Edge, {
|
|
18
18
|
ref: def.target.propDef,
|
|
19
|
-
});
|
|
19
|
+
}, def.skipValidation);
|
|
20
20
|
def.edges.lang = def.lang;
|
|
21
21
|
}
|
|
22
22
|
const edgeProp = def.edges.props[p];
|
|
@@ -82,12 +82,6 @@ export const walkDefs = (db, def, f) => {
|
|
|
82
82
|
includeAllProps(refDef);
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
else if (prop.typeIndex === TEXT) {
|
|
86
|
-
if (!def.include.langTextFields.has(prop.prop)) {
|
|
87
|
-
def.include.langTextFields.set(prop.prop, { def: prop, codes: new Set() });
|
|
88
|
-
}
|
|
89
|
-
def.include.langTextFields.get(prop.prop).codes.add(def.lang ?? 0);
|
|
90
|
-
}
|
|
91
85
|
else {
|
|
92
86
|
includeProp(def, prop);
|
|
93
87
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { DbClient } from '../index.js';
|
|
2
2
|
import { QueryDef, QueryDefType, QueryTarget } from './types.js';
|
|
3
|
-
export declare const createQueryDef: (db: DbClient, type: QueryDefType, target: QueryTarget) => QueryDef;
|
|
3
|
+
export declare const createQueryDef: (db: DbClient, type: QueryDefType, target: QueryTarget, skipValidation: boolean) => QueryDef;
|
|
@@ -2,9 +2,10 @@ import { langCodesMap } from '@based/schema';
|
|
|
2
2
|
import { DEF_RANGE_PROP_LIMIT, DEF_RANGE_REF_LIMIT } from './thresholds.js';
|
|
3
3
|
import { QueryDefType, } from './types.js';
|
|
4
4
|
import { validateAlias, validateId, validateIds, validateType, } from './validation.js';
|
|
5
|
-
const createEmptySharedDef = () => {
|
|
5
|
+
const createEmptySharedDef = (skipValidation) => {
|
|
6
6
|
const q = {
|
|
7
7
|
errors: [],
|
|
8
|
+
skipValidation,
|
|
8
9
|
filter: { conditions: new Map(), size: 0 },
|
|
9
10
|
range: { offset: 0, limit: 0 },
|
|
10
11
|
lang: langCodesMap.get('none'),
|
|
@@ -23,8 +24,8 @@ const createEmptySharedDef = () => {
|
|
|
23
24
|
};
|
|
24
25
|
return q;
|
|
25
26
|
};
|
|
26
|
-
export const createQueryDef = (db, type, target) => {
|
|
27
|
-
const queryDef = createEmptySharedDef();
|
|
27
|
+
export const createQueryDef = (db, type, target, skipValidation) => {
|
|
28
|
+
const queryDef = createEmptySharedDef(skipValidation);
|
|
28
29
|
if (type === QueryDefType.Edge) {
|
|
29
30
|
const t = target;
|
|
30
31
|
const q = queryDef;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ALIAS, ALIASES, BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TEXT, TIMESTAMP, UINT16, UINT32, UINT8, VECTOR, JSON, } from '../../../server/schema/types.js';
|
|
1
|
+
import { ALIAS, ALIASES, BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TEXT, TIMESTAMP, UINT16, UINT32, UINT8, VECTOR, JSON, CARDINALITY, } 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
4
|
import { inverseLangMap } from '@based/schema';
|
|
5
|
+
import { READ_EDGE, READ_ID, READ_REFERENCE, READ_REFERENCES } from './types.js';
|
|
5
6
|
const addField = (p, value, item, defaultOnly = false, lang = 0) => {
|
|
6
7
|
let i = p.__isEdge === true ? 1 : 0;
|
|
7
8
|
// TODO OPTMIZE
|
|
@@ -58,19 +59,15 @@ const getEmptyField = (p, item) => {
|
|
|
58
59
|
return select;
|
|
59
60
|
};
|
|
60
61
|
const readMainValue = (prop, result, index, item) => {
|
|
61
|
-
// 1: timestamp, 4: number
|
|
62
62
|
if (prop.typeIndex === TIMESTAMP || prop.typeIndex === NUMBER) {
|
|
63
63
|
addField(prop, readDoubleLE(result, index), item);
|
|
64
64
|
}
|
|
65
|
-
// 5: uint32
|
|
66
65
|
else if (prop.typeIndex === UINT32) {
|
|
67
66
|
addField(prop, readUint32(result, index), item);
|
|
68
67
|
}
|
|
69
|
-
// 9: boolean
|
|
70
68
|
else if (prop.typeIndex === BOOLEAN) {
|
|
71
69
|
addField(prop, Boolean(result[index]), item);
|
|
72
70
|
}
|
|
73
|
-
// 10: Enum
|
|
74
71
|
else if (prop.typeIndex === ENUM) {
|
|
75
72
|
if (result[index] === 0) {
|
|
76
73
|
addField(prop, undefined, item);
|
|
@@ -79,9 +76,7 @@ const readMainValue = (prop, result, index, item) => {
|
|
|
79
76
|
addField(prop, prop.enum[result[index] - 1], item);
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
|
-
// 11: string
|
|
83
79
|
else if (prop.typeIndex === STRING) {
|
|
84
|
-
// Also delete this default then (same as other string)
|
|
85
80
|
const len = result[index];
|
|
86
81
|
if (len !== 0) {
|
|
87
82
|
const str = readUtf8(result, index + 1, len);
|
|
@@ -91,32 +86,25 @@ const readMainValue = (prop, result, index, item) => {
|
|
|
91
86
|
addField(prop, '', item);
|
|
92
87
|
}
|
|
93
88
|
}
|
|
94
|
-
// ?: json
|
|
95
89
|
else if (prop.typeIndex === JSON) {
|
|
96
|
-
addField(prop, global.JSON.parse(
|
|
90
|
+
addField(prop, global.JSON.parse(readUtf8(result, index + 1, index + 1 + result[index])), item);
|
|
97
91
|
}
|
|
98
|
-
// 25: binary
|
|
99
92
|
else if (prop.typeIndex === BINARY) {
|
|
100
93
|
addField(prop, result.subarray(index + 1, index + 1 + result[index]), item);
|
|
101
94
|
}
|
|
102
|
-
// 18: int8
|
|
103
95
|
else if (prop.typeIndex === INT8) {
|
|
104
96
|
const signedVal = (result[index] << 24) >> 24;
|
|
105
97
|
addField(prop, signedVal, item);
|
|
106
98
|
}
|
|
107
|
-
// 19: uint8
|
|
108
99
|
else if (prop.typeIndex === UINT8) {
|
|
109
100
|
addField(prop, result[index], item);
|
|
110
101
|
}
|
|
111
|
-
// 20: int16
|
|
112
102
|
else if (prop.typeIndex === INT16) {
|
|
113
103
|
addField(prop, readInt16(result, index), item);
|
|
114
104
|
}
|
|
115
|
-
// 21: uint16
|
|
116
105
|
else if (prop.typeIndex === UINT16) {
|
|
117
106
|
addField(prop, readUint16(result, index), item);
|
|
118
107
|
}
|
|
119
|
-
// 22: int32
|
|
120
108
|
else if (prop.typeIndex === INT32) {
|
|
121
109
|
addField(prop, readInt32(result, index), item);
|
|
122
110
|
}
|
|
@@ -143,7 +131,10 @@ const handleUndefinedProps = (id, q, item) => {
|
|
|
143
131
|
for (const k in q.include.propsRead) {
|
|
144
132
|
if (q.include.propsRead[k] !== id) {
|
|
145
133
|
const prop = q.schema.reverseProps[k];
|
|
146
|
-
if (prop.typeIndex ===
|
|
134
|
+
if (prop.typeIndex === CARDINALITY) {
|
|
135
|
+
addField(prop, 0, item);
|
|
136
|
+
}
|
|
137
|
+
else if (prop.typeIndex === TEXT && q.lang == 0) {
|
|
147
138
|
const lan = getEmptyField(prop, item);
|
|
148
139
|
const lang = q.include.langTextFields.get(prop.prop).codes;
|
|
149
140
|
if (lang.has(0)) {
|
|
@@ -173,16 +164,13 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
173
164
|
while (i < end) {
|
|
174
165
|
const index = result[i];
|
|
175
166
|
i++;
|
|
176
|
-
|
|
177
|
-
if (index === 255) {
|
|
167
|
+
if (index === READ_ID) {
|
|
178
168
|
handleUndefinedProps(id, q, item);
|
|
179
169
|
return i - offset;
|
|
180
170
|
}
|
|
181
|
-
|
|
182
|
-
if (index === 252) {
|
|
171
|
+
if (index === READ_EDGE) {
|
|
183
172
|
let prop = result[i];
|
|
184
|
-
|
|
185
|
-
if (prop === 254) {
|
|
173
|
+
if (prop === READ_REFERENCE) {
|
|
186
174
|
i++;
|
|
187
175
|
const field = result[i];
|
|
188
176
|
i++;
|
|
@@ -206,9 +194,8 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
206
194
|
addField(ref.target.propDef, refItem, item);
|
|
207
195
|
i += size - 5;
|
|
208
196
|
}
|
|
209
|
-
// index:253 refs
|
|
210
197
|
}
|
|
211
|
-
else if (prop ===
|
|
198
|
+
else if (prop === READ_REFERENCES) {
|
|
212
199
|
i++;
|
|
213
200
|
const field = result[i];
|
|
214
201
|
i++;
|
|
@@ -227,7 +214,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
227
214
|
if (t === JSON) {
|
|
228
215
|
i++;
|
|
229
216
|
const size = readUint32(result, i);
|
|
230
|
-
addField(edgeDef, global.JSON.parse(
|
|
217
|
+
addField(edgeDef, global.JSON.parse(readUtf8(result, i + 6, size + i)), item);
|
|
231
218
|
i += size + 4;
|
|
232
219
|
}
|
|
233
220
|
else if (t === BINARY) {
|
|
@@ -253,9 +240,8 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
253
240
|
i += edgeDef.len;
|
|
254
241
|
}
|
|
255
242
|
}
|
|
256
|
-
// index:254 ref
|
|
257
243
|
}
|
|
258
|
-
else if (index ===
|
|
244
|
+
else if (index === READ_REFERENCE) {
|
|
259
245
|
const field = result[i];
|
|
260
246
|
i++;
|
|
261
247
|
const size = readUint32(result, i);
|
|
@@ -278,9 +264,8 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
278
264
|
addField(ref.target.propDef, refItem, item);
|
|
279
265
|
i += size - 5;
|
|
280
266
|
}
|
|
281
|
-
// index:253 refs
|
|
282
267
|
}
|
|
283
|
-
else if (index ===
|
|
268
|
+
else if (index === READ_REFERENCES) {
|
|
284
269
|
const field = result[i];
|
|
285
270
|
i++;
|
|
286
271
|
const ref = q.references.get(field);
|
|
@@ -296,7 +281,13 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
296
281
|
}
|
|
297
282
|
else {
|
|
298
283
|
const prop = q.schema.reverseProps[index];
|
|
299
|
-
if (prop.typeIndex ===
|
|
284
|
+
if (prop.typeIndex === CARDINALITY) {
|
|
285
|
+
q.include.propsRead[index] = id;
|
|
286
|
+
const size = readUint32(result, i);
|
|
287
|
+
addField(prop, readUint32(result, i + 4), item);
|
|
288
|
+
i += size + 4;
|
|
289
|
+
}
|
|
290
|
+
else if (prop.typeIndex === JSON) {
|
|
300
291
|
q.include.propsRead[index] = id;
|
|
301
292
|
const size = readUint32(result, i);
|
|
302
293
|
addField(prop, global.JSON.parse(Buffer.from(result.subarray(i + 6, i + size)).toString()), item);
|
|
@@ -329,7 +320,6 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
329
320
|
addField(prop, read(result, i + 4, size), item);
|
|
330
321
|
}
|
|
331
322
|
else {
|
|
332
|
-
// q.include.propsRead[index] = id
|
|
333
323
|
addField(prop, read(result, i + 4, size), item, false, result[i + 4]);
|
|
334
324
|
}
|
|
335
325
|
}
|
|
@@ -360,7 +350,6 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
360
350
|
}
|
|
361
351
|
}
|
|
362
352
|
}
|
|
363
|
-
// to add defaults - may not optimal for performance
|
|
364
353
|
handleUndefinedProps(id, q, item);
|
|
365
354
|
return i - offset;
|
|
366
355
|
};
|