@onurege3467/zerohelper 8.0.0 → 9.0.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.
Files changed (48) hide show
  1. package/README.md +292 -612
  2. package/dist/database/IDatabase.d.ts +77 -0
  3. package/dist/database/IDatabase.js +10 -0
  4. package/dist/database/cacheWrapper.d.ts +31 -0
  5. package/dist/database/cacheWrapper.js +228 -0
  6. package/dist/database/index.d.ts +11 -0
  7. package/dist/database/index.js +94 -0
  8. package/dist/database/json.d.ts +32 -0
  9. package/dist/database/json.js +210 -0
  10. package/dist/database/migration.d.ts +21 -0
  11. package/dist/database/migration.js +97 -0
  12. package/dist/database/mongodb.d.ts +24 -0
  13. package/dist/database/mongodb.js +153 -0
  14. package/dist/database/mysql.d.ts +31 -0
  15. package/dist/database/mysql.js +385 -0
  16. package/dist/database/pg.d.ts +30 -0
  17. package/dist/database/pg.js +300 -0
  18. package/dist/database/redis.d.ts +23 -0
  19. package/dist/database/redis.js +157 -0
  20. package/dist/database/sqlite.d.ts +25 -0
  21. package/dist/database/sqlite.js +273 -0
  22. package/dist/database/types.d.ts +76 -0
  23. package/dist/database/types.js +2 -0
  24. package/dist/database/zpack.d.ts +59 -0
  25. package/dist/database/zpack.js +462 -0
  26. package/dist/functions/index.d.ts +183 -0
  27. package/dist/functions/index.js +636 -0
  28. package/dist/functions/temp_isphone.d.ts +1 -0
  29. package/dist/functions/temp_isphone.js +7 -0
  30. package/dist/index.d.ts +8 -0
  31. package/dist/index.js +45 -0
  32. package/dist/test.d.ts +1 -0
  33. package/dist/test.js +55 -0
  34. package/dist/test_zpack.d.ts +1 -0
  35. package/dist/test_zpack.js +64 -0
  36. package/package.json +23 -6
  37. package/database/IDatabase.js +0 -92
  38. package/database/cacheWrapper.js +0 -585
  39. package/database/index.js +0 -72
  40. package/database/json.js +0 -281
  41. package/database/migration.js +0 -227
  42. package/database/mongodb.js +0 -203
  43. package/database/mysql.js +0 -526
  44. package/database/pg.js +0 -527
  45. package/database/redis.js +0 -342
  46. package/database/sqlite.js +0 -551
  47. package/functions/index.js +0 -705
  48. package/index.js +0 -7
