@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.
- package/README.md +292 -612
- package/dist/database/IDatabase.d.ts +77 -0
- package/dist/database/IDatabase.js +10 -0
- package/dist/database/cacheWrapper.d.ts +31 -0
- package/dist/database/cacheWrapper.js +228 -0
- package/dist/database/index.d.ts +11 -0
- package/dist/database/index.js +94 -0
- package/dist/database/json.d.ts +32 -0
- package/dist/database/json.js +210 -0
- package/dist/database/migration.d.ts +21 -0
- package/dist/database/migration.js +97 -0
- package/dist/database/mongodb.d.ts +24 -0
- package/dist/database/mongodb.js +153 -0
- package/dist/database/mysql.d.ts +31 -0
- package/dist/database/mysql.js +385 -0
- package/dist/database/pg.d.ts +30 -0
- package/dist/database/pg.js +300 -0
- package/dist/database/redis.d.ts +23 -0
- package/dist/database/redis.js +157 -0
- package/dist/database/sqlite.d.ts +25 -0
- package/dist/database/sqlite.js +273 -0
- package/dist/database/types.d.ts +76 -0
- package/dist/database/types.js +2 -0
- package/dist/database/zpack.d.ts +59 -0
- package/dist/database/zpack.js +462 -0
- package/dist/functions/index.d.ts +183 -0
- package/dist/functions/index.js +636 -0
- package/dist/functions/temp_isphone.d.ts +1 -0
- package/dist/functions/temp_isphone.js +7 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +45 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +55 -0
- package/dist/test_zpack.d.ts +1 -0
- package/dist/test_zpack.js +64 -0
- package/package.json +23 -6
- package/database/IDatabase.js +0 -92
- package/database/cacheWrapper.js +0 -585
- package/database/index.js +0 -72
- package/database/json.js +0 -281
- package/database/migration.js +0 -227
- package/database/mongodb.js +0 -203
- package/database/mysql.js +0 -526
- package/database/pg.js +0 -527
- package/database/redis.js +0 -342
- package/database/sqlite.js +0 -551
- package/functions/index.js +0 -705
- 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;
|