@onurege3467/zerohelper 7.0.0 → 7.2.0
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/database/cacheWrapper.js +168 -55
- package/database/index.js +5 -2
- package/database/mysql.js +67 -54
- package/database/pg.js +67 -77
- package/database/redis.js +162 -0
- package/database/sqlite.js +159 -31
- package/package.json +4 -6
- package/readme.md +35 -0
- package/data/test_db.json +0 -3
- package/data/test_db.sqlite +0 -0
- package/data/test_db_cached.sqlite +0 -0
- package/test copy.js +0 -144
- package/test.js +0 -261
package/database/sqlite.js
CHANGED
|
@@ -92,6 +92,11 @@ class SQLiteDatabase extends IDatabase{
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
// Object ve Array kontrolü
|
|
96
|
+
if (typeof value === 'object') {
|
|
97
|
+
return 'TEXT'; // SQLite'da JSON olarak string halinde saklanacak
|
|
98
|
+
}
|
|
99
|
+
|
|
95
100
|
// Varsayılan olarak TEXT
|
|
96
101
|
return 'TEXT';
|
|
97
102
|
}
|
|
@@ -120,6 +125,24 @@ class SQLiteDatabase extends IDatabase{
|
|
|
120
125
|
return bestType || 'TEXT';
|
|
121
126
|
}
|
|
122
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Eksik kolonları kontrol eder ve ekler
|
|
130
|
+
* @param {string} table - Tablo adı
|
|
131
|
+
* @param {object} data - Kontrol edilecek veri
|
|
132
|
+
*/
|
|
133
|
+
async _ensureMissingColumns(table, data) {
|
|
134
|
+
const columnsInfo = await this.query(`PRAGMA table_info(\`${table}\`)`);
|
|
135
|
+
const existingNames = columnsInfo.map(col => col.name);
|
|
136
|
+
|
|
137
|
+
for (const key of Object.keys(data)) {
|
|
138
|
+
if (!existingNames.includes(key)) {
|
|
139
|
+
const columnType = this._detectColumnType(data[key]);
|
|
140
|
+
await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`);
|
|
141
|
+
console.log(`Added missing column '${key}' to table '${table}' with type ${columnType}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
123
146
|
/**
|
|
124
147
|
* SQL sorgusu çalıştırır. Promise döndürür.
|
|
125
148
|
* @param {string} sql - Çalıştırılacak SQL sorgusu.
|
|
@@ -179,17 +202,43 @@ class SQLiteDatabase extends IDatabase{
|
|
|
179
202
|
/**
|
|
180
203
|
* Verilen verideki anahtarların tabloda sütun olarak var olduğundan emin olur.
|
|
181
204
|
* @private
|
|
205
|
+
* @deprecated Bu fonksiyon yerine _ensureMissingColumns kullanılıyor
|
|
182
206
|
*/
|
|
183
207
|
async _ensureColumns(table, data) {
|
|
184
|
-
|
|
185
|
-
|
|
208
|
+
return this._ensureMissingColumns(table, data);
|
|
209
|
+
}
|
|
186
210
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
211
|
+
/**
|
|
212
|
+
* Değeri serileştir (JSON objeler için)
|
|
213
|
+
*/
|
|
214
|
+
_serializeValue(value) {
|
|
215
|
+
if (value instanceof Date) {
|
|
216
|
+
return value.toISOString();
|
|
217
|
+
}
|
|
218
|
+
if (Array.isArray(value) || (typeof value === 'object' && value !== null)) {
|
|
219
|
+
return JSON.stringify(value);
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Değeri deserileştir (JSON objeler için)
|
|
226
|
+
*/
|
|
227
|
+
_deserializeValue(value) {
|
|
228
|
+
if (typeof value === 'string') {
|
|
229
|
+
try {
|
|
230
|
+
// JSON string olup olmadığını kontrol et
|
|
231
|
+
if (value.startsWith('[') || value.startsWith('{')) {
|
|
232
|
+
const parsed = JSON.parse(value);
|
|
233
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
234
|
+
return parsed;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
// JSON parse hatası, orijinal değeri döndür
|
|
191
239
|
}
|
|
192
240
|
}
|
|
241
|
+
return value;
|
|
193
242
|
}
|
|
194
243
|
|
|
195
244
|
/**
|
|
@@ -199,11 +248,13 @@ class SQLiteDatabase extends IDatabase{
|
|
|
199
248
|
async insert(table, data) {
|
|
200
249
|
const copy = { ...data };
|
|
201
250
|
await this.ensureTable(table, copy);
|
|
202
|
-
|
|
251
|
+
|
|
252
|
+
// Eksik kolonları ekle
|
|
253
|
+
await this._ensureMissingColumns(table, copy);
|
|
203
254
|
|
|
204
255
|
const keys = Object.keys(copy);
|
|
205
256
|
const placeholders = keys.map(() => '?').join(',');
|
|
206
|
-
const values = Object.values(copy);
|
|
257
|
+
const values = Object.values(copy).map(v => this._serializeValue(v));
|
|
207
258
|
const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(',')}) VALUES (${placeholders})`;
|
|
208
259
|
|
|
209
260
|
const result = await this.query(sql, values);
|
|
@@ -216,12 +267,14 @@ class SQLiteDatabase extends IDatabase{
|
|
|
216
267
|
*/
|
|
217
268
|
async update(table, data, where) {
|
|
218
269
|
await this.ensureTable(table, { ...data, ...where });
|
|
219
|
-
|
|
270
|
+
|
|
271
|
+
// Eksik kolonları ekle
|
|
272
|
+
await this._ensureMissingColumns(table, { ...data, ...where });
|
|
220
273
|
|
|
221
274
|
const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(', ');
|
|
222
275
|
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
223
276
|
const sql = `UPDATE \`${table}\` SET ${setString} WHERE ${whereString}`;
|
|
224
|
-
const result = await this.query(sql, [...Object.values(data), ...Object.values(where)]);
|
|
277
|
+
const result = await this.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
|
|
225
278
|
return result.changes;
|
|
226
279
|
}
|
|
227
280
|
|
|
@@ -232,9 +285,13 @@ class SQLiteDatabase extends IDatabase{
|
|
|
232
285
|
async delete(table, where) {
|
|
233
286
|
if (!where || Object.keys(where).length === 0) return 0;
|
|
234
287
|
await this.ensureTable(table, { ...where });
|
|
288
|
+
|
|
289
|
+
// Eksik kolonları ekle (where koşulları için)
|
|
290
|
+
await this._ensureMissingColumns(table, where);
|
|
291
|
+
|
|
235
292
|
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
236
293
|
const sql = `DELETE FROM \`${table}\` WHERE ${whereString}`;
|
|
237
|
-
const result = await this.query(sql, Object.values(where));
|
|
294
|
+
const result = await this.query(sql, Object.values(where).map(v => this._serializeValue(v)));
|
|
238
295
|
return result.changes;
|
|
239
296
|
}
|
|
240
297
|
|
|
@@ -244,16 +301,29 @@ class SQLiteDatabase extends IDatabase{
|
|
|
244
301
|
*/
|
|
245
302
|
async select(table, where = null) {
|
|
246
303
|
await this.ensureTable(table, where || {});
|
|
304
|
+
|
|
305
|
+
// Eğer where koşulu varsa, eksik kolonları ekle
|
|
306
|
+
if (where && Object.keys(where).length > 0) {
|
|
307
|
+
await this._ensureMissingColumns(table, where);
|
|
308
|
+
}
|
|
309
|
+
|
|
247
310
|
let sql = `SELECT * FROM \`${table}\``;
|
|
248
311
|
let params = [];
|
|
249
312
|
|
|
250
313
|
if (where && Object.keys(where).length > 0) {
|
|
251
314
|
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
252
315
|
sql += ` WHERE ${whereString}`;
|
|
253
|
-
params = Object.values(where);
|
|
316
|
+
params = Object.values(where).map(v => this._serializeValue(v));
|
|
254
317
|
}
|
|
255
318
|
|
|
256
|
-
|
|
319
|
+
const rows = await this.query(sql, params);
|
|
320
|
+
return rows.map(row => {
|
|
321
|
+
const newRow = {};
|
|
322
|
+
for (const key in row) {
|
|
323
|
+
newRow[key] = this._deserializeValue(row[key]);
|
|
324
|
+
}
|
|
325
|
+
return newRow;
|
|
326
|
+
});
|
|
257
327
|
}
|
|
258
328
|
|
|
259
329
|
/**
|
|
@@ -261,7 +331,10 @@ class SQLiteDatabase extends IDatabase{
|
|
|
261
331
|
*/
|
|
262
332
|
async set(table, data, where) {
|
|
263
333
|
await this.ensureTable(table, { ...data, ...where });
|
|
264
|
-
|
|
334
|
+
|
|
335
|
+
// Eksik kolonları ekle
|
|
336
|
+
await this._ensureMissingColumns(table, { ...data, ...where });
|
|
337
|
+
|
|
265
338
|
const existing = await this.select(table, where);
|
|
266
339
|
if (existing.length === 0) {
|
|
267
340
|
return await this.insert(table, { ...where, ...data });
|
|
@@ -286,9 +359,13 @@ class SQLiteDatabase extends IDatabase{
|
|
|
286
359
|
async deleteOne(table, where) {
|
|
287
360
|
if (!where || Object.keys(where).length === 0) return 0;
|
|
288
361
|
await this.ensureTable(table, where);
|
|
362
|
+
|
|
363
|
+
// Eksik kolonları ekle (where koşulları için)
|
|
364
|
+
await this._ensureMissingColumns(table, where);
|
|
365
|
+
|
|
289
366
|
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
290
367
|
const sql = `DELETE FROM \`${table}\` WHERE rowid IN (SELECT rowid FROM \`${table}\` WHERE ${whereString} LIMIT 1)`;
|
|
291
|
-
const result = await this.query(sql, Object.values(where));
|
|
368
|
+
const result = await this.query(sql, Object.values(where).map(v => this._serializeValue(v)));
|
|
292
369
|
return result.changes;
|
|
293
370
|
}
|
|
294
371
|
|
|
@@ -298,11 +375,14 @@ class SQLiteDatabase extends IDatabase{
|
|
|
298
375
|
*/
|
|
299
376
|
async updateOne(table, data, where) {
|
|
300
377
|
await this.ensureTable(table, { ...data, ...where });
|
|
301
|
-
|
|
378
|
+
|
|
379
|
+
// Eksik kolonları ekle
|
|
380
|
+
await this._ensureMissingColumns(table, { ...data, ...where });
|
|
381
|
+
|
|
302
382
|
const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(', ');
|
|
303
383
|
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
304
384
|
const sql = `UPDATE \`${table}\` SET ${setString} WHERE rowid IN (SELECT rowid FROM \`${table}\` WHERE ${whereString} LIMIT 1)`;
|
|
305
|
-
const result = await this.query(sql, [...Object.values(data), ...Object.values(where)]);
|
|
385
|
+
const result = await this.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
|
|
306
386
|
return result.changes;
|
|
307
387
|
}
|
|
308
388
|
|
|
@@ -316,26 +396,74 @@ class SQLiteDatabase extends IDatabase{
|
|
|
316
396
|
// İlk elemanı tablo oluşturmak için kullan
|
|
317
397
|
await this.ensureTable(table, dataArray[0]);
|
|
318
398
|
|
|
319
|
-
// Tüm
|
|
320
|
-
|
|
321
|
-
|
|
399
|
+
// Tüm datalardan gelen tüm anahtarları topla
|
|
400
|
+
const allKeys = new Set();
|
|
401
|
+
dataArray.forEach(obj => {
|
|
402
|
+
Object.keys(obj).forEach(key => allKeys.add(key));
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// Tüm eksik kolonları ekle
|
|
406
|
+
for (const key of allKeys) {
|
|
407
|
+
const columnsInfo = await this.query(`PRAGMA table_info(\`${table}\`)`);
|
|
408
|
+
const existingNames = columnsInfo.map(col => col.name);
|
|
409
|
+
|
|
410
|
+
if (!existingNames.includes(key)) {
|
|
411
|
+
// Tüm değerleri kontrol ederek en uygun türü belirle
|
|
412
|
+
const columnValues = dataArray
|
|
413
|
+
.map(obj => obj[key])
|
|
414
|
+
.filter(val => val !== undefined && val !== null);
|
|
415
|
+
const columnType = columnValues.length > 0 ? this._determineBestColumnType(columnValues) : 'TEXT';
|
|
416
|
+
await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` ${columnType}`);
|
|
417
|
+
console.log(`Added missing column '${key}' to table '${table}' with type ${columnType}`);
|
|
418
|
+
}
|
|
322
419
|
}
|
|
323
420
|
|
|
324
|
-
const keys =
|
|
421
|
+
const keys = Array.from(allKeys);
|
|
325
422
|
const placeholders = keys.map(() => '?').join(',');
|
|
326
423
|
const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(',')}) VALUES (${placeholders})`;
|
|
327
424
|
|
|
328
|
-
// sqlite3'te toplu ekleme için transaction
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
425
|
+
// sqlite3'te toplu ekleme için transaction kullan
|
|
426
|
+
return new Promise((resolve, reject) => {
|
|
427
|
+
const stmt = this.db.prepare(sql, (err) => {
|
|
428
|
+
if (err) {
|
|
429
|
+
reject(err);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
this.db.serialize(() => {
|
|
435
|
+
this.db.run("BEGIN TRANSACTION;");
|
|
436
|
+
|
|
437
|
+
let completed = 0;
|
|
438
|
+
let hasError = false;
|
|
439
|
+
|
|
440
|
+
for (const item of dataArray) {
|
|
441
|
+
if (hasError) break;
|
|
442
|
+
|
|
443
|
+
const values = keys.map(k => this._serializeValue(item[k]));
|
|
444
|
+
stmt.run(values, (err) => {
|
|
445
|
+
if (err && !hasError) {
|
|
446
|
+
hasError = true;
|
|
447
|
+
this.db.run("ROLLBACK;");
|
|
448
|
+
reject(err);
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
completed++;
|
|
453
|
+
if (completed === dataArray.length && !hasError) {
|
|
454
|
+
this.db.run("COMMIT;", (err) => {
|
|
455
|
+
if (err) {
|
|
456
|
+
reject(err);
|
|
457
|
+
} else {
|
|
458
|
+
stmt.finalize();
|
|
459
|
+
resolve(dataArray.length);
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
});
|
|
336
466
|
});
|
|
337
|
-
|
|
338
|
-
return dataArray.length;
|
|
339
467
|
}
|
|
340
468
|
|
|
341
469
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onurege3467/zerohelper",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node test.js"
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
"sqlite3",
|
|
17
17
|
"quick.db",
|
|
18
18
|
"postgresql",
|
|
19
|
-
"redis",
|
|
20
19
|
"utility",
|
|
21
20
|
"functions",
|
|
22
21
|
"nodejs"
|
|
@@ -26,7 +25,6 @@
|
|
|
26
25
|
"description": "ZeroHelper is a versatile JavaScript library offering helper functions and database utilities for developers. It supports MongoDB, MySQL, SQLite, Redis, and PostgreSQL.",
|
|
27
26
|
"dependencies": {
|
|
28
27
|
"bcrypt": "^5.1.1",
|
|
29
|
-
|
|
30
28
|
"crypto": "^1.0.1",
|
|
31
29
|
"csv": "^6.3.11",
|
|
32
30
|
"dotenv": "^16.4.7",
|
|
@@ -34,13 +32,13 @@
|
|
|
34
32
|
"js-yaml": "^4.1.0",
|
|
35
33
|
"jsonwebtoken": "^9.0.2",
|
|
36
34
|
"lodash": "^4.17.21",
|
|
35
|
+
"lru-cache": "^10.0.0",
|
|
37
36
|
"mongodb": "^6.12.0",
|
|
38
37
|
"mysql2": "^3.14.1",
|
|
39
38
|
"path": "^0.12.7",
|
|
40
39
|
"pg": "^8.14.1",
|
|
41
40
|
"promise-mysql": "^5.2.0",
|
|
42
|
-
"redis": "^
|
|
43
|
-
"sqlite3": "^5.1.7"
|
|
44
|
-
"lru-cache": "^10.0.0"
|
|
41
|
+
"redis": "^5.8.2",
|
|
42
|
+
"sqlite3": "^5.1.7"
|
|
45
43
|
}
|
|
46
44
|
}
|
package/readme.md
CHANGED
|
@@ -187,6 +187,7 @@ const cachedSqliteDb = createDatabase({
|
|
|
187
187
|
config: {
|
|
188
188
|
filePath: path.join(__dirname, 'data', 'cached_development.sqlite'),
|
|
189
189
|
cache: {
|
|
190
|
+
type:'memory'
|
|
190
191
|
max: 1000, // Cache up to 1000 items
|
|
191
192
|
ttl: 1000 * 60 * 10, // Cache items for 10 minutes
|
|
192
193
|
updateAgeOnGet: true // Refresh TTL on access
|
|
@@ -196,6 +197,29 @@ const cachedSqliteDb = createDatabase({
|
|
|
196
197
|
|
|
197
198
|
// Subsequent `select` or `selectOne` calls for the same query will hit the cache
|
|
198
199
|
// Write operations (insert, update, delete, set, bulkInsert) will automatically invalidate the cache for the affected table.
|
|
200
|
+
|
|
201
|
+
const postgresWithRedisCache = createDatabase({
|
|
202
|
+
adapter: 'postgres',
|
|
203
|
+
config: {
|
|
204
|
+
host: 'localhost',
|
|
205
|
+
user: 'postgres',
|
|
206
|
+
password: 'password',
|
|
207
|
+
database: 'myapp',
|
|
208
|
+
cache: {
|
|
209
|
+
type: 'redis',
|
|
210
|
+
host: 'localhost',
|
|
211
|
+
port: 6379,
|
|
212
|
+
password: 'redis_password',
|
|
213
|
+
db: 0,
|
|
214
|
+
ttl: 600, //seconds
|
|
215
|
+
keyPrefix: 'myapp_cache:',
|
|
216
|
+
redis: {
|
|
217
|
+
connectTimeout: 10000,
|
|
218
|
+
lazyConnect: true
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
});
|
|
199
223
|
```
|
|
200
224
|
|
|
201
225
|
**Basic Usage (without cache configuration shown):**
|
|
@@ -250,6 +274,17 @@ const mongoDb = createDatabase({
|
|
|
250
274
|
database: 'my_app_prod'
|
|
251
275
|
}
|
|
252
276
|
});
|
|
277
|
+
// --- Using Redis ---
|
|
278
|
+
const redisDatabase = createDatabase({
|
|
279
|
+
adapter: 'redis',
|
|
280
|
+
config: {
|
|
281
|
+
host: 'localhost',
|
|
282
|
+
port: 6379,
|
|
283
|
+
password: 'redis_password',
|
|
284
|
+
db: 1,
|
|
285
|
+
keyPrefix: 'myapp_data:'
|
|
286
|
+
}
|
|
287
|
+
});
|
|
253
288
|
```
|
|
254
289
|
|
|
255
290
|
### Basic Operations (CRUD)
|
package/data/test_db.json
DELETED
package/data/test_db.sqlite
DELETED
|
Binary file
|
|
Binary file
|
package/test copy.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const createDatabase = require('./database');
|
|
3
|
-
const helpers = require('./functions');
|
|
4
|
-
const { setInterval } = require('timers');
|
|
5
|
-
|
|
6
|
-
const mysqlConfig = {
|
|
7
|
-
adapter: 'mysql',
|
|
8
|
-
config: {
|
|
9
|
-
host: process.env.MYSQL_HOST || 'localhost',
|
|
10
|
-
user: process.env.MYSQL_USER || 'root',
|
|
11
|
-
password: process.env.MYSQL_PASSWORD || '',
|
|
12
|
-
database: process.env.MYSQL_DATABASE || 'test_db_zerohelper',
|
|
13
|
-
cache: {
|
|
14
|
-
max: 100,
|
|
15
|
-
ttl: 1000 * 10,
|
|
16
|
-
updateAgeOnGet: true,
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
// Absurd configurations for testing edge cases
|
|
21
|
-
async function runDatabaseTests() {
|
|
22
|
-
console.log('Starting database tests...');
|
|
23
|
-
|
|
24
|
-
const databases = [
|
|
25
|
-
{ name: 'MySQL', config: mysqlConfig },
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
for (const dbInfo of databases) {
|
|
29
|
-
const { name, config } = dbInfo;
|
|
30
|
-
console.log(`\n--- Testing ${name} Database ---`);
|
|
31
|
-
let db;
|
|
32
|
-
try {
|
|
33
|
-
db = createDatabase(config);
|
|
34
|
-
console.log(`${name} database connected.`);
|
|
35
|
-
|
|
36
|
-
// Test Insert
|
|
37
|
-
const insertResult = await db.insert('users', { name: 'Test User', email: `test_${name.toLowerCase()}@example.com`, int_age: 30, bool_active: true,city: 'Test City' });
|
|
38
|
-
console.log(`${name} Insert:`, insertResult);
|
|
39
|
-
const selectResult = await db.selectOne('users', { _id: insertResult});
|
|
40
|
-
console.log(`${name} Select One:`, selectResult);
|
|
41
|
-
await db.set('users', {city:'Amkara'}, {_id: insertResult });
|
|
42
|
-
|
|
43
|
-
setInterval(async () => {
|
|
44
|
-
const updatedSelectResult = await db.selectOne('users', { _id: insertResult });
|
|
45
|
-
console.log(`${name} Select One after update:`, updatedSelectResult);
|
|
46
|
-
}, 1000);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} catch (error) {
|
|
51
|
-
console.error(`Error testing ${name} database:`, error);
|
|
52
|
-
} finally {
|
|
53
|
-
if (db) {
|
|
54
|
-
try {
|
|
55
|
-
} catch (closeError) {
|
|
56
|
-
console.error(`Error closing ${name} database connection:`, closeError);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
console.log('\nAll database tests completed.');
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
function runHelperFunctionTests() {
|
|
66
|
-
console.log('\nStarting helper function tests...');
|
|
67
|
-
|
|
68
|
-
// Random Functions
|
|
69
|
-
console.log('\n--- Testing Random Functions ---');
|
|
70
|
-
console.log('makeUniqueId:', helpers.random.makeUniqueId());
|
|
71
|
-
console.log('randomArray:', helpers.random.randomArray([1, 2, 3]));
|
|
72
|
-
console.log('randomText (5 chars):', helpers.random.randomText(5));
|
|
73
|
-
console.log('randomNumber (1-10):', helpers.random.randomNumber(1, 10));
|
|
74
|
-
console.log('randomEmoji:', helpers.random.randomEmoji());
|
|
75
|
-
console.log('randomHex:', helpers.random.randomHex());
|
|
76
|
-
console.log('randomFloat (1.0-2.0):', helpers.random.randomFloat(1.0, 2.0));
|
|
77
|
-
|
|
78
|
-
// String Functions
|
|
79
|
-
console.log('\n--- Testing String Functions ---');
|
|
80
|
-
console.log('titleCase:', helpers.string.titleCase('hello world'));
|
|
81
|
-
console.log('generateRandomString (8 chars):', helpers.string.generateRandomString(8));
|
|
82
|
-
|
|
83
|
-
// Array Functions
|
|
84
|
-
console.log('\n--- Testing Array Functions ---');
|
|
85
|
-
console.log('shuffleArray:', helpers.array.shuffleArray([1, 2, 3, 4, 5]));
|
|
86
|
-
console.log('flattenArray:', helpers.array.flattenArray([1, [2, [3]], 4]));
|
|
87
|
-
console.log('removeFalsyValues:', helpers.array.removeFalsyValues([0, 1, false, '', null, undefined, 2]));
|
|
88
|
-
const groupByData = [
|
|
89
|
-
{ type: 'A', value: 1 },
|
|
90
|
-
{ type: 'B', value: 2 },
|
|
91
|
-
{ type: 'A', value: 3 },
|
|
92
|
-
];
|
|
93
|
-
console.log('groupBy:', helpers.array.groupBy(groupByData, 'type'));
|
|
94
|
-
const pluckData = [
|
|
95
|
-
{ name: 'Alice', age: 30 },
|
|
96
|
-
{ name: 'Bob', age: 24 },
|
|
97
|
-
];
|
|
98
|
-
console.log('pluck (name):', helpers.array.pluck(pluckData, 'name'));
|
|
99
|
-
const sortByData = [
|
|
100
|
-
{ age: 30 },
|
|
101
|
-
{ age: 20 },
|
|
102
|
-
{ age: 40 },
|
|
103
|
-
];
|
|
104
|
-
console.log('sortBy (age):', helpers.array.sortBy(sortByData, 'age'));
|
|
105
|
-
|
|
106
|
-
// Object Functions
|
|
107
|
-
console.log('\n--- Testing Object Functions ---');
|
|
108
|
-
const filterObjectData = { a: 1, b: 2, c: 3 };
|
|
109
|
-
console.log('filterObjectByKey:', helpers.object.filterObjectByKey(filterObjectData, ['a', 'c']));
|
|
110
|
-
const deepMergeData1 = { a: 1, b: { c: 2 } };
|
|
111
|
-
const deepMergeData2 = { b: { d: 3 }, e: 4 };
|
|
112
|
-
console.log('deepMerge:', helpers.object.deepMerge(deepMergeData1, deepMergeData2));
|
|
113
|
-
|
|
114
|
-
// Crypto Functions
|
|
115
|
-
console.log('\n--- Testing Crypto Functions ---');
|
|
116
|
-
const secret = 'mySuperSecretKey';
|
|
117
|
-
const textToEncrypt = 'Hello Crypto!';
|
|
118
|
-
const encryptedResult = helpers.crypto.encryptText(textToEncrypt, secret);
|
|
119
|
-
const encryptedText = encryptedResult.encryptedText;
|
|
120
|
-
const iv = encryptedResult.iv;
|
|
121
|
-
console.log('encryptText:', encryptedText);
|
|
122
|
-
console.log('decryptText:', helpers.crypto.decryptText(encryptedText, secret, iv));
|
|
123
|
-
const password = 'mySecurePassword';
|
|
124
|
-
const hashedPassword = helpers.crypto.hashPassword(password);
|
|
125
|
-
console.log('hashPassword:', hashedPassword);
|
|
126
|
-
console.log('verifyPassword (true):', helpers.crypto.verifyPassword(password, hashedPassword));
|
|
127
|
-
console.log('verifyPassword (false):', helpers.crypto.verifyPassword('wrongPassword', hashedPassword));
|
|
128
|
-
const jwtPayload = { userId: 123, username: 'testuser' };
|
|
129
|
-
const jwtToken = helpers.crypto.generateJWT(jwtPayload, secret);
|
|
130
|
-
console.log('generateJWT:', jwtToken);
|
|
131
|
-
console.log('verifyJWT:', helpers.crypto.verifyJWT(jwtToken, secret));
|
|
132
|
-
|
|
133
|
-
// Math Functions
|
|
134
|
-
console.log('\n--- Testing Math Functions ---');
|
|
135
|
-
console.log('mean:', helpers.math.mean([1, 2, 3, 4, 5]));
|
|
136
|
-
console.log('isPrime (7):', helpers.math.isPrime(7));
|
|
137
|
-
console.log('isPrime (10):', helpers.math.isPrime(10));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async function main() {
|
|
141
|
-
await runDatabaseTests();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
main();
|