inibase 1.0.0-rc.60 → 1.0.0-rc.62
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/cli.js +12 -9
- package/dist/file.d.ts +3 -3
- package/dist/file.js +119 -147
- package/dist/index.d.ts +20 -11
- package/dist/index.js +203 -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,120 @@ 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
|
-
if (
|
|
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 mkdir(join(tablePath, ".tmp"), { recursive: true });
|
|
89
|
+
await mkdir(join(tablePath, ".cache"));
|
|
90
|
+
if (config) {
|
|
91
|
+
if (config.compression)
|
|
92
|
+
await open(join(tablePath, ".compression.config"), "w");
|
|
93
|
+
if (config.cache)
|
|
94
|
+
await open(join(tablePath, ".cache.config"), "w");
|
|
95
|
+
if (config.prepend)
|
|
96
|
+
await open(join(tablePath, ".prepend.config"), "w");
|
|
97
|
+
}
|
|
98
|
+
if (schema)
|
|
99
|
+
await writeFile(join(tablePath, "schema.json"), JSON.stringify(UtilsServer.addIdToSchema(schema, 0, this.salt, false), null, 2));
|
|
100
|
+
}
|
|
101
|
+
async updateTable(tableName, schema, config) {
|
|
102
|
+
const table = await this.getTable(tableName), tablePath = join(this.databasePath, tableName);
|
|
103
|
+
if (config) {
|
|
104
|
+
if (config.compression !== undefined) {
|
|
105
|
+
if (!config.compression && table.config.compression) {
|
|
106
|
+
try {
|
|
107
|
+
await UtilsServer.exec(`gunzip -r ${tablePath}/*.txt.gz 2>/dev/null`);
|
|
108
|
+
await unlink(join(tablePath, ".compression.config"));
|
|
109
|
+
}
|
|
110
|
+
catch { }
|
|
111
|
+
}
|
|
112
|
+
else if (config.compression && !table.config.compression) {
|
|
113
|
+
try {
|
|
114
|
+
await UtilsServer.exec(`gzip -r ${tablePath}/*.txt 2>/dev/null`);
|
|
115
|
+
await open(join(tablePath, ".compression.config"), "w");
|
|
116
|
+
}
|
|
117
|
+
catch { }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (config.cache !== undefined) {
|
|
121
|
+
if (config.cache && !table.config.cache)
|
|
122
|
+
await open(join(tablePath, ".cache.config"), "w");
|
|
123
|
+
else if (!config.cache && table.config.cache)
|
|
124
|
+
await unlink(join(tablePath, ".cache.config"));
|
|
125
|
+
}
|
|
126
|
+
if (config.prepend !== undefined) {
|
|
127
|
+
if (config.prepend && !table.config.prepend)
|
|
128
|
+
await open(join(tablePath, ".prepend.config"), "w");
|
|
129
|
+
else if (!config.prepend && table.config.prepend)
|
|
130
|
+
await unlink(join(tablePath, ".prepend.config"));
|
|
121
131
|
}
|
|
122
132
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
if (schema) {
|
|
134
|
+
// remove id from schema
|
|
135
|
+
schema = schema.filter(({ key }) => !["id", "createdAt", "updatedAt"].includes(key));
|
|
136
|
+
if (await File.isExists(join(tablePath, "schema.json"))) {
|
|
137
|
+
// update columns files names based on field id
|
|
138
|
+
const currentSchema = await this.getTableSchema(tableName, false);
|
|
139
|
+
schema = UtilsServer.addIdToSchema(schema, currentSchema?.length
|
|
140
|
+
? UtilsServer.findLastIdNumber(currentSchema, this.salt)
|
|
141
|
+
: 0, this.salt, false);
|
|
142
|
+
if (currentSchema?.length) {
|
|
143
|
+
const replaceOldPathes = Utils.findChangedProperties(this._schemaToIdsPath(tableName, currentSchema), this._schemaToIdsPath(tableName, schema));
|
|
144
|
+
if (replaceOldPathes)
|
|
145
|
+
await Promise.all(Object.entries(replaceOldPathes).map(async ([oldPath, newPath]) => {
|
|
146
|
+
if (await File.isExists(join(tablePath, oldPath)))
|
|
147
|
+
await rename(join(tablePath, oldPath), join(tablePath, newPath));
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else
|
|
152
|
+
schema = UtilsServer.addIdToSchema(schema, 0, this.salt, false);
|
|
153
|
+
await writeFile(join(tablePath, "schema.json"), JSON.stringify(schema, null, 2));
|
|
154
|
+
delete this.tables[tableName];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async getTable(tableName) {
|
|
158
|
+
const tablePath = join(this.databasePath, tableName);
|
|
159
|
+
if (!(await File.isExists(tablePath)))
|
|
160
|
+
this.throwError("TABLE_NOT_EXISTS", tableName);
|
|
161
|
+
if (!this.tables[tableName])
|
|
162
|
+
this.tables[tableName] = {
|
|
163
|
+
schema: await this.getTableSchema(tableName),
|
|
164
|
+
config: {
|
|
165
|
+
compression: await File.isExists(join(tablePath, ".compression.config")),
|
|
166
|
+
cache: await File.isExists(join(tablePath, ".cache.config")),
|
|
167
|
+
prepend: await File.isExists(join(tablePath, ".prepend.config")),
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
return this.tables[tableName];
|
|
126
171
|
}
|
|
127
172
|
async getTableSchema(tableName, encodeIDs = true) {
|
|
128
|
-
const tableSchemaPath = join(this.
|
|
173
|
+
const tableSchemaPath = join(this.databasePath, tableName, "schema.json");
|
|
129
174
|
if (!(await File.isExists(tableSchemaPath)))
|
|
130
175
|
return undefined;
|
|
131
|
-
const schemaFile = await
|
|
176
|
+
const schemaFile = await readFile(tableSchemaPath, "utf8");
|
|
132
177
|
if (!schemaFile)
|
|
133
178
|
return undefined;
|
|
134
179
|
const schema = JSON.parse(schemaFile), lastIdNumber = UtilsServer.findLastIdNumber(schema, this.salt);
|
|
@@ -156,15 +201,13 @@ export default class Inibase {
|
|
|
156
201
|
},
|
|
157
202
|
];
|
|
158
203
|
}
|
|
159
|
-
async
|
|
160
|
-
const
|
|
161
|
-
if (!schema)
|
|
162
|
-
schema = await this.getTableSchema(tableName);
|
|
163
|
-
if (!schema)
|
|
204
|
+
async throwErrorIfTableEmpty(tableName) {
|
|
205
|
+
const table = await this.getTable(tableName);
|
|
206
|
+
if (!table.schema)
|
|
164
207
|
throw this.throwError("NO_SCHEMA", tableName);
|
|
165
|
-
if (!(await File.isExists(join(
|
|
208
|
+
if (!(await File.isExists(join(this.databasePath, tableName, `id${this.getFileExtension(tableName)}`))))
|
|
166
209
|
throw this.throwError("NO_ITEMS", tableName);
|
|
167
|
-
return
|
|
210
|
+
return table;
|
|
168
211
|
}
|
|
169
212
|
validateData(data, schema, skipRequiredField = false) {
|
|
170
213
|
if (Utils.isArrayOfObjects(data))
|
|
@@ -285,12 +328,12 @@ export default class Inibase {
|
|
|
285
328
|
return null;
|
|
286
329
|
}
|
|
287
330
|
async checkUnique(tableName, schema) {
|
|
288
|
-
const tablePath = join(this.
|
|
331
|
+
const tablePath = join(this.databasePath, tableName);
|
|
289
332
|
for await (const [key, values] of Object.entries(this.checkIFunique)) {
|
|
290
333
|
const field = Utils.getField(key, schema);
|
|
291
334
|
if (!field)
|
|
292
335
|
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);
|
|
336
|
+
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
337
|
if (searchResult && totalLines > 0)
|
|
295
338
|
throw this.throwError("FIELD_UNIQUE", [
|
|
296
339
|
field.key,
|
|
@@ -376,14 +419,12 @@ export default class Inibase {
|
|
|
376
419
|
}
|
|
377
420
|
return RETURN;
|
|
378
421
|
};
|
|
379
|
-
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
joinPathesContents(mainPath, data) {
|
|
386
|
-
return this._addPathToKeys(this._CombineData(data), mainPath);
|
|
422
|
+
joinPathesContents(tableName, data) {
|
|
423
|
+
const tablePath = join(this.databasePath, tableName), combinedData = this._CombineData(data);
|
|
424
|
+
const newCombinedData = {};
|
|
425
|
+
for (const [key, value] of Object.entries(combinedData))
|
|
426
|
+
newCombinedData[join(tablePath, `${key}${this.getFileExtension(tableName)}`)] = value;
|
|
427
|
+
return newCombinedData;
|
|
387
428
|
}
|
|
388
429
|
_getItemsFromSchemaHelper(RETURN, item, index, field) {
|
|
389
430
|
if (Utils.isObject(item)) {
|
|
@@ -427,7 +468,7 @@ export default class Inibase {
|
|
|
427
468
|
}
|
|
428
469
|
}
|
|
429
470
|
async getItemsFromSchema(tableName, schema, linesNumber, options, prefix) {
|
|
430
|
-
const tablePath = join(this.
|
|
471
|
+
const tablePath = join(this.databasePath, tableName);
|
|
431
472
|
let RETURN = {};
|
|
432
473
|
for await (const field of schema) {
|
|
433
474
|
if ((field.type === "array" ||
|
|
@@ -498,13 +539,13 @@ export default class Inibase {
|
|
|
498
539
|
(Array.isArray(field.type) && field.type.includes("table")) ||
|
|
499
540
|
(Array.isArray(field.children) && field.children.includes("table"))) {
|
|
500
541
|
if (field.table &&
|
|
501
|
-
(await File.isExists(join(this.
|
|
502
|
-
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`)))) {
|
|
542
|
+
(await File.isExists(join(this.databasePath, field.table))) &&
|
|
543
|
+
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`)))) {
|
|
503
544
|
if (options.columns)
|
|
504
545
|
options.columns = options.columns
|
|
505
546
|
.filter((column) => column.includes(`${field.key}.`))
|
|
506
547
|
.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);
|
|
548
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, field.type, field.children, this.salt);
|
|
508
549
|
if (items)
|
|
509
550
|
for await (const [index, item] of Object.entries(items)) {
|
|
510
551
|
if (!RETURN[index])
|
|
@@ -515,8 +556,8 @@ export default class Inibase {
|
|
|
515
556
|
}
|
|
516
557
|
}
|
|
517
558
|
}
|
|
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);
|
|
559
|
+
else if (await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`))) {
|
|
560
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, field.type, field.children, this.salt);
|
|
520
561
|
if (items)
|
|
521
562
|
for (const [index, item] of Object.entries(items)) {
|
|
522
563
|
if (!RETURN[index])
|
|
@@ -543,13 +584,13 @@ export default class Inibase {
|
|
|
543
584
|
}
|
|
544
585
|
else if (field.type === "table") {
|
|
545
586
|
if (field.table &&
|
|
546
|
-
(await File.isExists(join(this.
|
|
547
|
-
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`)))) {
|
|
587
|
+
(await File.isExists(join(this.databasePath, field.table))) &&
|
|
588
|
+
(await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`)))) {
|
|
548
589
|
if (options.columns)
|
|
549
590
|
options.columns = options.columns
|
|
550
591
|
.filter((column) => column.includes(`${field.key}.`))
|
|
551
592
|
.map((column) => column.replace(`${field.key}.`, ""));
|
|
552
|
-
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension()}`), linesNumber, "number", undefined, this.salt);
|
|
593
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, "number", undefined, this.salt);
|
|
553
594
|
if (items)
|
|
554
595
|
for await (const [index, item] of Object.entries(items)) {
|
|
555
596
|
if (!RETURN[index])
|
|
@@ -560,8 +601,8 @@ export default class Inibase {
|
|
|
560
601
|
}
|
|
561
602
|
}
|
|
562
603
|
}
|
|
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);
|
|
604
|
+
else if (await File.isExists(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`))) {
|
|
605
|
+
const items = await File.get(join(tablePath, `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`), linesNumber, field.type, field.children, this.salt);
|
|
565
606
|
if (items)
|
|
566
607
|
for (const [index, item] of Object.entries(items)) {
|
|
567
608
|
if (!RETURN[index])
|
|
@@ -578,7 +619,7 @@ export default class Inibase {
|
|
|
578
619
|
return RETURN;
|
|
579
620
|
}
|
|
580
621
|
async applyCriteria(tableName, schema, options, criteria, allTrue) {
|
|
581
|
-
const tablePath = join(this.
|
|
622
|
+
const tablePath = join(this.databasePath, tableName);
|
|
582
623
|
let RETURN = {}, RETURN_LineNumbers = null;
|
|
583
624
|
if (!criteria)
|
|
584
625
|
return [null, null];
|
|
@@ -662,7 +703,7 @@ export default class Inibase {
|
|
|
662
703
|
searchOperator = "=";
|
|
663
704
|
searchComparedAtValue = value;
|
|
664
705
|
}
|
|
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);
|
|
706
|
+
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
707
|
if (searchResult) {
|
|
667
708
|
RETURN = Utils.deepMerge(RETURN, Object.fromEntries(Object.entries(searchResult).map(([id, value]) => [
|
|
668
709
|
id,
|
|
@@ -713,14 +754,14 @@ export default class Inibase {
|
|
|
713
754
|
async get(tableName, where, options = {
|
|
714
755
|
page: 1,
|
|
715
756
|
perPage: 15,
|
|
716
|
-
}, onlyOne, onlyLinesNumbers,
|
|
717
|
-
const tablePath = join(this.
|
|
757
|
+
}, onlyOne, onlyLinesNumbers, _skipIdColumn) {
|
|
758
|
+
const tablePath = join(this.databasePath, tableName);
|
|
718
759
|
// Ensure options.columns is an array
|
|
719
760
|
if (options.columns) {
|
|
720
761
|
options.columns = Array.isArray(options.columns)
|
|
721
762
|
? options.columns
|
|
722
763
|
: [options.columns];
|
|
723
|
-
if (!
|
|
764
|
+
if (!_skipIdColumn &&
|
|
724
765
|
options.columns.length &&
|
|
725
766
|
!options.columns.includes("id"))
|
|
726
767
|
options.columns.push("id");
|
|
@@ -729,7 +770,8 @@ export default class Inibase {
|
|
|
729
770
|
options.page = options.page || 1;
|
|
730
771
|
options.perPage = options.perPage || 15;
|
|
731
772
|
let RETURN;
|
|
732
|
-
let schema = await this.
|
|
773
|
+
let schema = (await this.throwErrorIfTableEmpty(tableName))
|
|
774
|
+
.schema;
|
|
733
775
|
if (options.columns?.length)
|
|
734
776
|
schema = this._filterSchemaByColumns(schema, options.columns);
|
|
735
777
|
if (where &&
|
|
@@ -741,14 +783,14 @@ export default class Inibase {
|
|
|
741
783
|
RETURN = Object.values(await this.getItemsFromSchema(tableName, schema, Array.from({ length: options.perPage }, (_, index) => (options.page - 1) * options.perPage +
|
|
742
784
|
index +
|
|
743
785
|
1), options));
|
|
744
|
-
if (await File.isExists(join(tablePath, ".
|
|
745
|
-
this.totalItems[`${tableName}-*`] = Number((await
|
|
786
|
+
if (await File.isExists(join(tablePath, ".pagination")))
|
|
787
|
+
this.totalItems[`${tableName}-*`] = Number((await readFile(join(tablePath, ".pagination"), "utf8")).split(",")[1]);
|
|
746
788
|
else {
|
|
747
|
-
let [lastId, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension()}`), -1, "number", undefined, this.salt, true);
|
|
789
|
+
let [lastId, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), -1, "number", undefined, this.salt, true);
|
|
748
790
|
if (lastId)
|
|
749
791
|
lastId = Number(Object.keys(lastId)?.[0] ?? 0);
|
|
750
792
|
this.totalItems[`${tableName}-*`] = totalItems;
|
|
751
|
-
await
|
|
793
|
+
await writeFile(join(tablePath, ".pagination"), `${lastId},${totalItems}`);
|
|
752
794
|
}
|
|
753
795
|
}
|
|
754
796
|
else if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
|
|
@@ -771,7 +813,7 @@ export default class Inibase {
|
|
|
771
813
|
let Ids = where;
|
|
772
814
|
if (!Array.isArray(Ids))
|
|
773
815
|
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);
|
|
816
|
+
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
817
|
if (!lineNumbers)
|
|
776
818
|
throw this.throwError("NO_RESULTS", tableName);
|
|
777
819
|
if (onlyLinesNumbers)
|
|
@@ -787,16 +829,17 @@ export default class Inibase {
|
|
|
787
829
|
else if (Utils.isObject(where)) {
|
|
788
830
|
let cachedFilePath = "";
|
|
789
831
|
// Criteria
|
|
790
|
-
if (
|
|
832
|
+
if (this.tables[tableName].config.cache)
|
|
791
833
|
cachedFilePath = join(tablePath, ".cache", `${UtilsServer.hashString(inspect(where, { sorted: true }))}${this.fileExtension}`);
|
|
792
|
-
if (
|
|
793
|
-
|
|
834
|
+
if (this.tables[tableName].config.cache &&
|
|
835
|
+
(await File.isExists(cachedFilePath))) {
|
|
836
|
+
const cachedItems = (await readFile(cachedFilePath, "utf8")).split(",");
|
|
794
837
|
this.totalItems[`${tableName}-*`] = cachedItems.length;
|
|
795
838
|
if (onlyLinesNumbers)
|
|
796
839
|
return cachedItems.map(Number);
|
|
797
840
|
return this.get(tableName, cachedItems
|
|
798
841
|
.slice((options.page - 1) * options.perPage, options.page * options.perPage)
|
|
799
|
-
.map(Number), options
|
|
842
|
+
.map(Number), options);
|
|
800
843
|
}
|
|
801
844
|
let linesNumbers = null;
|
|
802
845
|
[RETURN, linesNumbers] = await this.applyCriteria(tableName, schema, options, where);
|
|
@@ -805,8 +848,8 @@ export default class Inibase {
|
|
|
805
848
|
return Object.keys(RETURN).map(Number);
|
|
806
849
|
const alreadyExistsColumns = Object.keys(Object.values(RETURN)[0]);
|
|
807
850
|
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
|
|
851
|
+
if (this.tables[tableName].config.cache)
|
|
852
|
+
await writeFile(cachedFilePath, Array.from(linesNumbers).join(","));
|
|
810
853
|
}
|
|
811
854
|
}
|
|
812
855
|
if (!RETURN ||
|
|
@@ -831,7 +874,7 @@ export default class Inibase {
|
|
|
831
874
|
page: 1,
|
|
832
875
|
perPage: 15,
|
|
833
876
|
};
|
|
834
|
-
const tablePath = join(this.
|
|
877
|
+
const tablePath = join(this.databasePath, tableName), schema = (await this.getTable(tableName)).schema;
|
|
835
878
|
if (!schema)
|
|
836
879
|
throw this.throwError("NO_SCHEMA", tableName);
|
|
837
880
|
if (!returnPostedData)
|
|
@@ -841,14 +884,14 @@ export default class Inibase {
|
|
|
841
884
|
let lastId = 0, totalItems = 0, renameList = [];
|
|
842
885
|
try {
|
|
843
886
|
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
|
|
887
|
+
if (await File.isExists(join(tablePath, `id${this.getFileExtension(tableName)}`))) {
|
|
888
|
+
if (await File.isExists(join(tablePath, ".pagination")))
|
|
889
|
+
[lastId, totalItems] = (await readFile(join(tablePath, ".pagination"), "utf8"))
|
|
847
890
|
.split(",")
|
|
848
891
|
.map(Number);
|
|
849
892
|
else {
|
|
850
893
|
let lastIdObj = null;
|
|
851
|
-
[lastIdObj, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension()}`), -1, "number", undefined, this.salt, true);
|
|
894
|
+
[lastIdObj, totalItems] = await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), -1, "number", undefined, this.salt, true);
|
|
852
895
|
if (lastIdObj)
|
|
853
896
|
lastId = Number(Object.keys(lastIdObj)?.[0] ?? 0);
|
|
854
897
|
}
|
|
@@ -868,27 +911,26 @@ export default class Inibase {
|
|
|
868
911
|
this.validateData(RETURN, schema);
|
|
869
912
|
await this.checkUnique(tableName, schema);
|
|
870
913
|
RETURN = this.formatData(RETURN, schema);
|
|
871
|
-
const pathesContents = this.joinPathesContents(
|
|
914
|
+
const pathesContents = this.joinPathesContents(tableName, this.tables[tableName].config.prepend
|
|
872
915
|
? Array.isArray(RETURN)
|
|
873
916
|
? RETURN.toReversed()
|
|
874
917
|
: RETURN
|
|
875
918
|
: RETURN);
|
|
876
|
-
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(await File.append(path, content))));
|
|
919
|
+
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(await File.append(path, content, this.tables[tableName].config.prepend))));
|
|
877
920
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
878
921
|
renameList = [];
|
|
879
922
|
totalItems += Array.isArray(RETURN) ? RETURN.length : 1;
|
|
880
|
-
if (
|
|
923
|
+
if (this.tables[tableName].config.cache)
|
|
881
924
|
await this.clearCache(tablePath);
|
|
882
|
-
await
|
|
925
|
+
await writeFile(join(tablePath, ".pagination"), `${lastId},${totalItems}`);
|
|
883
926
|
if (returnPostedData)
|
|
884
|
-
return this.get(tableName,
|
|
927
|
+
return this.get(tableName, this.tables[tableName].config.prepend
|
|
885
928
|
? Array.isArray(RETURN)
|
|
886
929
|
? RETURN.map((_, index) => index + 1)
|
|
887
930
|
: 1
|
|
888
931
|
: Array.isArray(RETURN)
|
|
889
932
|
? RETURN.map((_, index) => totalItems - index)
|
|
890
|
-
: totalItems, options, !Utils.isArrayOfObjects(data)
|
|
891
|
-
undefined, schema);
|
|
933
|
+
: totalItems, options, !Utils.isArrayOfObjects(data));
|
|
892
934
|
}
|
|
893
935
|
finally {
|
|
894
936
|
if (renameList.length)
|
|
@@ -901,7 +943,7 @@ export default class Inibase {
|
|
|
901
943
|
perPage: 15,
|
|
902
944
|
}, returnUpdatedData) {
|
|
903
945
|
let renameList = [];
|
|
904
|
-
const tablePath = join(this.
|
|
946
|
+
const tablePath = join(this.databasePath, tableName), schema = (await this.throwErrorIfTableEmpty(tableName)).schema;
|
|
905
947
|
this.validateData(data, schema, true);
|
|
906
948
|
await this.checkUnique(tableName, schema);
|
|
907
949
|
data = this.formatData(data, schema, true);
|
|
@@ -919,13 +961,13 @@ export default class Inibase {
|
|
|
919
961
|
return this.put(tableName, data, data.id);
|
|
920
962
|
}
|
|
921
963
|
let totalItems;
|
|
922
|
-
if (await File.isExists(join(tablePath, ".
|
|
923
|
-
totalItems = (await
|
|
964
|
+
if (await File.isExists(join(tablePath, ".pagination")))
|
|
965
|
+
totalItems = (await readFile(join(tablePath, ".pagination"), "utf8"))
|
|
924
966
|
.split(",")
|
|
925
967
|
.map(Number)[1];
|
|
926
968
|
else
|
|
927
|
-
totalItems = await File.count(join(tablePath, `id${this.getFileExtension()}`));
|
|
928
|
-
const pathesContents = this.joinPathesContents(
|
|
969
|
+
totalItems = await File.count(join(tablePath, `id${this.getFileExtension(tableName)}`));
|
|
970
|
+
const pathesContents = this.joinPathesContents(tableName, {
|
|
929
971
|
...(({ id, ...restOfData }) => restOfData)(data),
|
|
930
972
|
updatedAt: Date.now(),
|
|
931
973
|
});
|
|
@@ -938,10 +980,10 @@ export default class Inibase {
|
|
|
938
980
|
renameList.push(await File.replace(path, replacementObject));
|
|
939
981
|
}));
|
|
940
982
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
941
|
-
if (
|
|
983
|
+
if (this.tables[tableName].config.cache)
|
|
942
984
|
await this.clearCache(join(tablePath, ".cache"));
|
|
943
985
|
if (returnUpdatedData)
|
|
944
|
-
return await this.get(tableName,
|
|
986
|
+
return await this.get(tableName, undefined, options);
|
|
945
987
|
}
|
|
946
988
|
finally {
|
|
947
989
|
if (renameList.length)
|
|
@@ -951,13 +993,13 @@ export default class Inibase {
|
|
|
951
993
|
}
|
|
952
994
|
else if ((Array.isArray(where) && where.every(Utils.isValidID)) ||
|
|
953
995
|
Utils.isValidID(where)) {
|
|
954
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
996
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
955
997
|
return this.put(tableName, data, lineNumbers);
|
|
956
998
|
}
|
|
957
999
|
else if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
|
|
958
1000
|
Utils.isNumber(where)) {
|
|
959
1001
|
// "where" in this case, is the line(s) number(s) and not id(s)
|
|
960
|
-
const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(
|
|
1002
|
+
const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(tableName, Utils.isArrayOfObjects(data)
|
|
961
1003
|
? data.map((item) => ({
|
|
962
1004
|
...item,
|
|
963
1005
|
updatedAt: Date.now(),
|
|
@@ -976,10 +1018,10 @@ export default class Inibase {
|
|
|
976
1018
|
await Promise.all(Object.entries(pathesContents).map(async ([path, content]) => renameList.push(await File.replace(path, content))));
|
|
977
1019
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
978
1020
|
renameList = [];
|
|
979
|
-
if (
|
|
1021
|
+
if (this.tables[tableName].config.cache)
|
|
980
1022
|
await this.clearCache(tablePath);
|
|
981
1023
|
if (returnUpdatedData)
|
|
982
|
-
return this.get(tableName, where, options, !Array.isArray(where)
|
|
1024
|
+
return this.get(tableName, where, options, !Array.isArray(where));
|
|
983
1025
|
}
|
|
984
1026
|
finally {
|
|
985
1027
|
if (renameList.length)
|
|
@@ -988,7 +1030,7 @@ export default class Inibase {
|
|
|
988
1030
|
}
|
|
989
1031
|
}
|
|
990
1032
|
else if (Utils.isObject(where)) {
|
|
991
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1033
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
992
1034
|
if (returnUpdatedData)
|
|
993
1035
|
return this.put(tableName, data, lineNumbers, options, returnUpdatedData);
|
|
994
1036
|
await this.put(tableName, data, lineNumbers, options, returnUpdatedData);
|
|
@@ -998,14 +1040,15 @@ export default class Inibase {
|
|
|
998
1040
|
}
|
|
999
1041
|
async delete(tableName, where, _id) {
|
|
1000
1042
|
const renameList = [];
|
|
1001
|
-
const tablePath = join(this.
|
|
1043
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1044
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1002
1045
|
if (!where) {
|
|
1003
1046
|
try {
|
|
1004
1047
|
await File.lock(join(tablePath, ".tmp"));
|
|
1005
1048
|
await Promise.all((await readdir(tablePath))
|
|
1006
1049
|
?.filter((fileName) => fileName.endsWith(".inib"))
|
|
1007
1050
|
.map(async (file) => unlink(join(tablePath, file))));
|
|
1008
|
-
if (
|
|
1051
|
+
if (this.tables[tableName].config.cache)
|
|
1009
1052
|
await this.clearCache(tablePath);
|
|
1010
1053
|
}
|
|
1011
1054
|
finally {
|
|
@@ -1015,25 +1058,25 @@ export default class Inibase {
|
|
|
1015
1058
|
}
|
|
1016
1059
|
if ((Array.isArray(where) && where.every(Utils.isValidID)) ||
|
|
1017
1060
|
Utils.isValidID(where)) {
|
|
1018
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1061
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1019
1062
|
return this.delete(tableName, lineNumbers, where);
|
|
1020
1063
|
}
|
|
1021
1064
|
if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
|
|
1022
1065
|
Utils.isNumber(where)) {
|
|
1023
1066
|
// "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()));
|
|
1067
|
+
const files = (await readdir(tablePath))?.filter((fileName) => fileName.endsWith(this.getFileExtension(tableName)));
|
|
1025
1068
|
if (files.length) {
|
|
1026
1069
|
try {
|
|
1027
1070
|
await File.lock(join(tablePath, ".tmp"));
|
|
1028
1071
|
await Promise.all(files.map(async (file) => renameList.push(await File.remove(join(tablePath, file), where))));
|
|
1029
1072
|
await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
1030
|
-
if (
|
|
1073
|
+
if (this.tables[tableName].config.cache)
|
|
1031
1074
|
await this.clearCache(tablePath);
|
|
1032
|
-
if (await File.isExists(join(tablePath, ".
|
|
1033
|
-
const [lastId, totalItems] = (await
|
|
1075
|
+
if (await File.isExists(join(tablePath, ".pagination"))) {
|
|
1076
|
+
const [lastId, totalItems] = (await readFile(join(tablePath, ".pagination"), "utf8"))
|
|
1034
1077
|
.split(",")
|
|
1035
1078
|
.map(Number);
|
|
1036
|
-
await
|
|
1079
|
+
await writeFile(join(tablePath, ".pagination"), `${lastId},${totalItems - (Array.isArray(where) ? where.length : 1)}`);
|
|
1037
1080
|
}
|
|
1038
1081
|
if (_id)
|
|
1039
1082
|
return Array.isArray(_id) && _id.length === 1 ? _id[0] : _id;
|
|
@@ -1047,7 +1090,7 @@ export default class Inibase {
|
|
|
1047
1090
|
}
|
|
1048
1091
|
}
|
|
1049
1092
|
else if (Utils.isObject(where)) {
|
|
1050
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1093
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1051
1094
|
return this.delete(tableName, lineNumbers);
|
|
1052
1095
|
}
|
|
1053
1096
|
else
|
|
@@ -1056,14 +1099,15 @@ export default class Inibase {
|
|
|
1056
1099
|
}
|
|
1057
1100
|
async sum(tableName, columns, where) {
|
|
1058
1101
|
const RETURN = {};
|
|
1059
|
-
const tablePath = join(this.
|
|
1102
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1103
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1060
1104
|
if (!Array.isArray(columns))
|
|
1061
1105
|
columns = [columns];
|
|
1062
1106
|
for await (const column of columns) {
|
|
1063
|
-
const columnPath = join(tablePath, `${column}${this.getFileExtension()}`);
|
|
1107
|
+
const columnPath = join(tablePath, `${column}${this.getFileExtension(tableName)}`);
|
|
1064
1108
|
if (await File.isExists(columnPath)) {
|
|
1065
1109
|
if (where) {
|
|
1066
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1110
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1067
1111
|
RETURN[column] = lineNumbers
|
|
1068
1112
|
? await File.sum(columnPath, lineNumbers)
|
|
1069
1113
|
: 0;
|
|
@@ -1076,14 +1120,15 @@ export default class Inibase {
|
|
|
1076
1120
|
}
|
|
1077
1121
|
async max(tableName, columns, where) {
|
|
1078
1122
|
const RETURN = {};
|
|
1079
|
-
const tablePath = join(this.
|
|
1123
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1124
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1080
1125
|
if (!Array.isArray(columns))
|
|
1081
1126
|
columns = [columns];
|
|
1082
1127
|
for await (const column of columns) {
|
|
1083
|
-
const columnPath = join(tablePath, `${column}${this.getFileExtension()}`);
|
|
1128
|
+
const columnPath = join(tablePath, `${column}${this.getFileExtension(tableName)}`);
|
|
1084
1129
|
if (await File.isExists(columnPath)) {
|
|
1085
1130
|
if (where) {
|
|
1086
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1131
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1087
1132
|
RETURN[column] = lineNumbers
|
|
1088
1133
|
? await File.max(columnPath, lineNumbers)
|
|
1089
1134
|
: 0;
|
|
@@ -1096,14 +1141,15 @@ export default class Inibase {
|
|
|
1096
1141
|
}
|
|
1097
1142
|
async min(tableName, columns, where) {
|
|
1098
1143
|
const RETURN = {};
|
|
1099
|
-
const tablePath = join(this.
|
|
1144
|
+
const tablePath = join(this.databasePath, tableName);
|
|
1145
|
+
await this.throwErrorIfTableEmpty(tableName);
|
|
1100
1146
|
if (!Array.isArray(columns))
|
|
1101
1147
|
columns = [columns];
|
|
1102
1148
|
for await (const column of columns) {
|
|
1103
|
-
const columnPath = join(tablePath, `${column}${this.getFileExtension()}`);
|
|
1149
|
+
const columnPath = join(tablePath, `${column}${this.getFileExtension(tableName)}`);
|
|
1104
1150
|
if (await File.isExists(columnPath)) {
|
|
1105
1151
|
if (where) {
|
|
1106
|
-
const lineNumbers = await this.get(tableName, where, undefined, undefined, true
|
|
1152
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1107
1153
|
RETURN[column] = lineNumbers
|
|
1108
1154
|
? await File.min(columnPath, lineNumbers)
|
|
1109
1155
|
: 0;
|
|
@@ -1118,7 +1164,7 @@ export default class Inibase {
|
|
|
1118
1164
|
page: 1,
|
|
1119
1165
|
perPage: 15,
|
|
1120
1166
|
}) {
|
|
1121
|
-
const tablePath = join(this.
|
|
1167
|
+
const tablePath = join(this.databasePath, tableName), schema = (await this.throwErrorIfTableEmpty(tableName)).schema;
|
|
1122
1168
|
// Default values for page and perPage
|
|
1123
1169
|
options.page = options.page || 1;
|
|
1124
1170
|
options.perPage = options.perPage || 15;
|
|
@@ -1137,11 +1183,11 @@ export default class Inibase {
|
|
|
1137
1183
|
}
|
|
1138
1184
|
let cacheKey = "";
|
|
1139
1185
|
// Criteria
|
|
1140
|
-
if (
|
|
1186
|
+
if (this.tables[tableName].config.cache)
|
|
1141
1187
|
cacheKey = UtilsServer.hashString(inspect(sortArray, { sorted: true }));
|
|
1142
1188
|
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);
|
|
1189
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
1190
|
+
keepItems = Object.values((await File.get(join(tablePath, `id${this.getFileExtension(tableName)}`), lineNumbers, "number", undefined, this.salt)) ?? {}).map(Number);
|
|
1145
1191
|
isLineNumbers = false;
|
|
1146
1192
|
if (!keepItems.length)
|
|
1147
1193
|
throw this.throwError("NO_RESULTS", tableName);
|
|
@@ -1151,7 +1197,7 @@ export default class Inibase {
|
|
|
1151
1197
|
keepItems = Array.from({ length: options.perPage }, (_, index) => (options.page - 1) * options.perPage +
|
|
1152
1198
|
index +
|
|
1153
1199
|
1);
|
|
1154
|
-
const filesPathes = [["id", true], ...sortArray].map((column) => join(tablePath, `${column[0]}${this.getFileExtension()}`));
|
|
1200
|
+
const filesPathes = [["id", true], ...sortArray].map((column) => join(tablePath, `${column[0]}${this.getFileExtension(tableName)}`));
|
|
1155
1201
|
// Construct the paste command to merge files and filter lines by IDs
|
|
1156
1202
|
const pasteCommand = `paste ${filesPathes.join(" ")}`;
|
|
1157
1203
|
// Construct the sort command dynamically based on the number of files for sorting
|
|
@@ -1176,19 +1222,20 @@ export default class Inibase {
|
|
|
1176
1222
|
await File.lock(join(tablePath, ".tmp"), cacheKey);
|
|
1177
1223
|
// Combine the commands
|
|
1178
1224
|
// Execute the command synchronously
|
|
1179
|
-
const
|
|
1225
|
+
const lines = (await UtilsServer.exec(this.tables[tableName].config.cache
|
|
1180
1226
|
? (await File.isExists(join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)))
|
|
1181
1227
|
? `${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
|
|
1182
1228
|
: `${pasteCommand} | ${sortCommand} -o ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)} && ${awkCommand} ${join(tablePath, ".cache", `${cacheKey}${this.fileExtension}`)}`
|
|
1183
1229
|
: `${pasteCommand} | ${sortCommand} | ${awkCommand}`, {
|
|
1184
1230
|
encoding: "utf-8",
|
|
1185
|
-
})
|
|
1231
|
+
})).stdout
|
|
1232
|
+
.trim()
|
|
1233
|
+
.split("\n");
|
|
1186
1234
|
// Parse the result and extract the specified lines
|
|
1187
|
-
const lines = stdout.trim().split("\n");
|
|
1188
1235
|
const outputArray = lines.map((line) => {
|
|
1189
1236
|
const splitedFileColumns = line.split("\t"); // Assuming tab-separated columns
|
|
1190
1237
|
const outputObject = {};
|
|
1191
|
-
// Extract values for each file, including `id${this.getFileExtension()}`
|
|
1238
|
+
// Extract values for each file, including `id${this.getFileExtension(tableName)}`
|
|
1192
1239
|
filesPathes.forEach((fileName, index) => {
|
|
1193
1240
|
const field = Utils.getField(parse(fileName).name, schema);
|
|
1194
1241
|
if (field)
|
|
@@ -1196,7 +1243,7 @@ export default class Inibase {
|
|
|
1196
1243
|
});
|
|
1197
1244
|
return outputObject;
|
|
1198
1245
|
});
|
|
1199
|
-
const restOfColumns = await this.get(tableName, outputArray.map(({ id }) => id), options, undefined, undefined,
|
|
1246
|
+
const restOfColumns = await this.get(tableName, outputArray.map(({ id }) => id), options, undefined, undefined, true);
|
|
1200
1247
|
return restOfColumns
|
|
1201
1248
|
? outputArray.map((item, index) => ({
|
|
1202
1249
|
...item,
|