inibase 1.2.9 → 1.2.10
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/index.d.ts +1 -0
- package/dist/index.js +53 -44
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -927,47 +927,49 @@ export default class Inibase {
|
|
|
927
927
|
}
|
|
928
928
|
}
|
|
929
929
|
}
|
|
930
|
+
_setNestedKey(obj, path, value) {
|
|
931
|
+
const keys = path.split(".");
|
|
932
|
+
const lastKey = keys.pop();
|
|
933
|
+
const target = keys.reduce((acc, key) => {
|
|
934
|
+
if (typeof acc[key] !== "object" || acc[key] === null) {
|
|
935
|
+
acc[key] = {};
|
|
936
|
+
}
|
|
937
|
+
return acc[key];
|
|
938
|
+
}, obj);
|
|
939
|
+
target[lastKey] = value;
|
|
940
|
+
}
|
|
930
941
|
async applyCriteria(tableName, options, criteria, allTrue, searchIn) {
|
|
931
942
|
const tablePath = join(this.databasePath, tableName);
|
|
932
|
-
|
|
933
|
-
const RETURN = {};
|
|
934
|
-
/* ---------- fast exit ---------- */
|
|
943
|
+
let RETURN = {};
|
|
935
944
|
if (!criteria || Object.keys(criteria).length === 0)
|
|
936
945
|
return null;
|
|
937
|
-
/* ---------- split top-level logical groups ---------- */
|
|
938
946
|
const criteriaAND = criteria.and;
|
|
939
|
-
const criteriaOR = criteria.or;
|
|
940
947
|
if (criteriaAND)
|
|
941
948
|
delete criteria.and;
|
|
949
|
+
const criteriaOR = criteria.or;
|
|
942
950
|
if (criteriaOR)
|
|
943
951
|
delete criteria.or;
|
|
944
|
-
/** cache table schema once – Utils.getField() is cheap but we call it a lot */
|
|
945
952
|
const schema = globalConfig[this.databasePath].tables.get(tableName).schema;
|
|
946
|
-
/* ---------- MAIN LOOP (top-level criteria only) ---------- */
|
|
947
953
|
if (Object.keys(criteria).length) {
|
|
948
954
|
if (allTrue === undefined)
|
|
949
955
|
allTrue = true;
|
|
950
|
-
for (
|
|
951
|
-
/* bail early if no candidates left for an “AND” chain */
|
|
952
|
-
if (allTrue && searchIn && searchIn.size === 0)
|
|
953
|
-
return null;
|
|
956
|
+
for await (let [key, value] of Object.entries(criteria)) {
|
|
954
957
|
const field = Utils.getField(key, schema);
|
|
955
958
|
if (!field)
|
|
956
959
|
continue;
|
|
957
|
-
let value = rawValue;
|
|
958
|
-
/* ----- resolve relational sub-queries ----- */
|
|
959
960
|
if (field.table && Utils.isObject(value)) {
|
|
960
|
-
const
|
|
961
|
+
const items = await this.get(field.table, value, {
|
|
961
962
|
columns: "id",
|
|
963
|
+
perPage: Number.POSITIVE_INFINITY,
|
|
962
964
|
});
|
|
963
|
-
|
|
964
|
-
|
|
965
|
+
if (items?.length)
|
|
966
|
+
value = `[]${items.map(({ id }) => id)}`;
|
|
967
|
+
else if (allTrue)
|
|
965
968
|
return null;
|
|
966
969
|
}
|
|
967
|
-
|
|
968
|
-
let
|
|
969
|
-
let
|
|
970
|
-
let searchLogicalOperator;
|
|
970
|
+
let searchOperator = undefined;
|
|
971
|
+
let searchComparedAtValue = undefined;
|
|
972
|
+
let searchLogicalOperator = undefined;
|
|
971
973
|
if (Utils.isObject(value)) {
|
|
972
974
|
/* nested object with .and / .or inside */
|
|
973
975
|
const nestedAnd = value.and;
|
|
@@ -985,6 +987,7 @@ export default class Inibase {
|
|
|
985
987
|
searchComparedAtValue = crit.map((c) => c[1]);
|
|
986
988
|
searchLogicalOperator = logic;
|
|
987
989
|
}
|
|
990
|
+
delete value[logic];
|
|
988
991
|
}
|
|
989
992
|
}
|
|
990
993
|
else if (Array.isArray(value)) {
|
|
@@ -1006,45 +1009,51 @@ export default class Inibase {
|
|
|
1006
1009
|
searchOperator = "=";
|
|
1007
1010
|
searchComparedAtValue = value;
|
|
1008
1011
|
}
|
|
1009
|
-
|
|
1010
|
-
const [hitRows, totalLines, lineSet] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, searchIn, {
|
|
1012
|
+
const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue, searchLogicalOperator, searchIn, {
|
|
1011
1013
|
...field,
|
|
1012
1014
|
databasePath: this.databasePath,
|
|
1013
1015
|
table: field.table ?? tableName,
|
|
1014
1016
|
}, options.perPage, (options.page - 1) * options.perPage +
|
|
1015
1017
|
(options.page > 1 ? 1 : 0), true);
|
|
1016
|
-
if (!
|
|
1018
|
+
if (!searchResult) {
|
|
1017
1019
|
if (allTrue)
|
|
1018
|
-
return null;
|
|
1019
|
-
continue;
|
|
1020
|
-
}
|
|
1021
|
-
/* ---------- map rows into RETURN without deep-merge ---------- */
|
|
1022
|
-
for (const [lnStr, val] of Object.entries(hitRows)) {
|
|
1023
|
-
const ln = +lnStr;
|
|
1024
|
-
const row = (RETURN[ln] ??= {});
|
|
1025
|
-
row[key] = val;
|
|
1020
|
+
return null;
|
|
1021
|
+
continue;
|
|
1026
1022
|
}
|
|
1023
|
+
const formatedSearchResult = Object.fromEntries(Object.entries(searchResult).map(([id, value]) => {
|
|
1024
|
+
const nestedObj = {};
|
|
1025
|
+
this._setNestedKey(nestedObj, key, value);
|
|
1026
|
+
return [id, nestedObj];
|
|
1027
|
+
}));
|
|
1028
|
+
RETURN = allTrue
|
|
1029
|
+
? formatedSearchResult
|
|
1030
|
+
: Utils.deepMerge(RETURN, formatedSearchResult);
|
|
1027
1031
|
this.totalItems.set(`${tableName}-${key}`, totalLines);
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
searchIn = lineSet;
|
|
1032
|
+
if (linesNumbers?.size && allTrue)
|
|
1033
|
+
searchIn = linesNumbers;
|
|
1031
1034
|
}
|
|
1032
1035
|
}
|
|
1033
|
-
/* ---------- process nested .and / .or recursively (unchanged) ---------- */
|
|
1034
1036
|
if (criteriaAND && Utils.isObject(criteriaAND)) {
|
|
1035
|
-
const
|
|
1036
|
-
if (
|
|
1037
|
+
const searchResult = await this.applyCriteria(tableName, options, criteriaAND, true, searchIn);
|
|
1038
|
+
if (searchResult)
|
|
1039
|
+
RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).filter(([_k, v], _i) => Object.keys(v).filter((key) => Object.keys(criteriaAND).includes(key)).length)));
|
|
1040
|
+
else
|
|
1037
1041
|
return null;
|
|
1038
|
-
for (const [lnStr, data] of Object.entries(res))
|
|
1039
|
-
(RETURN[+lnStr] ??= {}), Object.assign(RETURN[+lnStr], data);
|
|
1040
1042
|
}
|
|
1041
1043
|
if (criteriaOR && Utils.isObject(criteriaOR)) {
|
|
1042
|
-
const
|
|
1043
|
-
if (
|
|
1044
|
-
|
|
1045
|
-
|
|
1044
|
+
const searchResult = await this.applyCriteria(tableName, options, criteriaOR, false, searchIn);
|
|
1045
|
+
if (searchResult) {
|
|
1046
|
+
RETURN = Utils.deepMerge(RETURN, searchResult);
|
|
1047
|
+
if (!Object.keys(RETURN).length)
|
|
1048
|
+
RETURN = {};
|
|
1049
|
+
RETURN = Object.fromEntries(Object.entries(RETURN).filter(([_index, item]) => Object.keys(item).filter((key) => Object.keys(criteriaOR).includes(key) ||
|
|
1050
|
+
Object.keys(criteriaOR).some((criteriaKey) => criteriaKey.startsWith(`${key}.`))).length));
|
|
1051
|
+
if (!Object.keys(RETURN).length)
|
|
1052
|
+
RETURN = {};
|
|
1053
|
+
}
|
|
1054
|
+
else
|
|
1055
|
+
RETURN = {};
|
|
1046
1056
|
}
|
|
1047
|
-
/* ---------- final answer ---------- */
|
|
1048
1057
|
return Object.keys(RETURN).length ? RETURN : null;
|
|
1049
1058
|
}
|
|
1050
1059
|
_filterSchemaByColumns(schema, columns) {
|