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