inibase 1.0.0-rc.113 → 1.0.0-rc.115

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/file.d.ts CHANGED
@@ -107,7 +107,7 @@ export declare const remove: (filePath: string, linesToDelete: number | number[]
107
107
  *
108
108
  * Note: Decodes each line for comparison and can handle complex queries with multiple conditions.
109
109
  */
110
- export declare const search: (filePath: string, operator: ComparisonOperator | ComparisonOperator[], comparedAtValue: string | number | boolean | null | (string | number | boolean | null)[], logicalOperator?: "and" | "or", fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[] | Schema, limit?: number, offset?: number, readWholeFile?: boolean, secretKey?: string | Buffer) => Promise<[Record<number, string | number | boolean | null | (string | number | boolean | null)[]> | null, number, Set<number> | null]>;
110
+ export declare const search: (filePath: string, operator: ComparisonOperator | ComparisonOperator[], comparedAtValue: string | number | boolean | null | (string | number | boolean | null)[], logicalOperator?: "and" | "or", searchIn?: Set<number>, fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[] | Schema, limit?: number, offset?: number, readWholeFile?: boolean, secretKey?: string | Buffer) => Promise<[Record<number, string | number | boolean | null | (string | number | boolean | null)[]> | null, number, Set<number> | null]>;
111
111
  /**
112
112
  * Asynchronously calculates the sum of numerical values from specified lines in a file.
113
113
  *
package/dist/file.js CHANGED
@@ -505,7 +505,7 @@ export const remove = async (filePath, linesToDelete) => {
505
505
  *
506
506
  * Note: Decodes each line for comparison and can handle complex queries with multiple conditions.
507
507
  */
508
- export const search = async (filePath, operator, comparedAtValue, logicalOperator, fieldType, fieldChildrenType, limit, offset, readWholeFile, secretKey) => {
508
+ export const search = async (filePath, operator, comparedAtValue, logicalOperator, searchIn, fieldType, fieldChildrenType, limit, offset, readWholeFile, secretKey) => {
509
509
  // Initialize a Map to store the matching lines with their line numbers.
510
510
  const matchingLines = {};
511
511
  // Initialize counters for line number, found items, and processed items.
@@ -521,6 +521,9 @@ export const search = async (filePath, operator, comparedAtValue, logicalOperato
521
521
  for await (const line of rl) {
522
522
  // Increment the line count for each line.
523
523
  linesCount++;
524
+ // Search only in provided linesNumbers
525
+ if (searchIn && !searchIn.has(linesCount))
526
+ continue;
524
527
  // Decode the line for comparison.
525
528
  const decodedLine = decode(line, fieldType, fieldChildrenType, secretKey);
526
529
  // Check if the line meets the specified conditions based on comparison and logical operators.
package/dist/index.js CHANGED
@@ -401,7 +401,7 @@ export default class Inibase {
401
401
  const field = Utils.getField(key, schema);
402
402
  if (!field)
403
403
  continue;
404
- const [searchResult, totalLines] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), Array.isArray(values) ? "=" : "[]", values, undefined, field.type, field.children, 1, undefined, false, this.salt);
404
+ const [searchResult, totalLines] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), Array.isArray(values) ? "=" : "[]", values, undefined, undefined, field.type, field.children, 1, undefined, false, this.salt);
405
405
  if (searchResult && totalLines > 0)
406
406
  throw this.Error("FIELD_UNIQUE", [
407
407
  field.key,
@@ -411,19 +411,21 @@ export default class Inibase {
411
411
  this.checkIFunique = {};
412
412
  }
413
413
  formatData(data, schema, formatOnlyAvailiableKeys) {
414
- if (Utils.isArrayOfObjects(data))
415
- return data.map((single_data) => this.formatData(single_data, schema, formatOnlyAvailiableKeys));
416
- if (Utils.isObject(data)) {
414
+ const clonedData = JSON.parse(JSON.stringify(data));
415
+ if (Utils.isArrayOfObjects(clonedData))
416
+ return clonedData.map((singleData) => this.formatData(singleData, schema, formatOnlyAvailiableKeys));
417
+ if (Utils.isObject(clonedData)) {
418
+ const RETURN = {};
417
419
  for (const field of schema) {
418
- if (!Object.hasOwn(data, field.key)) {
420
+ if (!Object.hasOwn(clonedData, field.key)) {
419
421
  if (formatOnlyAvailiableKeys)
420
422
  continue;
421
- data[field.key] = this.getDefaultValue(field);
423
+ RETURN[field.key] = this.getDefaultValue(field);
422
424
  continue;
423
425
  }
424
- data[field.key] = this.formatField(data[field.key], field.type, field.children, formatOnlyAvailiableKeys);
426
+ RETURN[field.key] = this.formatField(clonedData[field.key], field.type, field.children, formatOnlyAvailiableKeys);
425
427
  }
426
- return data;
428
+ return RETURN;
427
429
  }
428
430
  return [];
429
431
  }
@@ -741,30 +743,24 @@ export default class Inibase {
741
743
  }
742
744
  }
743
745
  }
744
- async applyCriteria(tableName, schema, options, criteria, allTrue) {
746
+ async applyCriteria(tableName, schema, options, criteria, allTrue, searchIn) {
745
747
  const tablePath = join(this.databasePath, tableName);
746
- let RETURN = {}, RETURN_LineNumbers = null;
748
+ let RETURN = {};
747
749
  if (!criteria)
748
750
  return [null, null];
749
751
  if (criteria.and && Utils.isObject(criteria.and)) {
750
- const [searchResult, lineNumbers] = await this.applyCriteria(tableName, schema, options, criteria.and, true);
752
+ const [searchResult, lineNumbers] = await this.applyCriteria(tableName, schema, options, criteria.and, true, searchIn);
751
753
  if (searchResult) {
752
- RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).filter(([_k, v], _i) => Object.keys(v).length ===
753
- Object.keys(criteria.and ?? {}).length)));
754
+ RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).filter(([_k, v], _i) => Object.keys(v).filter((key) => Object.keys(criteria.and).includes(key)).length)));
754
755
  delete criteria.and;
755
- RETURN_LineNumbers = lineNumbers;
756
+ searchIn = lineNumbers;
756
757
  }
757
758
  else
758
759
  return [null, null];
759
760
  }
