@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/sqlite.js
DELETED
|
@@ -1,551 +0,0 @@
|
|
|
1
|
-
const IDatabase = require('./IDatabase'); // Arayüzü import et
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @implements {IDatabase}
|
|
5
|
-
*/
|
|
6
|
-
const sqlite3 = require('sqlite3').verbose();
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
|
|
10
|
-
class SQLiteDatabase extends IDatabase{
|
|
11
|
-
/**
|
|
12
|
-
* @param {object} config - Yapılandırma nesnesi.
|
|
13
|
-
* @param {string} config.filePath - SQLite veritabanı dosyasının yolu.
|
|
14
|
-
*/
|
|
15
|
-
constructor(config) {
|
|
16
|
-
super()
|
|
17
|
-
if (!config || !config.filePath) {
|
|
18
|
-
throw new Error('SQLite yapılandırması için "filePath" gereklidir.');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Veritabanı dosyasının bulunacağı klasörün var olduğundan emin ol
|
|
22
|
-
const dir = path.dirname(config.filePath);
|
|
23
|
-
if (!fs.existsSync(dir)) {
|
|
24
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
this.db = new sqlite3.Database(config.filePath, (err) => {
|
|
28
|
-
if (err) {
|
|
29
|
-
console.error("SQLite connection error:", err.message);
|
|
30
|
-
} else {
|
|
31
|
-
console.log('Connected to the SQLite database.');
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Değerin türünü otomatik olarak tespit eder ve SQLite türünü döndürür.
|
|
38
|
-
* @param {any} value - Kontrol edilecek değer
|
|
39
|
-
* @returns {string} SQLite veri türü
|
|
40
|
-
*/
|
|
41
|
-
_detectColumnType(value) {
|
|
42
|
-
if (value === null || value === undefined) {
|
|
43
|
-
return 'TEXT'; // Varsayılan olarak TEXT
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Boolean kontrolü
|
|
47
|
-
if (typeof value === 'boolean') {
|
|
48
|
-
return 'BOOLEAN';
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Number kontrolü
|
|
52
|
-
if (typeof value === 'number') {
|
|
53
|
-
// Tam sayı mı ondalık mı kontrol et
|
|
54
|
-
if (Number.isInteger(value)) {
|
|
55
|
-
return 'INTEGER';
|
|
56
|
-
} else {
|
|
57
|
-
return 'REAL';
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Date kontrolü
|
|
62
|
-
if (value instanceof Date) {
|
|
63
|
-
return 'DATETIME';
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// String kontrolü - sayısal string'leri kontrol et
|
|
67
|
-
if (typeof value === 'string') {
|
|
68
|
-
// Boş string kontrolü
|
|
69
|
-
if (value.trim() === '') {
|
|
70
|
-
return 'TEXT';
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Tam sayı string kontrolü
|
|
74
|
-
if (/^-?\d+$/.test(value.trim())) {
|
|
75
|
-
return 'INTEGER';
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Ondalık sayı string kontrolü
|
|
79
|
-
if (/^-?\d+\.\d+$/.test(value.trim())) {
|
|
80
|
-
return 'REAL';
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Boolean string kontrolü
|
|
84
|
-
const lowerValue = value.toLowerCase().trim();
|
|
85
|
-
if (lowerValue === 'true' || lowerValue === 'false') {
|
|
86
|
-
return 'BOOLEAN';
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ISO date string kontrolü
|
|
90
|
-
if (value.match(/^\d{4}-\d{2}-\d{2}/) || value.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)) {
|
|
91
|
-
return 'DATETIME';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Object ve Array kontrolü
|
|
96
|
-
if (typeof value === 'object') {
|
|
97
|
-
return 'TEXT'; // SQLite'da JSON olarak string halinde saklanacak
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Varsayılan olarak TEXT
|
|
101
|
-
return 'TEXT';
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Birden fazla değerden en uygun sütun türünü belirler.
|
|
106
|
-
* @param {Array} values - Değer dizisi
|
|
107
|
-
* @returns {string} En uygun SQLite veri türü
|
|
108
|
-
*/
|
|
109
|
-
_determineBestColumnType(values) {
|
|
110
|
-
const types = values.map(v => this._detectColumnType(v));
|
|
111
|
-
|
|
112
|
-
// Tür öncelik sırası: INTEGER < REAL < BOOLEAN < DATETIME < TEXT
|
|
113
|
-
const typePriority = {
|
|
114
|
-
'INTEGER': 1,
|
|
115
|
-
'REAL': 2,
|
|
116
|
-
'BOOLEAN': 3,
|
|
117
|
-
'DATETIME': 4,
|
|
118
|
-
'TEXT': 5
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
// En yüksek öncelikli türü seç
|
|
122
|
-
const maxPriority = Math.max(...types.map(t => typePriority[t] || 5));
|
|
123
|
-
const bestType = Object.keys(typePriority).find(t => typePriority[t] === maxPriority);
|
|
124
|
-
|
|
125
|
-
return bestType || 'TEXT';
|
|
126
|
-
}
|
|
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
|
-
|
|
146
|
-
/**
|
|
147
|
-
* SQL sorgusu çalıştırır. Promise döndürür.
|
|
148
|
-
* @param {string} sql - Çalıştırılacak SQL sorgusu.
|
|
149
|
-
* @param {Array} params - Sorgu parametreleri.
|
|
150
|
-
*/
|
|
151
|
-
query(sql, params = []) {
|
|
152
|
-
return new Promise((resolve, reject) => {
|
|
153
|
-
// SELECT sorguları için .all() kullanılır
|
|
154
|
-
if (sql.trim().toUpperCase().startsWith('SELECT') || sql.trim().toUpperCase().startsWith('PRAGMA')) {
|
|
155
|
-
this.db.all(sql, params, (err, rows) => {
|
|
156
|
-
if (err) reject(err);
|
|
157
|
-
else resolve(rows);
|
|
158
|
-
});
|
|
159
|
-
} else {
|
|
160
|
-
// INSERT, UPDATE, DELETE gibi sorgular için .run() kullanılır
|
|
161
|
-
this.db.run(sql, params, function (err) {
|
|
162
|
-
if (err) reject(err);
|
|
163
|
-
else resolve({ changes: this.changes, lastInsertRowid: this.lastID });
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Bir tablonun var olup olmadığını kontrol eder, yoksa oluşturur.
|
|
171
|
-
* @param {string} table - Tablo adı.
|
|
172
|
-
* @param {object} data - Tablo oluşturulurken sütunları belirlemek için örnek veri.
|
|
173
|
-
*/
|
|
174
|
-
async ensureTable(table, data = {}) {
|
|
175
|
-
try {
|
|
176
|
-
await this.query(`SELECT 1 FROM \`${table}\` LIMIT 1`);
|
|
177
|
-
} catch (error) {
|
|
178
|
-
if (error.message.includes('no such table')) {
|
|
179
|
-
const columnDefinitions = Object.keys(data).map(col => {
|
|
180
|
-
const columnType = this._detectColumnType(data[col]);
|
|
181
|
-
return `\`${col}\` ${columnType}`;
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
let columnsPart = '';
|
|
185
|
-
if (columnDefinitions.length > 0) {
|
|
186
|
-
columnsPart = ', ' + columnDefinitions.join(", ");
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const createTableSQL = `
|
|
190
|
-
CREATE TABLE \`${table}\` (
|
|
191
|
-
_id INTEGER PRIMARY KEY AUTOINCREMENT
|
|
192
|
-
${columnsPart}
|
|
193
|
-
)
|
|
194
|
-
`;
|
|
195
|
-
await this.query(createTableSQL);
|
|
196
|
-
} else {
|
|
197
|
-
throw error;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Verilen verideki anahtarların tabloda sütun olarak var olduğundan emin olur.
|
|
204
|
-
* @private
|
|
205
|
-
* @deprecated Bu fonksiyon yerine _ensureMissingColumns kullanılıyor
|
|
206
|
-
*/
|
|
207
|
-
async _ensureColumns(table, data) {
|
|
208
|
-
return this._ensureMissingColumns(table, data);
|
|
209
|
-
}
|
|
210
|
-
|
|
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
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return value;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Bir tabloya yeni veri ekler.
|
|
246
|
-
* @returns {Promise<number>} Eklenen satırın ID'si.
|
|
247
|
-
*/
|
|
248
|
-
async insert(table, data) {
|
|
249
|
-
const copy = { ...data };
|
|
250
|
-
await this.ensureTable(table, copy);
|
|
251
|
-
|
|
252
|
-
// Eksik kolonları ekle
|
|
253
|
-
await this._ensureMissingColumns(table, copy);
|
|
254
|
-
|
|
255
|
-
const keys = Object.keys(copy);
|
|
256
|
-
const placeholders = keys.map(() => '?').join(',');
|
|
257
|
-
const values = Object.values(copy).map(v => this._serializeValue(v));
|
|
258
|
-
const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(',')}) VALUES (${placeholders})`;
|
|
259
|
-
|
|
260
|
-
const result = await this.query(sql, values);
|
|
261
|
-
return result.lastInsertRowid;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Tablodaki verileri günceller.
|
|
266
|
-
* @returns {Promise<number>} Etkilenen satır sayısı.
|
|
267
|
-
*/
|
|
268
|
-
async update(table, data, where) {
|
|
269
|
-
await this.ensureTable(table, { ...data, ...where });
|
|
270
|
-
|
|
271
|
-
// Eksik kolonları ekle
|
|
272
|
-
await this._ensureMissingColumns(table, { ...data, ...where });
|
|
273
|
-
|
|
274
|
-
const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(', ');
|
|
275
|
-
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
276
|
-
const sql = `UPDATE \`${table}\` SET ${setString} WHERE ${whereString}`;
|
|
277
|
-
const result = await this.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
|
|
278
|
-
return result.changes;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Tablodan veri siler.
|
|
283
|
-
* @returns {Promise<number>} Etkilenen satır sayısı.
|
|
284
|
-
*/
|
|
285
|
-
async delete(table, where) {
|
|
286
|
-
if (!where || Object.keys(where).length === 0) return 0;
|
|
287
|
-
await this.ensureTable(table, { ...where });
|
|
288
|
-
|
|
289
|
-
// Eksik kolonları ekle (where koşulları için)
|
|
290
|
-
await this._ensureMissingColumns(table, where);
|
|
291
|
-
|
|
292
|
-
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
293
|
-
const sql = `DELETE FROM \`${table}\` WHERE ${whereString}`;
|
|
294
|
-
const result = await this.query(sql, Object.values(where).map(v => this._serializeValue(v)));
|
|
295
|
-
return result.changes;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Tablodan veri seçer.
|
|
300
|
-
* @returns {Promise<Array<object>>} Sonuç satırları.
|
|
301
|
-
*/
|
|
302
|
-
async select(table, where = null) {
|
|
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 => `\`${k}\` = ?`).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
|
-
* Veri varsa günceller, yoksa ekler (upsert).
|
|
331
|
-
*/
|
|
332
|
-
async set(table, data, where) {
|
|
333
|
-
await this.ensureTable(table, { ...data, ...where });
|
|
334
|
-
|
|
335
|
-
// Eksik kolonları ekle
|
|
336
|
-
await this._ensureMissingColumns(table, { ...data, ...where });
|
|
337
|
-
|
|
338
|
-
const existing = await this.select(table, where);
|
|
339
|
-
if (existing.length === 0) {
|
|
340
|
-
return await this.insert(table, { ...where, ...data });
|
|
341
|
-
} else {
|
|
342
|
-
return await this.update(table, data, where);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Koşula uyan ilk veriyi seçer.
|
|
348
|
-
* @returns {Promise<object|null>} Bulunan satır veya null.
|
|
349
|
-
*/
|
|
350
|
-
async selectOne(table, where = null) {
|
|
351
|
-
const results = await this.select(table, where);
|
|
352
|
-
return results[0] || null;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Koşula uyan ilk veriyi siler.
|
|
357
|
-
* @returns {Promise<number>} Etkilenen satır sayısı (0 veya 1).
|
|
358
|
-
*/
|
|
359
|
-
async deleteOne(table, where) {
|
|
360
|
-
if (!where || Object.keys(where).length === 0) return 0;
|
|
361
|
-
await this.ensureTable(table, where);
|
|
362
|
-
|
|
363
|
-
// Eksik kolonları ekle (where koşulları için)
|
|
364
|
-
await this._ensureMissingColumns(table, where);
|
|
365
|
-
|
|
366
|
-
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
367
|
-
const sql = `DELETE FROM \`${table}\` WHERE rowid IN (SELECT rowid FROM \`${table}\` WHERE ${whereString} LIMIT 1)`;
|
|
368
|
-
const result = await this.query(sql, Object.values(where).map(v => this._serializeValue(v)));
|
|
369
|
-
return result.changes;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Koşula uyan ilk veriyi günceller.
|
|
374
|
-
* @returns {Promise<number>} Etkilenen satır sayısı (0 veya 1).
|
|
375
|
-
*/
|
|
376
|
-
async updateOne(table, data, where) {
|
|
377
|
-
await this.ensureTable(table, { ...data, ...where });
|
|
378
|
-
|
|
379
|
-
// Eksik kolonları ekle
|
|
380
|
-
await this._ensureMissingColumns(table, { ...data, ...where });
|
|
381
|
-
|
|
382
|
-
const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(', ');
|
|
383
|
-
const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
|
|
384
|
-
const sql = `UPDATE \`${table}\` SET ${setString} WHERE rowid IN (SELECT rowid FROM \`${table}\` WHERE ${whereString} LIMIT 1)`;
|
|
385
|
-
const result = await this.query(sql, [...Object.values(data).map(v => this._serializeValue(v)), ...Object.values(where).map(v => this._serializeValue(v))]);
|
|
386
|
-
return result.changes;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Toplu veri ekleme.
|
|
391
|
-
* @returns {Promise<number>} Eklenen satır sayısı.
|
|
392
|
-
*/
|
|
393
|
-
async bulkInsert(table, dataArray) {
|
|
394
|
-
if (!Array.isArray(dataArray) || dataArray.length === 0) return 0;
|
|
395
|
-
|
|
396
|
-
// İlk elemanı tablo oluşturmak için kullan
|
|
397
|
-
await this.ensureTable(table, dataArray[0]);
|
|
398
|
-
|
|
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
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
const keys = Array.from(allKeys);
|
|
422
|
-
const placeholders = keys.map(() => '?').join(',');
|
|
423
|
-
const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(',')}) VALUES (${placeholders})`;
|
|
424
|
-
|
|
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
|
-
});
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* WHERE clause oluşturur
|
|
471
|
-
* @param {object} where - WHERE koşulları
|
|
472
|
-
* @returns {object} - whereClause string ve values array
|
|
473
|
-
*/
|
|
474
|
-
buildWhereClause(where = {}) {
|
|
475
|
-
const conditions = Object.keys(where);
|
|
476
|
-
if (conditions.length === 0) {
|
|
477
|
-
return { whereClause: '', values: [] };
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const whereClause = ' WHERE ' + conditions.map(key => `${key} = ?`).join(' AND ');
|
|
481
|
-
const values = Object.values(where);
|
|
482
|
-
|
|
483
|
-
return { whereClause, values };
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Numerik alanları artırır (increment).
|
|
488
|
-
* @param {string} table - Verinin güncelleneceği tablo adı.
|
|
489
|
-
* @param {object} increments - Artırılacak alanlar ve miktarları.
|
|
490
|
-
* @param {object} where - Güncelleme koşulları.
|
|
491
|
-
* @returns {Promise<number>} Etkilenen kayıt sayısı.
|
|
492
|
-
*/
|
|
493
|
-
async increment(table, increments, where = {}) {
|
|
494
|
-
const incrementClauses = Object.keys(increments).map(field =>
|
|
495
|
-
`${field} = ${field} + ?`
|
|
496
|
-
).join(', ');
|
|
497
|
-
|
|
498
|
-
const incrementValues = Object.values(increments);
|
|
499
|
-
const { whereClause, values: whereValues } = this.buildWhereClause(where);
|
|
500
|
-
|
|
501
|
-
const sql = `UPDATE ${table} SET ${incrementClauses}${whereClause}`;
|
|
502
|
-
const allValues = [...incrementValues, ...whereValues];
|
|
503
|
-
|
|
504
|
-
return new Promise((resolve, reject) => {
|
|
505
|
-
this.db.run(sql, allValues, function(err) {
|
|
506
|
-
if (err) reject(err);
|
|
507
|
-
else resolve(this.changes);
|
|
508
|
-
});
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* Numerik alanları azaltır (decrement).
|
|
514
|
-
* @param {string} table - Verinin güncelleneceği tablo adı.
|
|
515
|
-
* @param {object} decrements - Azaltılacak alanlar ve miktarları.
|
|
516
|
-
* @param {object} where - Güncelleme koşulları.
|
|
517
|
-
* @returns {Promise<number>} Etkilenen kayıt sayısı.
|
|
518
|
-
*/
|
|
519
|
-
async decrement(table, decrements, where = {}) {
|
|
520
|
-
const decrementClauses = Object.keys(decrements).map(field =>
|
|
521
|
-
`${field} = ${field} - ?`
|
|
522
|
-
).join(', ');
|
|
523
|
-
|
|
524
|
-
const decrementValues = Object.values(decrements);
|
|
525
|
-
const { whereClause, values: whereValues } = this.buildWhereClause(where);
|
|
526
|
-
|
|
527
|
-
const sql = `UPDATE ${table} SET ${decrementClauses}${whereClause}`;
|
|
528
|
-
const allValues = [...decrementValues, ...whereValues];
|
|
529
|
-
|
|
530
|
-
return new Promise((resolve, reject) => {
|
|
531
|
-
this.db.run(sql, allValues, function(err) {
|
|
532
|
-
if (err) reject(err);
|
|
533
|
-
else resolve(this.changes);
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Veritabanı bağlantısını kapatır.
|
|
540
|
-
*/
|
|
541
|
-
async close() {
|
|
542
|
-
return new Promise((resolve, reject) => {
|
|
543
|
-
this.db.close((err) => {
|
|
544
|
-
if (err) reject(err);
|
|
545
|
-
else resolve();
|
|
546
|
-
});
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
module.exports = SQLiteDatabase;
|