package/database/pg.js DELETED
@@ -1,527 +0,0 @@
1
- const IDatabase = require('./IDatabase'); // Arayüzü import et
2
- const { Pool } = require('pg');
3
-
4
- /**
5
- * @implements {IDatabase}
6
- */
7
- class PostgreSQLDatabase extends IDatabase {
8
- constructor(config) {
9
- super();
10
- this.config = config;
11
- this.pool = null;
12
- this._queue = [];
13
- this._connected = false;
14
-
15
- this._connectionPromise = new Promise(async (resolve, reject) => {
16
- try {
17
- // First, connect to create database if not exists
18
- const tempPool = new Pool({
19
- host: config.host,
20
- port: config.port || 5432,
21
- user: config.user,
22
- password: config.password,
23
- database: 'postgres' // Connect to default database first
24
- });
25
-
26
- try {
27
- await tempPool.query(`CREATE DATABASE "${config.database}"`);
28
- } catch (error) {
29
- // Database might already exist, ignore error
30
- if (!error.message.includes('already exists')) {
31
- console.warn('Database creation warning:', error.message);
32
- }
33
- }
34
- await tempPool.end();
35
-
36
- // Now connect to the actual database
37
- this.pool = new Pool({
38
- host: config.host,
39
- port: config.port || 5432,
40
- user: config.user,
41
- password: config.password,
42
- database: config.database,
43
- max: config.connectionLimit || 10,
44
- idleTimeoutMillis: 30000,
45
- connectionTimeoutMillis: 2000,
46
- });
47
-
48
- this._connected = true;
49
- resolve(this.pool);
50
- this._processQueue(); // Process any queued requests
51
- } catch (error) {
52
- console.error("PostgreSQL connection error:", error);
53
- reject(error);
54
- }
55
- });
56
- }
57
-
58
- /**
59
- * Değerin türüne göre PostgreSQL column türünü otomatik belirler
60
- */
61
- _getColumnType(value) {
62
- if (value === null || value === undefined) {
63
- return 'TEXT'; // Null değerler için varsayılan
64
- }
65
-
66
- if (typeof value === 'boolean') {
67
- return 'BOOLEAN';
68
- }
69
-
70
- if (typeof value === 'number') {
71
- if (Number.isInteger(value)) {
72
- // Integer range kontrolü
73
- if (value >= -32768 && value <= 32767) {
74
- return 'SMALLINT';
75
- } else if (value >= -2147483648 && value <= 2147483647) {
76
- return 'INTEGER';
77
- } else {
78
- return 'BIGINT';
79
- }
80
- } else {
81
- // Float/Double için
82
- return 'DOUBLE PRECISION';
83
- }
84
- }
85
-
86
- if (typeof value === 'string') {
87
- const length = value.length;
88
- if (length <= 255) {
89
- return 'VARCHAR(255)';
90
- } else {
91
- return 'TEXT';
92
- }
93
- }
94
-
95
- if (typeof value === 'object') {
96
- // Array ve Object'ler JSONB olarak saklanır
97
- return 'JSONB';
98
- }
99
-
100
- if (value instanceof Date) {
101
- return 'TIMESTAMP';
102
- }
103
-
104
- // Varsayılan
105
- return 'TEXT';
106
- }
107
-
108
- /**
109
- * Birden fazla değere göre en uygun column türünü belirler
110
- */
111
- _getBestColumnType(values) {
112
- const types = values.map(val => this._getColumnType(val));
113
- const uniqueTypes = [...new Set(types)];
114
-
115
- // Eğer hepsi aynı türse, o türü kullan
116
- if (uniqueTypes.length === 1) {
117
- return uniqueTypes[0];
118
- }
119
-
120
- // Mixed türler için öncelik sırası
121
- const typePriority = {
122
- 'TEXT': 10,
123
- 'JSONB': 9,
124
- 'VARCHAR(255)': 8,
125
- 'TIMESTAMP': 7,
126
- 'DOUBLE PRECISION': 6,
127
- 'BIGINT': 5,
128
- 'INTEGER': 4,
129
- 'SMALLINT': 3,
130
- 'BOOLEAN': 2
131
- };
132
-
133
- // En yüksek öncelikli türü seç
134
- let bestType = uniqueTypes[0];
135
- let bestPriority = typePriority[bestType] || 0;
136
-
137
- for (const type of uniqueTypes) {
138
- const priority = typePriority[type] || 0;
139
- if (priority > bestPriority) {
140
- bestType = type;
141
- bestPriority = priority;
142
- }
143
- }
144
-
145
- return bestType;
146
- }
147
-
148
- /**
149
- * Eksik kolonları kontrol eder ve ekler
150
- */
151
- async _ensureMissingColumns(table, data) {
152
- const existingColumns = await this.query(`
153
- SELECT column_name
154
- FROM information_schema.columns
155
- WHERE table_name = $1 AND table_schema = 'public'
156
- `, [table]);
157
-
158
- if (!existingColumns || existingColumns.length === 0) {
159
- throw new Error(`Table ${table} does not exist.`);
160
- }
161
-
162
- const existingColumnNames = existingColumns.map(col => col.column_name);
163
-
164
- for (const key of Object.keys(data)) {
165
- if (!existingColumnNames.includes(key)) {
166
- const columnType = this._getColumnType(data[key]);
167
- const alterSQL = `ALTER TABLE "${table}" ADD COLUMN "${key}" ${columnType}`;
168
- await this.query(alterSQL);
169
- console.log(`Added missing column '${key}' to table '${table}' with type ${columnType}`);
170
- }
171
- }
172
- }
173
-
174
- async _queueRequest(operation) {
175
- if (this._connected) {
176
- return operation();
177
- } else {
178
- return new Promise((resolve, reject) => {
179
- this._queue.push({ operation, resolve, reject });
180
- });
181
- }
182
- }
183
-
184
- async _processQueue() {
185
- if (!this._connected) return;
186
-
187
- while (this._queue.length > 0) {
188
- const { operation, resolve, reject } = this._queue.shift();
189
- try {
190
- const result = await operation();
191
- resolve(result);
192
- } catch (error) {
193
- reject(error);
194
- }
195
- }
196
- }
197
-
198
- async query(sql, params = []) {
199
- return this._queueRequest(async () => {
200
- const pool = await this._connectionPromise;
201
- const result = await pool.query(sql, params);
202
- return result.rows;
203
- });
204
- }
205
-
206
- async ensureTable(table, data = {}) {
207
- return this._queueRequest(async () => {
208
- const tables = await this.query(`
209
- SELECT table_name
210
- FROM information_schema.tables
211
- WHERE table_schema = 'public' AND table_name = $1
212
- `, [table]);
213
-
214
- if (tables.length === 0) {
215
- const columnDefinitions = Object.keys(data).map(col => {
216
- const columnType = this._getColumnType(data[col]);
217
- return `"${col}" ${columnType}`;
218
- });
219
-
220
- let columnsPart = '';
221
- if (columnDefinitions.length > 0) {
222
- columnsPart = ', ' + columnDefinitions.join(", ");
223
- }
224
-
225
- const createTableSQL = `
226
- CREATE TABLE "${table}" (
227
- "_id" SERIAL PRIMARY KEY
228
- ${columnsPart}
229
- )
230
- `;
231
- await this.query(createTableSQL);
232
- }
233
- });
234
- }
235
-
236
- async insert(table, data) {
237
- return this._queueRequest(async () => {
238
- const copy = { ...data };
239
- await this.ensureTable(table, copy);
240
-
241
- // Eksik kolonları ekle
242
- await this._ensureMissingColumns(table, copy);
243
-
244
- const existingColumns = await this.query(`
245
- SELECT column_name, column_default, is_nullable, data_type
246
- FROM information_schema.columns
247
- WHERE table_name = $1 AND table_schema = 'public'
248
- `, [table]);
249
-
250
- const primaryKeyColumn = existingColumns.find(col =>
251
- col.column_default && col.column_default.includes('nextval')
252
- );
253
-
254
- const insertData = { ...copy };
255
- // Remove the auto-incrementing primary key from insertData if it's present
256
- if (primaryKeyColumn && insertData[primaryKeyColumn.column_name] !== undefined) {
257
- delete insertData[primaryKeyColumn.column_name];
258
- }
259
-
260
- const keys = Object.keys(insertData);
261
- const placeholders = keys.map((_, index) => `$${index + 1}`).join(",");
262
- const values = Object.values(insertData).map(value => this._serializeValue(value));
263
- const sql = `INSERT INTO "${table}" (${keys.map(k => `"${k}"`).join(",")}) VALUES (${placeholders}) RETURNING "_id"`;
264
-
265
- const result = await this.query(sql, values);
266
- return result[0]._id;
267
- });
268
- }
269
-
270
- async update(table, data, where) {
271
- return this._queueRequest(async () => {
272
- await this.ensureTable(table, { ...data, ...where });
273
-
274
- // Eksik kolonları ekle
275
- await this._ensureMissingColumns(table, { ...data, ...where });
276
-
277
- const setString = Object.keys(data).map((k, i) => `"${k}" = $${i + 1}`).join(", ");
278
- const whereString = Object.keys(where).map((k, i) => `"${k}" = $${Object.keys(data).length + i + 1}`).join(" AND ");
279
- const sql = `UPDATE "${table}" SET ${setString} WHERE ${whereString}`;
280
-
281
- const result = await this.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
282
- return result.length; // PostgreSQL doesn't return affectedRows in the same way
283
- });
284
- }
285
-
286
- async delete(table, where) {
287
- return this._queueRequest(async () => {
288
- if (!where || Object.keys(where).length === 0) return 0;
289
- await this.ensureTable(table, { ...where });
290
-
291
- // Eksik kolonları ekle (where koşulları için)
292
- await this._ensureMissingColumns(table, where);
293
-
294
- const whereString = Object.keys(where).map((k, i) => `"${k}" = $${i + 1}`).join(" AND ");
295
- const sql = `DELETE FROM "${table}" WHERE ${whereString}`;
296
- const result = await this.query(sql, Object.values(where).map(v => this._serializeValue(v)));
297
- return result.length;
298
- });
299
- }
300
-
301
- async select(table, where = null) {
302
- return this._queueRequest(async () => {
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
-
310
- let sql = `SELECT * FROM "${table}"`;
311
- let params = [];
312
-
313
- if (where && Object.keys(where).length > 0) {
314
- const whereString = Object.keys(where).map((k, i) => `"${k}" = $${i + 1}`).join(" AND ");
315
- sql += ` WHERE ${whereString}`;
316
- params = Object.values(where).map(v => this._serializeValue(v));
317
- }
318
-
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
- });
327
- });
328
- }
329
-
330
- async set(table, data, where) {
331
- return this._queueRequest(async () => {
332
- await this.ensureTable(table, { ...data, ...where });
333
-
334
- // Eksik kolonları ekle
335
- await this._ensureMissingColumns(table, { ...data, ...where });
336
-
337
- const existing = await this.select(table, where);
338
- if (existing.length === 0) {
339
- return await this.insert(table, { ...where, ...data });
340
- } else {
341
- return await this.update(table, data, where);
342
- }
343
- });
344
- }
345
-
346
- async selectOne(table, where = null) {
347
- return this._queueRequest(async () => {
348
- const results = await this.select(table, where);
349
- if (results[0]) {
350
- const newResult = {};
351
- for (const key in results[0]) {
352
- newResult[key] = this._deserializeValue(results[0][key]);
353
- }
354
- return newResult;
355
- }
356
- return null;
357
- });
358
- }
359
-
360
- async deleteOne(table, where) {
361
- return this._queueRequest(async () => {
362
- await this.ensureTable(table, where);
363
-
364
- // Eksik kolonları ekle (where koşulları için)
365
- await this._ensureMissingColumns(table, where);
366
-
367
- const row = await this.selectOne(table, where);
368
- if (!row) return 0;
369
-
370
- const whereString = Object.keys(where).map((k, i) => `"${k}" = $${i + 1}`).join(" AND ");
371
- const sql = `DELETE FROM "${table}" WHERE ${whereString} AND ctid = (SELECT ctid FROM "${table}" WHERE ${whereString} LIMIT 1)`;
372
- const result = await this.query(sql, [...Object.values(where).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
373
- return result.length;
374
- });
375
- }
376
-
377
- async updateOne(table, data, where) {
378
- return this._queueRequest(async () => {
379
- await this.ensureTable(table, { ...data, ...where });
380
-
381
- // Eksik kolonları ekle
382
- await this._ensureMissingColumns(table, { ...data, ...where });
383
-
384
- const setString = Object.keys(data).map((k, i) => `"${k}" = $${i + 1}`).join(", ");
385
- const whereString = Object.keys(where).map((k, i) => `"${k}" = $${Object.keys(data).length + i + 1}`).join(" AND ");
386
- const sql = `UPDATE "${table}" SET ${setString} WHERE ${whereString} AND ctid = (SELECT ctid FROM "${table}" WHERE ${whereString} LIMIT 1)`;
387
-
388
- const result = await this.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
389
- return result.length;
390
- });
391
- }
392
-
393
- async bulkInsert(table, dataArray) {
394
- return this._queueRequest(async () => {
395
- if (!Array.isArray(dataArray) || dataArray.length === 0) return 0;
396
- await this.ensureTable(table, dataArray[0]);
397
-
398
- const existingColumns = await this.query(`
399
- SELECT column_name
400
- FROM information_schema.columns
401
- WHERE table_name = $1 AND table_schema = 'public'
402
- `, [table]);
403
-
404
- const existingColumnNames = existingColumns.map(col => col.column_name);
405
-
406
- // Tüm datalardan gelen tüm anahtarları topla
407
- const allKeys = new Set();
408
- dataArray.forEach(obj => {
409
- Object.keys(obj).forEach(key => allKeys.add(key));
410
- });
411
-
412
- // Eksik kolonları kontrol et ve ekle
413
- for (const key of allKeys) {
414
- if (!existingColumnNames.includes(key)) {
415
- // Tüm değerleri kontrol ederek en uygun türü belirle
416
- const columnValues = dataArray
417
- .map(obj => obj[key])
418
- .filter(val => val !== undefined && val !== null);
419
- const columnType = columnValues.length > 0 ? this._getBestColumnType(columnValues) : 'TEXT';
420
- await this.query(`ALTER TABLE "${table}" ADD COLUMN "${key}" ${columnType}`);
421
- console.log(`Added missing column '${key}' to table '${table}' with type ${columnType}`);
422
- }
423
- }
424
-
425
- const keys = Array.from(allKeys);
426
-
427
- // PostgreSQL için VALUES clause oluştur
428
- const placeholders = dataArray.map((_, rowIndex) =>
429
- `(${keys.map((_, colIndex) => `$${rowIndex * keys.length + colIndex + 1}`).join(',')})`
430
- ).join(',');
431
-
432
- const values = dataArray.flatMap(obj => keys.map(k => this._serializeValue(obj[k])));
433
- const sql = `INSERT INTO "${table}" (${keys.map(k => `"${k}"`).join(",")}) VALUES ${placeholders}`;
434
-
435
- const result = await this.query(sql, values);
436
- return result.length;
437
- });
438
- }
439
-
440
- async close() {
441
- if (this.pool) await this.pool.end();
442
- }
443
-
444
- // Helper to serialize values for storage
445
- _serializeValue(value) {
446
- if (value instanceof Date) {
447
- return value.toISOString(); // PostgreSQL TIMESTAMP format
448
- }
449
- if (Array.isArray(value) || (typeof value === 'object' && value !== null)) {
450
- return JSON.stringify(value); // PostgreSQL will handle JSONB conversion
451
- }
452
- return value;
453
- }
454
-
455
- // Helper to deserialize values after retrieval
456
- _deserializeValue(value) {
457
- // PostgreSQL JSONB columns are automatically parsed by pg driver
458
- // No need for manual JSON parsing unlike MySQL
459
- return value;
460
- }
461
-
462
- /**
463
- * WHERE clause oluşturur (PostgreSQL $n syntax için)
464
- * @param {object} where - WHERE koşulları
465
- * @param {number} startIndex - Başlangıç parameter indeksi
466
- * @returns {object} - whereClause string ve values array
467
- */
468
- buildWhereClause(where = {}, startIndex = 0) {
469
- const conditions = Object.keys(where);
470
- if (conditions.length === 0) {
471
- return { whereClause: '', values: [] };
472
- }
473
-
474
- const whereClause = ' WHERE ' + conditions.map((key, index) =>
475
- `${key} = $${startIndex + index + 1}`
476
- ).join(' AND ');
477
- const values = Object.values(where).map(v => this._serializeValue(v));
478
-
479
- return { whereClause, values };
480
- }
481
-
482
- /**
483
- * Numerik alanları artırır (increment).
484
- * @param {string} table - Verinin güncelleneceği tablo adı.
485
- * @param {object} increments - Artırılacak alanlar ve miktarları.
486
- * @param {object} where - Güncelleme koşulları.
487
- * @returns {Promise<number>} Etkilenen kayıt sayısı.
488
- */
489
- async increment(table, increments, where = {}) {
490
- const incrementClauses = Object.keys(increments).map((field, index) =>
491
- `${field} = ${field} + $${index + 1}`
492
- ).join(', ');
493
-
494
- const incrementValues = Object.values(increments);
495
- const { whereClause, values: whereValues } = this.buildWhereClause(where, incrementValues.length);
496
-
497
- const sql = `UPDATE ${table} SET ${incrementClauses}${whereClause}`;
498
- const allValues = [...incrementValues, ...whereValues];
499
-
500
- const result = await this.pool.query(sql, allValues);
501
- return result.rowCount;
502
- }
503
-
504
- /**
505
- * Numerik alanları azaltır (decrement).
506
- * @param {string} table - Verinin güncelleneceği tablo adı.
507
- * @param {object} decrements - Azaltılacak alanlar ve miktarları.
508
- * @param {object} where - Güncelleme koşulları.
509
- * @returns {Promise<number>} Etkilenen kayıt sayısı.
510
- */
511
- async decrement(table, decrements, where = {}) {
512
- const decrementClauses = Object.keys(decrements).map((field, index) =>
513
- `${field} = ${field} - $${index + 1}`
514
- ).join(', ');
515
-
516
- const decrementValues = Object.values(decrements);
517
- const { whereClause, values: whereValues } = this.buildWhereClause(where, decrementValues.length);
518
-
519
- const sql = `UPDATE ${table} SET ${decrementClauses}${whereClause}`;
520
- const allValues = [...decrementValues, ...whereValues];
521
-
522
- const result = await this.pool.query(sql, allValues);
523
- return result.rowCount;
524
- }
525
- }
526
-
527
- module.exports = PostgreSQLDatabase;