760
- if (criteria.or && Utils.isObject(criteria.or)) {
761
- const [searchResult, lineNumbers] = await this.applyCriteria(tableName, schema, options, criteria.or, false);
761
+ const criteriaOR = criteria.or;
762
+ if (criteriaOR)
762
763
  delete criteria.or;
763
- if (searchResult) {
764
- RETURN = Utils.deepMerge(RETURN, searchResult);
765
- RETURN_LineNumbers = lineNumbers;
766
- }
767
- }
768
764
  if (Object.keys(criteria).length > 0) {
769
765
  if (allTrue === undefined)
770
766
  allTrue = true;
@@ -826,7 +822,7 @@ export default class Inibase {
826
822
  searchOperator = "=";
827
823
  searchComparedAtValue = value;
828
824
  }
829
- const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, field?.type, field?.children, options.perPage, (options.page - 1) * options.perPage + 1, true, this.salt);
825
+ const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, allTrue ? searchIn : undefined, field?.type, field?.children, options.perPage, (options.page - 1) * options.perPage + 1, true, this.salt);
830
826
  if (searchResult) {
831
827
  RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).map(([id, value]) => [
832
828
  id,
@@ -835,18 +831,32 @@ export default class Inibase {
835
831
  },
836
832
  ])));
837
833
  this.totalItems[`${tableName}-${key}`] = totalLines;
838
- RETURN_LineNumbers = linesNumbers;
839
- }
840
- if (allTrue && index > 0) {
841
- if (!Object.keys(RETURN).length)
842
- RETURN = {};
843
- RETURN = Object.fromEntries(Object.entries(RETURN).filter(([_index, item]) => Object.keys(item).length > index));
844
- if (!Object.keys(RETURN).length)
845
- RETURN = {};
834
+ if (linesNumbers?.size) {
835
+ if (searchIn) {
836
+ for (const lineNumber of linesNumbers)
837
+ searchIn.add(lineNumber);
838
+ }
839
+ else
840
+ searchIn = linesNumbers;
841
+ }
846
842
  }
843
+ else if (allTrue)
844
+ return [null, null];
845
+ }
846
+ }
847
+ if (criteriaOR && Utils.isObject(criteriaOR)) {
848
+ const [searchResult, lineNumbers] = await this.applyCriteria(tableName, schema, options, criteriaOR, false, searchIn);
849
+ if (searchResult) {
850
+ RETURN = Utils.deepMerge(RETURN, searchResult);
851
+ if (!Object.keys(RETURN).length)
852
+ RETURN = {};
853
+ RETURN = Object.fromEntries(Object.entries(RETURN).filter(([_index, item]) => Object.keys(item).filter((key) => Object.keys(criteriaOR).includes(key)).length));
854
+ if (!Object.keys(RETURN).length)
855
+ RETURN = {};
856
+ searchIn = lineNumbers;
847
857
  }
848
858
  }
