inibase 1.0.0-rc.60 → 1.0.0-rc.61
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 +111 -78
- package/dist/file.d.ts +3 -3
- package/dist/file.js +42 -44
- package/dist/index.d.ts +20 -11
- package/dist/index.js +206 -156
- package/dist/utils.d.ts +1 -3
- package/dist/utils.js +37 -1
- package/dist/utils.server.d.ts +5 -0
- package/dist/utils.server.js +6 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
|
-
import { unlink, rename, mkdir, readdir } from "node:fs/promises";
|
|
2
|
+
import { unlink, rename, mkdir, readdir, open, writeFile, readFile, } from "node:fs/promises";
|
|
3
3
|
import { existsSync, appendFileSync, readFileSync } from "node:fs";
|
|
4
4
|
import { join, parse } from "node:path";
|
|
5
5
|
import { scryptSync, randomBytes } from "node:crypto";
|
|
@@ -8,22 +8,19 @@ import Inison from "inison";
|
|
|
8
8
|
import * as File from "./file.js";
|
|
9
9
|
import * as Utils from "./utils.js";
|
|
10
10
|
import * as UtilsServer from "./utils.server.js";
|
|
11
|
-
import * as Config from "./config.js";
|
|
12
11
|
export default class Inibase {
|
|
13
|
-
folder;
|
|
14
|
-
database;
|
|
15
|
-
table;
|
|
16
12
|
pageInfo;
|
|
13
|
+
salt;
|
|
14
|
+
databasePath;
|
|
15
|
+
tables;
|
|
17
16
|
fileExtension = ".txt";
|
|
18
17
|
checkIFunique;
|
|
19
18
|
totalItems;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.totalItems = _totalItems;
|
|
26
|
-
this.pageInfo = _pageInfo;
|
|
19
|
+
constructor(database, mainFolder = ".") {
|
|
20
|
+
this.databasePath = join(mainFolder, database);
|
|
21
|
+
this.tables = {};
|
|
22
|
+
this.totalItems = {};
|
|
23
|
+
this.pageInfo = {};
|
|
27
24
|
this.checkIFunique = {};
|
|
28
25
|
if (!process.env.INIBASE_SECRET) {
|
|
29
26
|
if (existsSync(".env") &&
|
|
@@ -34,25 +31,14 @@ export default class Inibase {
|
|
|
34
31
|
}
|
|
35
32
|
else
|
|
36
33
|
this.salt = Buffer.from(process.env.INIBASE_SECRET, "hex");
|
|
37
|
-
// try {
|
|
38
|
-
// if (Config.isCompressionEnabled)
|
|
39
|
-
// execSync(
|
|
40
|
-
// `gzip -r ${join(this.folder, this.database)}/*/*.txt 2>/dev/null`,
|
|
41
|
-
// );
|
|
42
|
-
// else
|
|
43
|
-
// execSync(
|
|
44
|
-
// `gunzip -r ${join(
|
|
45
|
-
// this.folder,
|
|
46
|
-
// this.database,
|
|
47
|
-
// )}/*/*.txt.gz 2>/dev/null`,
|
|
48
|
-
// );
|
|
49
|
-
// } catch {}
|
|
50
34
|
}
|
|
51
35
|
throwError(code, variable, language = "en") {
|
|
52
36
|
const errorMessages = {
|
|
53
37
|
en: {
|
|
54
38
|
FIELD_UNIQUE: "Field {variable} should be unique, got {variable} instead",
|
|
55
39
|
FIELD_REQUIRED: "Field {variable} is required",
|
|
40
|
+
TABLE_EXISTS: "Table {variable} already exists",
|
|
41
|
+
TABLE_NOT_EXISTS: "Table {variable} doesn't exist",
|
|
56
42
|
NO_SCHEMA: "Table {variable} does't have a schema",
|
|
57
43
|
NO_ITEMS: "Table {variable} is empty",
|
|
58
44
|
NO_RESULTS: "No results found for table {variable}",
|
|
@@ -74,61 +60,123 @@ export default class Inibase {
|
|
|
74
60
|
: errorMessage.replaceAll("{variable}", `'${variable.toString()}'`)
|
|
75
61
|
: errorMessage.replaceAll("{variable}", ""));
|
|
76
62
|
}
|
|
77
|
-
getFileExtension = () => {
|
|
63
|
+
getFileExtension = (tableName) => {
|
|
78
64
|
let mainExtension = this.fileExtension;
|
|
79
65
|
// TODO: ADD ENCRYPTION
|
|
80
|
-
// if(
|
|
66
|
+
// if(this.tables[tableName].config.encryption)
|
|
81
67
|
// mainExtension += ".enc"
|
|
82
|
-
if (
|
|
68
|
+
if (this.tables[tableName].config.compression)
|
|
83
69
|
mainExtension += ".gz";
|
|
84
70
|
return mainExtension;
|
|
85
71
|
};
|
|
86
|
-
_schemaToIdsPath = (schema, prefix = "") => {
|
|
72
|
+
_schemaToIdsPath = (tableName, schema, prefix = "") => {
|
|
87
73
|
const RETURN = {};
|
|
88
74
|
for (const field of schema)
|
|
89
75
|
if ((field.type === "array" || field.type === "object") &&
|
|
90
76
|
field.children &&
|
|
91
77
|
Utils.isArrayOfObjects(field.children)) {
|
|
92
|
-
Utils.deepMerge(RETURN, this._schemaToIdsPath(field.children, `${(prefix ?? "") + field.key}.`));
|
|
78
|
+
Utils.deepMerge(RETURN, this._schemaToIdsPath(tableName, field.children, `${(prefix ?? "") + field.key}.`));
|
|
93
79
|
}
|
|
94
80
|
else if (field.id)
|
|
95
|
-
RETURN[field.id] = `${(prefix ?? "") + field.key}${this.getFileExtension()}`;
|
|
81
|
+
RETURN[field.id] = `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`;
|
|
96
82
|
return RETURN;
|
|
97
83
|
};
|
|
98
|
-
async
|
|
99
|
-
const tablePath = join(this.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
84
|
+
async createTable(tableName, schema, config) {
|
|
85
|
+
const tablePath = join(this.databasePath, tableName);
|
|
86
|
+
if (await File.isExists(tablePath))
|
|
87
|
+
this.throwError("TABLE_EXISTS", tableName);
|
|
88
|
+
await Promise.all([
|
|
89
|
+
mkdir(tablePath, { recursive: true }),
|
|
90
|
+
mkdir(join(tablePath, ".tmp")),
|
|
91
|
+
mkdir(join(tablePath, ".cache")),
|
|
92
|
+
]);
|
|
93
|
+
if (config) {
|
|
94
|
+
if (config.compression)
|
|
95
|
+
await open(join(tablePath, ".compression.config"), "w");
|
|
96
|
+
if (config.cache)
|
|
97
|
+
await open(join(tablePath, ".cache.config"), "w");
|
|
98
|
+
if (config.prepend)
|
|
99
|
+
await open(join(tablePath, ".prepend.config"), "w");
|
|
100
|
+
}
|
|
101
|
+
if (schema)
|
|
102
|
+
await writeFile(join(tablePath, "schema.json"), JSON.stringify(UtilsServer.addIdToSchema(schema, 0, this.salt, false), null, 2));
|
|
103
|
+
}
|
|
104
|
+
async updateTable(tableName, schema, config) {
|
|
105
|
+
const table = await this.getTable(tableName), tablePath = join(this.databasePath, tableName);
|
|
106
|
+
if (config) {
|
|
107
|
+
if (config.compression !== undefined) {
|
|
108
|
+
if (!config.compression && table.config.compression) {
|
|
109
|
+
try {
|
|
110
|
+
await UtilsServer.exec(`gunzip -r ${tablePath}/*.txt.gz 2>/dev/null`);
|
|
111
|
+
await unlink(join(tablePath, ".compression.config"));
|
|
112
|
+
}
|
|
113
|
+
catch { }
|
|
114
|
+
}
|
|
115
|
+
else if (config.compression && !table.config.compression) {
|
|
116
|
+
try {
|
|
117
|
+
await UtilsServer.exec(`gzip -r ${tablePath}/*.txt 2>/dev/null`);
|
|
118
|
+
await open(join(tablePath, ".compression.config"), "w");
|
|
119
|
+
}
|
|
120
|
+
catch { }
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (config.cache !== undefined) {
|
|
124
|
+
if (config.cache && !table.config.cache)
|
|
125
|
+
await open(join(tablePath, ".cache.config"), "w");
|
|
126
|
+
else if (!config.cache && table.config.cache)
|
|
127
|
+
await unlink(join(tablePath, ".cache.config"));
|
|
128
|
+
}
|
|
129
|
+
if (config.prepend !== undefined) {
|
|
130
|
+
if (config.prepend && !table.config.prepend)
|
|
131
|
+
await open(join(tablePath, ".prepend.config"), "w");
|
|
132
|
+
else if (!config.prepend && table.config.prepend)
|
|
133
|
+
await unlink(join(tablePath, ".prepend.config"));
|
|
121
134
|
}
|
|
122
135
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
if (schema) {
|
|
137
|
+
// remove id from schema
|
|
138
|
+
schema = schema.filter(({ key }) => !["id", "createdAt", "updatedAt"].includes(key));
|
|
139
|
+
if (await File.isExists(join(tablePath, "schema.json"))) {
|
|
140
|
+
// update columns files names based on field id
|
|
141
|
+
const currentSchema = await this.getTableSchema(tableName, false);
|
|
142
|
+
schema = UtilsServer.addIdToSchema(schema, currentSchema?.length
|
|
143
|
+
? UtilsServer.findLastIdNumber(currentSchema, this.salt)
|
|
144
|
+
: 0, this.salt, false);
|
|
145
|
+
if (currentSchema?.length) {
|
|
146
|
+
const replaceOldPathes = Utils.findChangedProperties(this._schemaToIdsPath(tableName, currentSchema), this._schemaToIdsPath(tableName, schema));
|
|
147
|
+
if (replaceOldPathes)
|
|
148
|
+
await Promise.all(Object.entries(replaceOldPathes).map(async ([oldPath, newPath]) => {
|
|
149
|
+
if (await File.isExists(join(tablePath, oldPath)))
|
|
150
|
+
await rename(join(tablePath, oldPath), join(tablePath, newPath));
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else
|
|
155
|
+
schema = UtilsServer.addIdToSchema(schema, 0, this.salt, false);
|
|
156
|
+
await writeFile(join(tablePath, "schema.json"), JSON.stringify(schema, null, 2));
|
|
157
|
+
delete this.tables[tableName];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async getTable(tableName) {
|
|
161
|
+
const tablePath = join(this.databasePath, tableName);
|
|
162
|
+
if (!(await File.isExists(tablePath)))
|
|
163
|
+
this.throwError("TABLE_NOT_EXISTS", tableName);
|
|
164
|
+
if (!this.tables[tableName])
|
|
165
|
+
this.tables[tableName] = {
|
|
166
|
+
schema: await this.getTableSchema(tableName),
|
|
167
|
+
config: {
|
|
168
|
+
compression: await File.isExists(join(tablePath, ".compression.config")),
|
|
169
|
+
cache: await File.isExists(join(tablePath, ".cache.config")),
|
|
170
|
+
prepend: await File.isExists(join(tablePath, ".prepend.config")),
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
return this.tables[tableName];
|
|
126
174
|
}
|
|
127
175
|
async getTableSchema(tableName, encodeIDs = true) {
|
|
128
|
-
const tableSchemaPath = join(this.
|
|
176
|
+
const tableSchemaPath = join(this.databasePath, tableName, "schema.json");
|
|
129
177
|
if (!(await File.isExists(tableSchemaPath)))
|
|
130
178
|
return undefined;
|
|
131
|
-
const schemaFile = await
|
|
179
|
+
const schemaFile = await readFile(tableSchemaPath, "utf8");
|
|
132
180
|
if (!schemaFile)
|
|
133
181
|
return undefined;
|
|
134
182
|
const schema = JSON.parse(schemaFile), lastIdNumber = UtilsServer.findLastIdNumber(schema, this.salt);
|
|
@@ -156,15 +204,13 @@ export default class Inibase {
|
|
|
156
204
|
},
|
|
157
205
|
];
|
|
158
206
|
}
|
|
159
|
-
async
|
|
160
|
-
const
|
|
161
|
-
if (!schema)
|
|
162
|
-
schema = await this.getTableSchema(tableName);
|
|
163
|
-
if (!schema)
|
|
207
|
+
async throwErrorIfTableEmpty(tableName) {
|
|
208
|
+
const table = await this.getTable(tableName);
|
|
209
|
+
if (!table.schema)
|
|
164
210
|
throw this.throwError("NO_SCHEMA", tableName);
|
|
165
|
-
if (!(await File.isExists(join(
|
|
211
|
+
if (!(await File.isExists(join(this.databasePath, tableName, `id${this.getFileExtension(tableName)}`))))
|
|
166
212
|
throw this.throwError("NO_ITEMS", tableName);
|
|
167
|
-
return
|
|
213
|
+
return table;
|
|
168
214
|
}
|
|
169
215
|
validateData(data, schema, skipRequiredField = false) {
|
|
170
216
|
if (Utils.isArrayOfObjects(data))
|
|
@@ -285,12 +331,12 @@ export default class Inibase {
|
|
|
285
331
|
return null;
|
|
286
332
|
}
|
|
287
333
|
async checkUnique(tableName, schema) {
|
|
288
|
-
const tablePath = join(this.
|
|
334
|
+
const tablePath = join(this.databasePath, tableName);
|
|
289
335
|
for await (const [key, values] of Object.entries(this.checkIFunique)) {
|
|
290
336
|
const field = Utils.getField(key, schema);
|
|
291
337
|
if (!field)
|
|
292
338
|
continue;
|
|
293
|
-
const [searchResult, totalLines] = await File.search(join(tablePath, `${key}${this.getFileExtension()}`), Array.isArray(values) ? "=" : "[]", values, undefined, field.type, field.children, 1, undefined, false, this.salt);
|
|
339
|
+
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);
|
|
294
340
|
if (searchResult && totalLines > 0)
|
|
295
341
|
throw this.throwError("FIELD_UNIQUE", [
|
|
296
342
|
field.key,
|
|
@@ -376,14 +422,12 @@ export default class Inibase {
|
|
|
376
422
|
}
|
|
377
423
|
return RETURN;
|
|
378
424
|
};
|
|
379
|
-
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
joinPathesContents(mainPath, data) {
|
|
386
|
-
return this._addPathToKeys(this._CombineData(data), mainPath);
|
|
425
|
+
joinPathesContents(tableName, data) {
|
|
426
|
+
const tablePath = join(this.databasePath, tableName), combinedData = this._CombineData(data);
|
|
427
|
+
const newCombinedData = {};
|
|
428
|
+
for (const [key, value] of Object.entries(combinedData))
|
|
429
|
+
newCombinedData[join(tablePath, `${key}${this.getFileExtension(tableName)}`)] = value;
|
|
430
|
+
return newCombinedData;
|
|
387
431
|
}
|
|
388
432
|
_getItemsFromSchemaHelper(RETURN, item, index, field) {
|
|
389
433
|
if (Utils.isObject(item)) {
|
|
@@ -427,7 +471,7 @@ export default class Inibase {
|
|
|
427
471
|
}
|
|
428
472
|
}
|
|
429
473
|
async getItemsFromSchema(tableName, schema, linesNumber, options, prefix) {
|
|
430
|
-
const tablePath = join(this.
|
|
474
|
+
const tablePath = join(this.databasePath, tableName);
|
|
431
475
|
let RETURN = {};
|
|
432
476
|
for await (const field of schema) {
|
|
433
477
|
if ((field.type === "array" ||
|
|
@@ -498,13 +542,13 @@ export default class Inibase {
|
|
|
498
542
|
(Array.isArray(field.type) && field.type.includes("table")) ||
|
|
499
543
|
(Array.isArray(field.children) && field.children.includes("table"))) {
|
|
500
544
|
if (field.table &&
|
|
501
|
-
(await File.isExists(join(this.
|
|
502
|
-
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`)))) {
|
|
545
|
+
(await File.isExists(join(this.databasePath, field.table))) &&
|
|
546
|
+
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`)))) {
|
|
503
547
|
if (options.columns)
|
|
504
548
|
options.columns = options.columns
|
|
505
549
|
.filter((column) => column.includes(`${field.key}.`))
|
|
506
550
|
.map((column) => column.replace(`${field.key}.`, ""));
|
|
507
|
-
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`), linesNumber, field.type, field.children, this.salt);
|
|
551
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, field.type, field.children, this.salt);
|
|
508
552
|
if (items)
|
|
509
553
|
for await (const [index, item] of Object.entries(items)) {
|
|
510
554
|
if (!RETURN[index])
|
|
@@ -515,8 +559,8 @@ export default class Inibase {
|
|
|
515
559
|
}
|
|
516
560
|
}
|
|
517
561
|
}
|
|
518
|
-
else if (await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`))) {
|
|
519
|
-
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`), linesNumber, field.type, field.children, this.salt);
|
|
562
|
+
else if (await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`))) {
|
|
563
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, field.type, field.children, this.salt);
|
|
520
564
|
if (items)
|
|
521
565
|
for (const [index, item] of Object.entries(items)) {
|
|
522
566
|
if (!RETURN[index])
|
|
@@ -543,13 +587,13 @@ export default class Inibase {
|
|
|
543
587
|
}
|
|
544
588
|
else if (field.type === "table") {
|
|
545
589
|
if (field.table &&
|
|
546
|
-
(await File.isExists(join(this.
|
|
547
|
-
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`)))) {
|
|
590
|
+
(await File.isExists(join(this.databasePath, field.table))) &&
|
|
591
|
+
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`)))) {
|
|
548
592
|
if (options.columns)
|
|
549
593
|
options.columns = options.columns
|
|
550
594
|
.filter((column) => column.includes(`${field.key}.`))
|
|
551
595
|
.map((column) => column.replace(`${field.key}.`, ""));
|
|
552
|
-
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`), linesNumber, "number", undefined, this.salt);
|
|
596
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, "number", undefined, this.salt);
|
|
553
597
|
if (items)
|
|
554
598
|
for await (const [index, item] of Object.entries(items)) {
|
|
555
599
|
if (!RETURN[index])
|
|
@@ -560,8 +604,8 @@ export default class Inibase {
|
|
|
560
604
|
}
|
|
561
605
|
}
|
|
562
606
|
}
|
|
563
|
-
else if (await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`))) {
|
|
564
|
-
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`), linesNumber, field.type, field.children, this.salt);
|
|
607
|
+
else if (await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`))) {
|
|
608
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, field.type, field.children, this.salt);
|
|
565
609
|
if (items)
|
|
566
610
|
for (const [index, item] of Object.entries(items)) {
|
|
567
611
|
if (!RETURN[index])
|
|
@@ -578,7 +622,7 @@ export default class Inibase {
|
|
|
578
622
|
return RETURN;
|
|
579
623
|
}
|
|
580
624
|
async applyCriteria(tableName, schema, options, criteria, allTrue) {
|
|
581
|
-
const tablePath = join(this.
|
|
625
|
+
const tablePath = join(this.databasePath, tableName);
|
|
582
626
|
let RETURN = {}, RETURN_LineNumbers = null;
|
|
583
627
|
if (!criteria)
|
|
584
628
|
return [null, null];
|
|
@@ -662,7 +706,7 @@ export default class Inibase {
|
|
|
662
706
|
searchOperator = "=";
|
|
663
707
|
searchComparedAtValue = value;
|
|
664
708
|
}
|
|
665
|
-
const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension()}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, field?.type, field?.children, options.perPage, options.page - 1 * options.perPage + 1, true, this.salt);
|
|
709
|
+
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);
|
|
666
710
|
if (searchResult) {
|
|
667
711
|
RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).map(([id, value]) => [
|
|
668
712
|
id,
|
|
@@ -713,14 +757,14 @@ export default class Inibase {
|
|
|
713
757
|
async get(tableName, where, options = {
|
|
714
758
|
page: 1,
|
|
715
759
|
perPage: 15,
|
|
716
|
-
}, onlyOne, onlyLinesNumbers,
|
|
717
|
-
const tablePath = join(this.
|
|
760
|
+
}, onlyOne, onlyLinesNumbers, _skipIdColumn) {
|
|
761
|
+
const tablePath = join(this.databasePath, tableName);
|
|
718
762
|
// Ensure options.columns is an array
|
|
719
763
|
if (options.columns) {
|
|
720
764
|
options.columns = Array.isArray(options.columns)
|
|
721
765
|
? options.columns
|
|
722
766
|
: [options.columns];
|
|
723
|
-
if (!
|
|
767
|
+
if (!_skipIdColumn &&
|
|
724
768
|
options.columns.length &&
|
|
725
769
|
!options.columns.includes("id"))
|
|
726
770
|
options.columns.push("id");
|
|
@@ -729,7 +773,8 @@ export default class Inibase {
|
|
|
729
773
|
options.page = options.page || 1;
|
|
730
774
|
options.perPage = options.perPage || 15;
|
|
731
775
|
let RETURN;
|
|
732
|
-
let schema = await this.
|
|
776
|
+
let schema = (await this.throwErrorIfTableEmpty(tableName))
|
|
777
|
+
.schema;
|
|
733
778
|
if (options.columns?.length)
|
|
734
779
|
schema = this._filterSchemaByColumns(schema, options.columns);
|
|
735
780
|
if (where &&
|
|
@@ -741,14 +786,14 @@ export default class Inibase {
|
|
|
741
786
|
RETURN = Object.values(await this.getItemsFromSchema(tableName, schema, Array.from({ length: options.perPage }, (_, index) => (options.page - 1) * options.perPage +
|
|
742
787
|
index +
|
|
743
788
|
1), options));
|
|
744
|
-
if (await File.isExists(join(tablePath, ".
|
|
745
|
-
this.totalItems[`${tableName}-*`] = Number((await
|
|
789
|
+
if (await File.isExists(join(tablePath, ".pagination")))
|
|
790
|
+
this.totalItems[`${tableName}-*`] = Number((await readFile(join(tablePath, ".pagination"), "utf8")).split(",")[1]);
|
|
746
791
|
else {
|
|
747
|
-
let [lastId, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension()}`), -1, "number", undefined, this.salt, true);
|
|
792
|
+
let [lastId, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), -1, "number", undefined, this.salt, true);
|
|
748
793
|
if (lastId)
|
|
749
794
|
lastId = Number(Object.keys(lastId)?.[0] ?? 0);
|
|
750
795
|
this.totalItems[`${tableName}-*`] = totalItems;
|
|
751
|
-
await
|
|
796
|
+
await writeFile(join(tablePath, ".pagination"), `${lastId},${totalItems}`);
|
|
752
797
|
}
|
|
753
798
|
}
|
|
754
799
|
else if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
|
|
@@ -771,7 +816,7 @@ export default class Inibase {
|
|
|
771
816
|
let Ids = where;
|
|
772
817
|
if (!Array.isArray(Ids))
|
|
773
818
|
Ids = [Ids];
|
|
774
|
-
const [lineNumbers, countItems] = await File.search(join(tablePath, `id${this.getFileExtension()}`), "[]", Ids.map((id) => Utils.isNumber(id) ? Number(id) : UtilsServer.decodeID(id, this.salt)), undefined, "number", undefined, Ids.length, 0, !this.totalItems[`${tableName}-*`], this.salt);
|
|
819
|
+
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);
|
|
775
820
|
if (!lineNumbers)
|
|
776
821
|
throw this.throwError("NO_RESULTS", tableName);
|
|
777
822
|
if (onlyLinesNumbers)
|
|
@@ -787,16 +832,17 @@ export default class Inibase {
|
|
|
787
832
|
else if (Utils.isObject(where)) {
|
|
788
833
|
let cachedFilePath = "";
|
|
789
834
|
// Criteria
|
|
790
|
-
if (
|
|
835
|
+
if (this.tables[tableName].config.cache)
|
|
791
836
|
cachedFilePath = join(tablePath, ".cache", `${UtilsServer.hashString(inspect(where, { sorted: true }))}${this.fileExtension}`);
|
|
792
|
-
if (
|
|
793
|
-
|
|
837
|
+
if (this.tables[tableName].config.cache &&
|
|
838
|
+
(await File.isExists(cachedFilePath))) {
|
|
839
|
+
const cachedItems = (await readFile(cachedFilePath, "utf8")).split(",");
|
|
794
840
|
this.totalItems[`${tableName}-*`] = cachedItems.length;
|
|
795
841
|
if (onlyLinesNumbers)
|
|
796
842
|
return cachedItems.map(Number);
|
|
797
843
|
return this.get(tableName, cachedItems
|
|
798
844
|
.slice((options.page - 1) * options.perPage, options.page * options.perPage)
|
|
799
|
-
.map(Number), options
|
|
845
|
+
.map(Number), options);
|
|
800
846
|
}
|
|
801
847
|
let linesNumbers = null;
|
|
802
848
|
[RETURN, linesNumbers] = await this.applyCriteria(tableName, schema, options, where);
|
|
@@ -805,8 +851,8 @@ export default class Inibase {
|
|
|
805
851
|
return Object.keys(RETURN).map(Number);
|
|
806
852
|
const alreadyExistsColumns = Object.keys(Object.values(RETURN)[0]);
|
|
807
853
|
RETURN = Object.values(Utils.deepMerge(RETURN, await this.getItemsFromSchema(tableName, schema.filter(({ key }) => !alreadyExistsColumns.includes(key)), Object.keys(RETURN).map(Number), options)));
|
|
808
|
-
if (
|
|
809
|
-
await
|
|
854
|
+
if (this.tables[tableName].config.cache)
|
|
855
|
+
await writeFile(cachedFilePath, Array.from(linesNumbers).join(","));
|
|
810
856
|
}
|
|
811
857
|
}
|
|
812
858
|
if (!RETURN ||
|
|
@@ -831,7 +877,7 @@ export default class Inibase {
|
|
|
831
877
|
page: 1,
|
|
832
878
|
perPage: 15,
|
|
833
879
|
};
|
|
834
|
-
const tablePath = join(this.
|
|
880
|
+
const tablePath = join(this.databasePath, tableName), schema = (await this.getTable(tableName)).schema;
|
|
835
881
|
if (!schema)
|
|
836
882
|
throw this.throwError("NO_SCHEMA", tableName);
|
|
837
883
|
if (!returnPostedData)
|
|
@@ -841,14 +887,14 @@ export default class Inibase {
|
|
|
841
887
|
let lastId = 0, totalItems = 0, renameList = [];
|
|
842
888
|
try {
|
|
843
889
|
await File.lock(join(tablePath, ".tmp"), keys);
|
|
844
|
-
if (await File.isExists(join(tablePath, `id${this.getFileExtension()}`))) {
|
|
845
|
-
if (await File.isExists(join(tablePath, ".
|
|
846
|
-
[lastId, totalItems] = (await
|
|
890
|
+
if (await File.isExists(join(tablePath, `id${this.getFileExtension(tableName)}`))) {
|
|
891
|
+
if (await File.isExists(join(tablePath, ".pagination")))
|
|
892
|
+
[lastId, totalItems] = (await readFile(join(tablePath, ".pagination"), "utf8"))
|
|
847
893
|
.split(",")
|
|
848
894
|
.map(Number);
|
|
849
895
|
else {
|
|
850
896
|
let lastIdObj = null;
|
|
851
|
-
[lastIdObj, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension()}`), -1, "number", undefined, this.salt, true);
|
|
897
|
+
[lastIdObj, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), -1, "number", undefined, this.salt, true);
|
|
852
898
|
if (lastIdObj)
|
|
853
899
|
lastId = Number(Object.keys(lastIdObj)?.[0] ?? 0);
|
|
854
900
|
}
|
|
@@ -868,27 +914,26 @@ export default class Inibase {
|
|
|
868
914
|
this.validateData(RETURN, schema);
|
|
869
915
|
await this.checkUnique(tableName, schema);
|
|
870
916
|
RETURN = this.formatData(RETURN, schema);
|
|
871
|
-
const pathesContents = this.joinPathesContents(
|
|
917
|
+
const pathesContents = this.joinPathesContents(tableName, this.tables[tableName].config.prepend
|
|
872
918
|
? Array.isArray(RETURN)
|
|
873
919
|
? RETURN.toReversed()
|
|
874
920
|
: RETURN
|
|
875
921
|
: RETURN);
|
|
876
|
-
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(await File.append(path, content))));
|
|
922
|
+
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(await File.append(path, content, this.tables[tableName].config.prepend))));
|
|
877
923
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
878
924
|
renameList = [];
|
|
879
925
|
totalItems += Array.isArray(RETURN) ? RETURN.length : 1;
|
|
880
|
-
if (
|
|
926
|
+
if (this.tables[tableName].config.cache)
|
|
881
927
|
await this.clearCache(tablePath);
|
|
882
|
-
await
|
|
928
|
+
await writeFile(join(tablePath, ".pagination"), `${lastId},${totalItems}`);
|
|
883
929
|
if (returnPostedData)
|
|
884
|
-
return this.get(tableName,
|
|
930
|
+
return this.get(tableName, this.tables[tableName].config.prepend
|
|
885
931
|
? Array.isArray(RETURN)
|
|
886
932
|
? RETURN.map((_, index) => index + 1)
|
|
887
933
|
: 1
|
|
888
934
|
: Array.isArray(RETURN)
|
|
889
935
|
? RETURN.map((_, index) => totalItems - index)
|
|
890
|
-
: totalItems, options, !Utils.isArrayOfObjects(data)
|
|
891
|
-
undefined, schema);
|
|
936
|
+
: totalItems, options, !Utils.isArrayOfObjects(data));
|
|
892
937
|
}
|
|
893
938
|
finally {
|
|
894
939
|
if (renameList.length)
|
|
@@ -901,7 +946,7 @@ export default class Inibase {
|
|
|
901
946
|
perPage: 15,
|
|
902
947
|
}, returnUpdatedData) {
|
|
903
948
|
let renameList = [];
|
|
904
|
-
const tablePath = join(this.
|
|
949
|
+
const tablePath = join(this.databasePath, tableName), schema = (await this.throwErrorIfTableEmpty(tableName)).schema;
|
|
905
950
|
this.validateData(data, schema, true);
|
|
906
951
|
await this.checkUnique(tableName, schema);
|
|
907
952
|
data = this.formatData(data, schema, true);
|
|
@@ -919,13 +964,13 @@ export default class Inibase {
|
|
|
919
964
|
return this.put(tableName, data, data.id);
|
|
920
965
|
}
|
|
921
966
|
let totalItems;
|
|
922
|
-
if (await File.isExists(join(tablePath, ".
|
|
923
|
-
totalItems = (await
|
|
967
|
+
if (await File.isExists(join(tablePath, ".pagination")))
|
|
968
|
+
totalItems = (await readFile(join(tablePath, ".pagination"), "utf8"))
|
|
924
969
|
.split(",")
|
|
925
970
|
.map(Number)[1];
|
|
926
971
|
else
|
|
927
|
-
totalItems = await File.count(join(tablePath, `id${this.getFileExtension()}`));
|
|
928
|
-
const pathesContents = this.joinPathesContents(
|
|
972
|
+
totalItems = await File.count(join(tablePath, `id${this.getFileExtension(tableName)}`));
|
|
973
|
+
const pathesContents = this.joinPathesContents(tableName, {
|
|
929
974
|
...(({ id, ...restOfData }) => restOfData)(data),
|
|
930
975
|
updatedAt: Date.now(),
|
|
931
976
|
});
|
|
@@ -938,10 +983,10 @@ export default class Inibase {
|
|
|
938
983
|
renameList.push(await File.replace(path, replacementObject));
|
|
939
984
|
}));
|
|
940
985
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
941
|
-
if (
|
|
986
|
+
if (this.tables[tableName].config.cache)
|
|
942
987
|
await this.clearCache(join(tablePath, ".cache"));
|
|
943
988
|
if (returnUpdatedData)
|
|
944
|
-
return await this.get(tableName,
|
|
989
|
+
return await this.get(tableName, undefined, options);
|
|
945
990
|
}
|
|
946
991
|
finally {
|
|
947
992
|
if (renameList.length)
|
|
@@ -951,13 +996,13 @@ export default class Inibase {
|
|
|
951
996
|
}
|
|
952
997
|
else if ((Array.isArray(where) && where.every(Utils.isValidID)) ||
|
|
953
998
|
Utils.isValidID(where)) {
|
|
954
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
999
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
955
1000
|
return this.put(tableName, data, lineNumbers);
|
|
956
1001
|
}
|
|
957
1002
|
else if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
|
|
958
1003
|
Utils.isNumber(where)) {
|
|
959
1004
|
// "where" in this case, is the line(s) number(s) and not id(s)
|
|
960
|
-
const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(
|
|
1005
|
+
const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(tableName, Utils.isArrayOfObjects(data)
|
|
961
1006
|
? data.map((item) => ({
|
|
962
1007
|
...item,
|
|
963
1008
|
updatedAt: Date.now(),
|
|
@@ -976,10 +1021,10 @@ export default class Inibase {
|
|
|
976
1021
|
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(await File.replace(path, content))));
|
|
977
1022
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
978
1023
|
renameList = [];
|
|
979
|
-
if (
|
|
1024
|
+
if (this.tables[tableName].config.cache)
|
|
980
1025
|
await this.clearCache(tablePath);
|
|
981
1026
|
if (returnUpdatedData)
|
|
982
|
-
return this.get(tableName, where, options, !Array.isArray(where)
|
|
1027
|
+
return this.get(tableName, where, options, !Array.isArray(where));
|
|
983
1028
|
}
|
|
984
1029
|
finally {
|
|
985
1030
|
if (renameList.length)
|
|
@@ -988,7 +1033,7 @@ export default class Inibase {
|
|
|
988
1033
|
}
|
|
989
1034
|
}
|
|
990
1035
|
else if (Utils.isObject(where)) {
|
|
991
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1036
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
992
1037
|
if (returnUpdatedData)
|
|
993
1038
|
return this.put(tableName, data, lineNumbers, options, returnUpdatedData);
|
|
994
1039
|
await this.put(tableName, data, lineNumbers, options, returnUpdatedData);
|
|
@@ -998,14 +1043,15 @@ export default class Inibase {
|
|
|
998
1043
|
}
|
|
999
1044
|
async delete(tableName, where, _id) {
|
|
1000
1045
|
const renameList = [];
|
|
1001
|
-
const tablePath = join(this.
|
|
1046
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1047
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1002
1048
|
if (!where) {
|
|
1003
1049
|
try {
|
|
1004
1050
|
await File.lock(join(tablePath, ".tmp"));
|
|
1005
1051
|
await Promise.all((await readdir(tablePath))
|
|
1006
1052
|
?.filter((fileName) => fileName.endsWith(".inib"))
|
|
1007
1053
|
.map(async (file) => unlink(join(tablePath, file))));
|
|
1008
|
-
if (
|
|
1054
|
+
if (this.tables[tableName].config.cache)
|
|
1009
1055
|
await this.clearCache(tablePath);
|
|
1010
1056
|
}
|
|
1011
1057
|
finally {
|
|
@@ -1015,25 +1061,25 @@ export default class Inibase {
|
|
|
1015
1061
|
}
|
|
1016
1062
|
if ((Array.isArray(where) && where.every(Utils.isValidID)) ||
|
|
1017
1063
|
Utils.isValidID(where)) {
|
|
1018
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1064
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1019
1065
|
return this.delete(tableName, lineNumbers, where);
|
|
1020
1066
|
}
|
|
1021
1067
|
if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
|
|
1022
1068
|
Utils.isNumber(where)) {
|
|
1023
1069
|
// "where" in this case, is the line(s) number(s) and not id(s)
|
|
1024
|
-
const files = (await readdir(tablePath))?.filter((fileName) => fileName.endsWith(this.getFileExtension()));
|
|
1070
|
+
const files = (await readdir(tablePath))?.filter((fileName) => fileName.endsWith(this.getFileExtension(tableName)));
|
|
1025
1071
|
if (files.length) {
|
|
1026
1072
|
try {
|
|
1027
1073
|
await File.lock(join(tablePath, ".tmp"));
|
|
1028
1074
|
await Promise.all(files.map(async (file) => renameList.push(await File.remove(join(tablePath, file), where))));
|
|
1029
1075
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
1030
|
-
if (
|
|
1076
|
+
if (this.tables[tableName].config.cache)
|
|
1031
1077
|
await this.clearCache(tablePath);
|
|
1032
|
-
if (await File.isExists(join(tablePath, ".
|
|
1033
|
-
const [lastId, totalItems] = (await
|
|
1078
|
+
if (await File.isExists(join(tablePath, ".pagination"))) {
|
|
1079
|
+
const [lastId, totalItems] = (await readFile(join(tablePath, ".pagination"), "utf8"))
|
|
1034
1080
|
.split(",")
|
|
1035
1081
|
.map(Number);
|
|
1036
|
-
await
|
|
1082
|
+
await writeFile(join(tablePath, ".pagination"), `${lastId},${totalItems - (Array.isArray(where) ? where.length : 1)}`);
|
|
1037
1083
|
}
|
|
1038
1084
|
if (_id)
|
|
1039
1085
|
return Array.isArray(_id) && _id.length === 1 ? _id[0] : _id;
|
|
@@ -1047,7 +1093,7 @@ export default class Inibase {
|
|
|
1047
1093
|
}
|
|
1048
1094
|
}
|
|
1049
1095
|
else if (Utils.isObject(where)) {
|
|
1050
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1096
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1051
1097
|
return this.delete(tableName, lineNumbers);
|
|
1052
1098
|
}
|
|
1053
1099
|
else
|
|
@@ -1056,14 +1102,15 @@ export default class Inibase {
|
|
|
1056
1102
|
}
|
|
1057
1103
|
async sum(tableName, columns, where) {
|
|
1058
1104
|
const RETURN = {};
|
|
1059
|
-
const tablePath = join(this.
|
|
1105
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1106
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1060
1107
|
if (!Array.isArray(columns))
|
|
1061
1108
|
columns = [columns];
|
|
1062
1109
|
for await (const column of columns) {
|
|
1063
|
-
const columnPath = join(tablePath, `${column}${this.getFileExtension()}`);
|
|
1110
|
+
const columnPath = join(tablePath, `${column}${this.getFileExtension(tableName)}`);
|
|
1064
1111
|
if (await File.isExists(columnPath)) {
|
|
1065
1112
|
if (where) {
|
|
1066
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1113
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1067
1114
|
RETURN[column] = lineNumbers
|
|
1068
1115
|
? await File.sum(columnPath, lineNumbers)
|
|
1069
1116
|
: 0;
|
|
@@ -1076,14 +1123,15 @@ export default class Inibase {
|
|
|
1076
1123
|
}
|
|
1077
1124
|
async max(tableName, columns, where) {
|
|
1078
1125
|
const RETURN = {};
|
|
1079
|
-
const tablePath = join(this.
|
|
1126
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1127
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1080
1128
|
if (!Array.isArray(columns))
|
|
1081
1129
|
columns = [columns];
|
|
1082
1130
|
for await (const column of columns) {
|
|
1083
|
-
const columnPath = join(tablePath, `${column}${this.getFileExtension()}`);
|
|
1131
|
+
const columnPath = join(tablePath, `${column}${this.getFileExtension(tableName)}`);
|
|
1084
1132
|
if (await File.isExists(columnPath)) {
|
|
1085
1133
|
if (where) {
|
|
1086
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1134
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1087
1135
|
RETURN[column] = lineNumbers
|
|
1088
1136
|
? await File.max(columnPath, lineNumbers)
|
|
1089
1137
|
: 0;
|
|
@@ -1096,14 +1144,15 @@ export default class Inibase {
|
|
|
1096
1144
|
}
|
|
1097
1145
|
async min(tableName, columns, where) {
|
|
1098
1146
|
const RETURN = {};
|
|
1099
|
-
const tablePath = join(this.
|
|
1147
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1148
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1100
1149
|
if (!Array.isArray(columns))
|
|
1101
1150
|
columns = [columns];
|
|
1102
1151
|
for await (const column of columns) {
|
|
1103
|
-
const columnPath = join(tablePath, `${column}${this.getFileExtension()}`);
|
|
1152
|
+
const columnPath = join(tablePath, `${column}${this.getFileExtension(tableName)}`);
|
|
1104
1153
|
if (await File.isExists(columnPath)) {
|
|
1105
1154
|
if (where) {
|
|
1106
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1155
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1107
1156
|
RETURN[column] = lineNumbers
|
|
1108
1157
|
? await File.min(columnPath, lineNumbers)
|
|
1109
1158
|
: 0;
|
|
@@ -1118,7 +1167,7 @@ export default class Inibase {
|
|
|
1118
1167
|
page: 1,
|
|
1119
1168
|
perPage: 15,
|
|
1120
1169
|
}) {
|
|
1121
|
-
const tablePath = join(this.
|
|
1170
|
+
const tablePath = join(this.databasePath, tableName), schema = (await this.throwErrorIfTableEmpty(tableName)).schema;
|
|
1122
1171
|
// Default values for page and perPage
|
|
1123
1172
|
options.page = options.page || 1;
|
|
1124
1173
|
options.perPage = options.perPage || 15;
|
|
@@ -1137,11 +1186,11 @@ export default class Inibase {
|
|
|
1137
1186
|
}
|
|
1138
1187
|
let cacheKey = "";
|
|
1139
1188
|
// Criteria
|
|
1140
|
-
if (
|
|
1189
|
+
if (this.tables[tableName].config.cache)
|
|
1141
1190
|
cacheKey = UtilsServer.hashString(inspect(sortArray, { sorted: true }));
|
|
1142
1191
|
if (where) {
|
|
1143
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1144
|
-
keepItems = Object.values((await File.get(join(tablePath, `id${this.getFileExtension()}`), lineNumbers, "number", undefined, this.salt)) ?? {}).map(Number);
|
|
1192
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1193
|
+
keepItems = Object.values((await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), lineNumbers, "number", undefined, this.salt)) ?? {}).map(Number);
|
|
1145
1194
|
isLineNumbers = false;
|
|
1146
1195
|
if (!keepItems.length)
|
|
1147
1196
|
throw this.throwError("NO_RESULTS", tableName);
|
|
@@ -1151,7 +1200,7 @@ export default class Inibase {
|
|
|
1151
1200
|
keepItems = Array.from({ length: options.perPage }, (_, index) => (options.page - 1) * options.perPage +
|
|
1152
1201
|
index +
|
|
1153
1202
|
1);
|
|
1154
|
-
const filesPathes = [["id", true], ...sortArray].map((column) => join(tablePath, `${column[0]}${this.getFileExtension()}`));
|
|
1203
|
+
const filesPathes = [["id", true], ...sortArray].map((column) => join(tablePath, `${column[0]}${this.getFileExtension(tableName)}`));
|
|
1155
1204
|
// Construct the paste command to merge files and filter lines by IDs
|
|
1156
1205
|
const pasteCommand = `paste ${filesPathes.join(" ")}`;
|
|
1157
1206
|
// Construct the sort command dynamically based on the number of files for sorting
|
|
@@ -1176,19 +1225,20 @@ export default class Inibase {
|
|
|
1176
1225
|
await File.lock(join(tablePath, ".tmp"), cacheKey);
|
|
1177
1226
|
// Combine the commands
|
|
1178
1227
|
// Execute the command synchronously
|
|
1179
|
-
const
|
|
1228
|
+
const lines = (await UtilsServer.exec(this.tables[tableName].config.cache
|
|
1180
1229
|
? (await File.isExists(join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)))
|
|
1181
1230
|
? `${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
|
|
1182
1231
|
: `${pasteCommand} | ${sortCommand} -o ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)} && ${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
|
|
1183
1232
|
: `${pasteCommand} | ${sortCommand} | ${awkCommand}`, {
|
|
1184
1233
|
encoding: "utf-8",
|
|
1185
|
-
})
|
|
1234
|
+
})).stdout
|
|
1235
|
+
.trim()
|
|
1236
|
+
.split("\n");
|
|
1186
1237
|
// Parse the result and extract the specified lines
|
|
1187
|
-
const lines = stdout.trim().split("\n");
|
|
1188
1238
|
const outputArray = lines.map((line) => {
|
|
1189
1239
|
const splitedFileColumns = line.split("\t"); // Assuming tab-separated columns
|
|
1190
1240
|
const outputObject = {};
|
|
1191
|
-
// Extract values for each file, including `id${this.getFileExtension()}`
|
|
1241
|
+
// Extract values for each file, including `id${this.getFileExtension(tableName)}`
|
|
1192
1242
|
filesPathes.forEach((fileName, index) => {
|
|
1193
1243
|
const field = Utils.getField(parse(fileName).name, schema);
|
|
1194
1244
|
if (field)
|
|
@@ -1196,7 +1246,7 @@ export default class Inibase {
|
|
|
1196
1246
|
});
|
|
1197
1247
|
return outputObject;
|
|
1198
1248
|
});
|
|
1199
|
-
const restOfColumns = await this.get(tableName, outputArray.map(({ id }) => id), options, undefined, undefined,
|
|
1249
|
+
const restOfColumns = await this.get(tableName, outputArray.map(({ id }) => id), options, undefined, undefined, true);
|
|
1200
1250
|
return restOfColumns
|
|
1201
1251
|
? outputArray.map((item, index) => ({
|
|
1202
1252
|
...item,
|