849
- return [Object.keys(RETURN).length ? RETURN : null, RETURN_LineNumbers];
859
+ return [Object.keys(RETURN).length ? RETURN : null, searchIn];
850
860
  }
851
861
  _filterSchemaByColumns(schema, columns) {
852
862
  return schema
@@ -947,7 +957,7 @@ export default class Inibase {
947
957
  if (!(await File.isExists(path)))
948
958
  return null;
949
959
  // Construct the paste command to merge files and filter lines by IDs
950
- const pasteCommand = `paste ${filesPathes.join(" ")}`;
960
+ const pasteCommand = `paste '${filesPathes.join("' '")}'`;
951
961
  // Construct the sort command dynamically based on the number of files for sorting
952
962
  const index = 2;
953
963
  const sortColumns = sortArray
@@ -960,15 +970,15 @@ export default class Inibase {
960
970
  return "";
961
971
  })
962
972
  .join(" ");
963
- const sortCommand = `sort ${sortColumns} -T=${join(tablePath, ".tmp")}`;
973
+ const sortCommand = `sort ${sortColumns} -T='${join(tablePath, ".tmp")}'`;
964
974
  try {
965
975
  if (cacheKey)
966
976
  await File.lock(join(tablePath, ".tmp"), cacheKey);
967
977
  // Combine && Execute the commands synchronously
968
978
  let lines = (await UtilsServer.exec(this.tables[tableName].config.cache
969
979
  ? (await File.isExists(join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)))
970
- ? `${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
971
- : `${pasteCommand} | ${sortCommand} -o ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)} && ${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
980
+ ? `${awkCommand} '${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}'`
981
+ : `${pasteCommand} | ${sortCommand} -o '${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}' && ${awkCommand} '${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}'`
972
982
  : `${pasteCommand} | ${sortCommand} | ${awkCommand}`, {
973
983
  encoding: "utf-8",
974
984
  })).stdout
@@ -1033,7 +1043,7 @@ export default class Inibase {
1033
1043
  let Ids = where;
1034
1044
  if (!Array.isArray(Ids))
1035
1045
  Ids = [Ids];
1036
- const [lineNumbers, countItems] = await File.search(join(tablePath, `id${this.getFileExtension(tableName)}`), "[]", Ids.map((id) => Utils.isNumber(id) ? Number(id) : UtilsServer.decodeID(id, this.salt)), undefined, "number", undefined, Ids.length, 0, !this.totalItems[`${tableName}-*`], this.salt);
1046
+ const [lineNumbers, countItems] = await File.search(join(tablePath, `id${this.getFileExtension(tableName)}`), "[]", Ids.map((id) => Utils.isNumber(id) ? Number(id) : UtilsServer.decodeID(id, this.salt)), undefined, undefined, "number", undefined, Ids.length, 0, !this.totalItems[`${tableName}-*`], this.salt);
1037
1047
  if (!lineNumbers)
1038
1048
  return null;
1039
1049
  if (!this.totalItems[`${tableName}-*`])
@@ -1195,7 +1205,7 @@ export default class Inibase {
1195
1205
  // Skip ID and (created|updated)At
1196
1206
  this.validateData(data, schema.slice(1, -2), true);
1197
1207
  await this.checkUnique(tableName, schema);
1198
- this.formatData(data, schema, true);
1208
+ data = this.formatData(data, schema, true);
1199
1209
  const pathesContents = this.joinPathesContents(tableName, {
1200
1210
  ...(({ id, ...restOfData }) => restOfData)(data),
1201
1211
  updatedAt: Date.now(),
@@ -1233,7 +1243,7 @@ export default class Inibase {
1233
1243
  // "where" in this case, is the line(s) number(s) and not id(s)
1234
1244
  this.validateData(data, schema.slice(1, -2), true);
1235
1245
  await this.checkUnique(tableName, schema.slice(1, -2));
1236
- this.formatData(data, schema, true);
1246
+ data = this.formatData(data, schema, true);
1237
1247
  const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(tableName, Utils.isArrayOfObjects(data)
1238
1248
  ? data.map((item) => ({
1239
1249
  ...item,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.113",
3
+ "version": "1.0.0-rc.115",
4
4
  "type": "module",
5
5
  "author": {
6
6
  "name": "Karim Amahtil",