@onurege3467/zerohelper 5.0.3 → 6.0.1

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 (62) hide show
  1. package/data/test_db.json +3 -0
  2. package/data/test_db.sqlite +0 -0
  3. package/data/test_db_cached.sqlite +0 -0
  4. package/database/cacheWrapper.js +121 -0
  5. package/database/index.js +24 -6
  6. package/database/{adapters/json.js → json.js} +9 -9
  7. package/database/{adapters/mongodb.js → mongodb.js} +1 -0
  8. package/database/{adapters/mysql.js → mysql.js} +12 -12
  9. package/database/{adapters/sqlite.js → sqlite.js} +86 -77
  10. package/functions/index.js +14 -4
  11. package/package.json +4 -3
  12. package/readme.md +111 -324
  13. package/test.js +244 -0
  14. package/database/csvdb/index.js +0 -90
  15. package/database/jsondatabase/index.js +0 -132
  16. package/database/migrate/index.js +0 -68
  17. package/database/mongodb/index.js +0 -49
  18. package/database/mongodb/src/client/Client.js +0 -37
  19. package/database/mongodb/src/structers/Collection.js +0 -136
  20. package/database/mongodb/src/structers/Data.js +0 -282
  21. package/database/mongodb/src/structers/Database.js +0 -53
  22. package/database/mongodb/src/tools/FormatTool.js +0 -5
  23. package/database/mysql/examples/example.js +0 -301
  24. package/database/mysql/index.js +0 -1
  25. package/database/mysql/structures/classes/MySQL.js +0 -41
  26. package/database/mysql/structures/errors/strings.js +0 -23
  27. package/database/mysql/structures/methods/add.js +0 -19
  28. package/database/mysql/structures/methods/all.js +0 -25
  29. package/database/mysql/structures/methods/auto_increment.js +0 -16
  30. package/database/mysql/structures/methods/base_get.js +0 -14
  31. package/database/mysql/structures/methods/base_set.js +0 -21
  32. package/database/mysql/structures/methods/clear.js +0 -16
  33. package/database/mysql/structures/methods/connect.js +0 -15
  34. package/database/mysql/structures/methods/create.js +0 -11
  35. package/database/mysql/structures/methods/create_db.js +0 -10
  36. package/database/mysql/structures/methods/delete.js +0 -31
  37. package/database/mysql/structures/methods/drop.js +0 -13
  38. package/database/mysql/structures/methods/end.js +0 -7
  39. package/database/mysql/structures/methods/exists.js +0 -15
  40. package/database/mysql/structures/methods/get.js +0 -40
  41. package/database/mysql/structures/methods/getAllData.js +0 -35
  42. package/database/mysql/structures/methods/has.js +0 -42
  43. package/database/mysql/structures/methods/includes.js +0 -17
  44. package/database/mysql/structures/methods/ping.js +0 -11
  45. package/database/mysql/structures/methods/process.js +0 -7
  46. package/database/mysql/structures/methods/pull.js +0 -23
  47. package/database/mysql/structures/methods/push.js +0 -23
  48. package/database/mysql/structures/methods/query.js +0 -9
  49. package/database/mysql/structures/methods/rename.js +0 -16
  50. package/database/mysql/structures/methods/set.js +0 -60
  51. package/database/mysql/structures/methods/stats.js +0 -13
  52. package/database/mysql/structures/methods/sub.js +0 -19
  53. package/database/mysql/structures/methods/tables.js +0 -8
  54. package/database/mysql/structures/methods/variables.js +0 -20
  55. package/database/newMongoDB/index.js +0 -94
  56. package/database/newMySQL/index.js +0 -205
  57. package/database/newSQLite/index.js +0 -240
  58. package/database/postgresql/index.js +0 -150
  59. package/database/redis/index.js +0 -125
  60. package/database/sqldb/index.js +0 -243
  61. package/database/yamldatabase/index.js +0 -76
  62. /package/database/{adapters/IDatabase.js → IDatabase.js} +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ "users": []
3
+ }
Binary file
Binary file
@@ -0,0 +1,121 @@
1
+ const { LRUCache } = require('lru-cache');
2
+
3
+ class CacheWrapper {
4
+ constructor(databaseInstance, options = {}) {
5
+ this.db = databaseInstance;
6
+ this.cache = new LRUCache({
7
+ max: options.max || 500, // Maximum number of items in cache
8
+ ttl: options.ttl || 1000 * 60 * 5, // Time to live in ms (5 minutes)
9
+ updateAgeOnGet: options.updateAgeOnGet !== undefined ? options.updateAgeOnGet : false, // Update item age on get
10
+ });
11
+ this.tableCaches = {}; // Cache for each table
12
+ }
13
+
14
+ _getCache(table) {
15
+ if (!this.tableCaches[table]) {
16
+ this.tableCaches[table] = new LRUCache({
17
+ max: this.cache.max,
18
+ ttl: this.cache.ttl,
19
+ updateAgeOnGet: this.cache.updateAgeOnGet,
20
+ });
21
+ }
22
+ return this.tableCaches[table];
23
+ }
24
+
25
+ _generateKey(table, where) {
26
+ return `${table}:${JSON.stringify(where || {})}`;
27
+ }
28
+
29
+ // Read operations
30
+ async select(table, where) {
31
+ const cache = this._getCache(table);
32
+ const key = this._generateKey(table, where);
33
+ let data = cache.get(key);
34
+
35
+ if (data) {
36
+ // console.log(`Cache hit for select: ${key}`);
37
+ return data;
38
+ }
39
+
40
+ // console.log(`Cache miss for select: ${key}`);
41
+ data = await this.db.select(table, where);
42
+ cache.set(key, data);
43
+ return data;
44
+ }
45
+
46
+ async selectOne(table, where) {
47
+ const cache = this._getCache(table);
48
+ const key = this._generateKey(table, where);
49
+ let data = cache.get(key);
50
+
51
+ if (data) {
52
+ // console.log(`Cache hit for selectOne: ${key}`);
53
+ return data;
54
+ }
55
+
56
+ // console.log(`Cache miss for selectOne: ${key}`);
57
+ data = await this.db.selectOne(table, where);
58
+ cache.set(key, data);
59
+ return data;
60
+ }
61
+
62
+ // Write operations (invalidate cache)
63
+ async insert(table, data) {
64
+ this._getCache(table).clear();
65
+ return this.db.insert(table, data);
66
+ }
67
+
68
+ async update(table, data, where) {
69
+ this._getCache(table).clear();
70
+ return this.db.update(table, data, where);
71
+ }
72
+
73
+ async set(table, data, where) {
74
+ this._getCache(table).clear();
75
+ return this.db.set(table, data, where);
76
+ }
77
+
78
+ async delete(table, where) {
79
+ this._getCache(table).clear();
80
+ return this.db.delete(table, where);
81
+ }
82
+
83
+ async bulkInsert(table, dataArray) {
84
+ this._getCache(table).clear();
85
+ return this.db.bulkInsert(table, dataArray);
86
+ }
87
+
88
+ async deleteOne(table, where) {
89
+ this._getCache(table).clear();
90
+ return this.db.deleteOne(table, where);
91
+ }
92
+
93
+ async updateOne(table, data, where) {
94
+ this._getCache(table).clear();
95
+ return this.db.updateOne(table, data, where);
96
+ }
97
+
98
+ // Pass-through for other methods (e.g., close, ensureTable, query for MySQL/SQLite)
99
+ async close() {
100
+ // Clear all caches before closing
101
+ Object.values(this.tableCaches).forEach(cache => cache.clear());
102
+ this.cache.clear();
103
+ return this.db.close();
104
+ }
105
+
106
+ // Dynamically pass through any other methods not explicitly defined here
107
+ // This ensures compatibility with specific adapter methods (e.g., MySQL's connect, ping)
108
+ // Note: This is a simplified approach. A more robust solution might involve checking
109
+ // if the underlying db instance has the method before calling.
110
+ get(target, prop) {
111
+ if (typeof this[prop] !== 'undefined') {
112
+ return this[prop];
113
+ } else if (typeof this.db[prop] === 'function') {
114
+ return this.db[prop].bind(this.db);
115
+ } else {
116
+ return this.db[prop];
117
+ }
118
+ }
119
+ }
120
+
121
+ module.exports = CacheWrapper;
package/database/index.js CHANGED
@@ -1,8 +1,9 @@
1
- const IDatabase = require('./adapters/IDatabase');
2
- const MySQLDatabase = require('./adapters/mysql');
3
- const SQLiteDatabase = require('./adapters/sqlite');
4
- const MongoDBDatabase = require('./adapters/mongodb');
5
- const JsonDatabase = require('./adapters/json');
1
+ const IDatabase = require('./IDatabase');
2
+ const MySQLDatabase = require('./mysql');
3
+ const SQLiteDatabase = require('./sqlite');
4
+ const MongoDBDatabase = require('./mongodb');
5
+ const JsonDatabase = require('./json');
6
+ const CacheWrapper = require('./cacheWrapper');
6
7
 
7
8
  const adapters = {
8
9
  mysql: MySQLDatabase,
@@ -35,7 +36,24 @@ function createDatabase(options) {
35
36
  const DatabaseClass = adapters[adapter];
36
37
 
37
38
  // Sınıfın bir örneğini oluştur ve doğrudan döndür
38
- return new DatabaseClass(config);
39
+ const dbInstance = new DatabaseClass(config);
40
+
41
+ // Eğer cache etkinse, veritabanı örneğini CacheWrapper ile sarmala
42
+ if (config.cache) {
43
+ return new Proxy(new CacheWrapper(dbInstance, config.cache), {
44
+ get: (target, prop) => {
45
+ if (typeof target[prop] !== 'undefined') {
46
+ return target[prop];
47
+ } else if (typeof target.db[prop] === 'function') {
48
+ return target.db[prop].bind(target.db);
49
+ } else {
50
+ return target.db[prop];
51
+ }
52
+ }
53
+ });
54
+ }
55
+
56
+ return dbInstance;
39
57
  }
40
58
 
41
59
  // Artık varsayılan olarak bu fonksiyonu export ediyoruz.
@@ -111,7 +111,7 @@ class JsonDatabase extends IDatabase{
111
111
  async ensureTable(table) {
112
112
  await this.initPromise;
113
113
  if (!this.db[table]) {
114
- return this._enqueueWrite(() => {
114
+ return this._queueRequest(() => {
115
115
  this.db[table] = [];
116
116
  });
117
117
  }
@@ -119,7 +119,7 @@ class JsonDatabase extends IDatabase{
119
119
 
120
120
  async insert(table, data) {
121
121
  await this.ensureTable(table);
122
- return this._enqueueWrite(() => {
122
+ return this._queueRequest(() => {
123
123
  const maxId = this.db[table].reduce((max, row) => (row._id > max ? row._id : max), 0);
124
124
  const newId = maxId + 1;
125
125
  const newRow = { _id: newId, ...data };
@@ -130,7 +130,7 @@ class JsonDatabase extends IDatabase{
130
130
 
131
131
  async update(table, data, where) {
132
132
  await this.ensureTable(table);
133
- return this._enqueueWrite(() => {
133
+ return this._queueRequest(() => {
134
134
  let affectedRows = 0;
135
135
  this.db[table].forEach(row => {
136
136
  if (this._matches(row, where)) {
@@ -144,7 +144,7 @@ class JsonDatabase extends IDatabase{
144
144
 
145
145
  async delete(table, where) {
146
146
  await this.ensureTable(table);
147
- return this._enqueueWrite(() => {
147
+ return this._queueRequest(() => {
148
148
  const initialLength = this.db[table].length;
149
149
  this.db[table] = this.db[table].filter(row => !this._matches(row, where));
150
150
  return initialLength - this.db[table].length;
@@ -179,32 +179,32 @@ class JsonDatabase extends IDatabase{
179
179
 
180
180
  async deleteOne(table, where) {
181
181
  await this.ensureTable(table);
182
- return this._enqueueWrite(() => {
182
+ return this._queueRequest(() => {
183
183
  const index = this.db[table].findIndex(row => this._matches(row, where));
184
184
  if (index > -1) {
185
185
  this.db[table].splice(index, 1);
186
186
  return 1; // 1 satır etkilendi
187
187
  }
188
- return 0; // Hiçbir satır etkilenmedi
188
+ return 0; // Hiçbir satır etkilendi
189
189
  });
190
190
  }
191
191
 
192
192
  async updateOne(table, data, where) {
193
193
  await this.ensureTable(table);
194
- return this._enqueueWrite(() => {
194
+ return this._queueRequest(() => {
195
195
  const row = this.db[table].find(row => this._matches(row, where));
196
196
  if (row) {
197
197
  Object.assign(row, data);
198
198
  return 1; // 1 satır etkilendi
199
199
  }
200
- return 0; // Hiçbir satır etkilenmedi
200
+ return 0; // Hiçbir satır etkilendi
201
201
  });
202
202
  }
203
203
 
204
204
  async bulkInsert(table, dataArray) {
205
205
  if (!Array.isArray(dataArray) || dataArray.length === 0) return 0;
206
206
  await this.ensureTable(table);
207
- return this._enqueueWrite(() => {
207
+ return this._queueRequest(() => {
208
208
  let maxId = this.db[table].reduce((max, row) => (row._id > max ? row._id : max), 0);
209
209
  dataArray.forEach(data => {
210
210
  maxId++;
@@ -7,6 +7,7 @@ const { MongoClient, ObjectId } = require("mongodb");
7
7
 
8
8
  class MongoDBDatabase extends IDatabase{
9
9
  constructor(config) {
10
+ super();
10
11
  this.config = config;
11
12
  this.client = new MongoClient(config.url, {
12
13
  useNewUrlParser: true,
@@ -80,7 +80,7 @@ class MySQLDatabase extends IDatabase{
80
80
 
81
81
  async ensureTable(table, data = {}) {
82
82
  return this._queueRequest(async () => {
83
- if (!data || Object.keys(data).length === 0) return;
83
+
84
84
 
85
85
  const escapedTable = mysql.escape(table);
86
86
  const tables = await this.query(`SHOW TABLES LIKE ${escapedTable}`);
@@ -124,20 +124,20 @@ class MySQLDatabase extends IDatabase{
124
124
  async update(table, data, where) {
125
125
  return this._queueRequest(async () => {
126
126
  await this.ensureTable(table, { ...data, ...where });
127
- const existingColumns = await this.query(`DESCRIBE `${table}``).catch(() => null);
127
+ const existingColumns = await this.query(`DESCRIBE \`${table}\``).catch(() => null);
128
128
  if (!existingColumns) throw new Error(`Table ${table} does not exist.`);
129
129
 
130
130
  const existingColumnNames = existingColumns.map(col => col.Field);
131
131
  for (const key of Object.keys(data)) {
132
132
  if (!existingColumnNames.includes(key)) {
133
- const alterSQL = `ALTER TABLE `${table}` ADD COLUMN `${key}` VARCHAR(255)`;
133
+ const alterSQL = `ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` VARCHAR(255)`;
134
134
  await this.query(alterSQL);
135
135
  console.log(`Added missing column '${key}' to table '${table}'`);
136
136
  }
137
137
  }
138
- const setString = Object.keys(data).map(k => ``${k}`` = ?`).join(", ");
139
- const whereString = Object.keys(where).map(k => ``${k}`` = ?`).join(" AND ");
140
- const sql = `UPDATE `${table}` SET ${setString} WHERE ${whereString}`;
138
+ const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(", ");
139
+ const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(" AND ");
140
+ const sql = `UPDATE \`${table}\` SET ${setString} WHERE ${whereString}`;
141
141
  const result = await this.query(sql, [...Object.values(data), ...Object.values(where)]);
142
142
  return result.affectedRows;
143
143
  });
@@ -157,11 +157,11 @@ class MySQLDatabase extends IDatabase{
157
157
  async select(table, where = null) {
158
158
  return this._queueRequest(async () => {
159
159
  await this.ensureTable(table, where || {});
160
- let sql = `SELECT * FROM `${table}``;
160
+ let sql = `SELECT * FROM \`${table}\``;
161
161
  let params = [];
162
162
 
163
163
  if (where && Object.keys(where).length > 0) {
164
- const whereString = Object.keys(where).map(k => ``${k}`` = ?`).join(" AND ");
164
+ const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(" AND ");
165
165
  sql += ` WHERE ${whereString}`;
166
166
  params = Object.values(where);
167
167
  }
@@ -238,20 +238,20 @@ class MySQLDatabase extends IDatabase{
238
238
  if (!Array.isArray(dataArray) || dataArray.length === 0) return 0;
239
239
  await this.ensureTable(table, dataArray[0]);
240
240
 
241
- const existingColumns = await this.query(`DESCRIBE `${table}``);
241
+ const existingColumns = await this.query(`DESCRIBE \`${table}\``);
242
242
  const existingColumnNames = existingColumns.map(col => col.Field);
243
243
  const keys = Object.keys(dataArray[0]);
244
244
 
245
245
  // Eksik kolonları sadece ilk elemana göre kontrol et
246
246
  for (const key of keys) {
247
247
  if (!existingColumnNames.includes(key)) {
248
- await this.query(`ALTER TABLE `${table}` ADD COLUMN `${key}` VARCHAR(255)`);
248
+ await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` VARCHAR(255)`);
249
249
  }
250
250
  }
251
251
 
252
252
  const placeholders = dataArray.map(() => `(${keys.map(() => '?').join(',')})`).join(',');
253
253
  const values = dataArray.flatMap(obj => keys.map(k => obj[k]));
254
- const sql = `INSERT INTO `${table}` (${keys.map(k => ``${k}``).join(",")}) VALUES ${placeholders}`;
254
+ const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(",")}) VALUES ${placeholders}`;
255
255
 
256
256
  const result = await this.query(sql, values);
257
257
  return result.affectedRows;
@@ -263,4 +263,4 @@ class MySQLDatabase extends IDatabase{
263
263
  }
264
264
  }
265
265
 
266
- module.exports = MySQLDatabase;
266
+ module.exports = MySQLDatabase;
@@ -3,7 +3,7 @@ const IDatabase = require('./IDatabase'); // Arayüzü import et
3
3
  /**
4
4
  * @implements {IDatabase}
5
5
  */
6
- const Database = require('better-sqlite3');
6
+ const sqlite3 = require('sqlite3').verbose();
7
7
  const fs = require('fs');
8
8
  const path = require('path');
9
9
 
@@ -24,28 +24,36 @@ class SQLiteDatabase extends IDatabase{
24
24
  fs.mkdirSync(dir, { recursive: true });
25
25
  }
26
26
 
27
- // better-sqlite3 senkron çalıştığı için bağlantı anında kurulur.
28
- this.db = new Database(config.filePath);
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
+ });
29
34
  }
30
35
 
31
36
  /**
32
- * SQL sorgusu çalıştırır. SELECT için satırları, diğerleri için bilgiyi döndürür.
37
+ * SQL sorgusu çalıştırır. Promise döndürür.
33
38
  * @param {string} sql - Çalıştırılacak SQL sorgusu.
34
39
  * @param {Array} params - Sorgu parametreleri.
35
40
  */
36
41
  query(sql, params = []) {
37
- try {
38
- // SELECT sorguları için .all() kullanılır ve bir dizi döndürür.
39
- return this.db.prepare(sql).all(params);
40
- } catch (error) {
41
- // INSERT, UPDATE, DELETE gibi sorgular .all() ile çalışmaz, .run() kullanılır.
42
- // Bu sorgular bir bilgi nesnesi döndürür (örn: { changes: 1, lastInsertRowid: 5 })
43
- if (error.message.includes('This statement does not return data')) {
44
- return this.db.prepare(sql).run(params);
42
+ return new Promise((resolve, reject) => {
43
+ // SELECT sorguları için .all() kullanılır
44
+ if (sql.trim().toUpperCase().startsWith('SELECT') || sql.trim().toUpperCase().startsWith('PRAGMA')) {
45
+ this.db.all(sql, params, (err, rows) => {
46
+ if (err) reject(err);
47
+ else resolve(rows);
48
+ });
49
+ } else {
50
+ // INSERT, UPDATE, DELETE gibi sorgular için .run() kullanılır
51
+ this.db.run(sql, params, function (err) {
52
+ if (err) reject(err);
53
+ else resolve({ changes: this.changes, lastInsertRowid: this.lastID });
54
+ });
45
55
  }
46
- // Başka bir hata varsa fırlat
47
- throw error;
48
- }
56
+ });
49
57
  }
50
58
 
51
59
  /**
@@ -53,16 +61,13 @@ class SQLiteDatabase extends IDatabase{
53
61
  * @param {string} table - Tablo adı.
54
62
  * @param {object} data - Tablo oluşturulurken sütunları belirlemek için örnek veri.
55
63
  */
56
- ensureTable(table, data = {}) {
57
- if (!data || Object.keys(data).length === 0) return;
64
+ async ensureTable(table, data = {}) {
65
+
58
66
 
59
67
  try {
60
- // Tablonun varlığını kontrol etmenin en hızlı yolu bir sorgu denemektir.
61
- this.db.prepare(`SELECT 1 FROM \`${table}\` LIMIT 1`).get();
68
+ await this.query(`SELECT 1 FROM \`${table}\` LIMIT 1`);
62
69
  } catch (error) {
63
- // "no such table" hatası alırsak, tabloyu oluştur.
64
70
  if (error.message.includes('no such table')) {
65
- // SQLite tipleri esnek olduğu için TEXT çoğu veri tipi için yeterlidir.
66
71
  const columns = Object.keys(data).map(col => `\`${col}\` TEXT`).join(', ');
67
72
  const createTableSQL = `
68
73
  CREATE TABLE \`${table}\` (
@@ -70,7 +75,7 @@ class SQLiteDatabase extends IDatabase{
70
75
  ${columns}
71
76
  )
72
77
  `;
73
- this.query(createTableSQL);
78
+ await this.query(createTableSQL);
74
79
  } else {
75
80
  throw error;
76
81
  }
@@ -81,69 +86,69 @@ class SQLiteDatabase extends IDatabase{
81
86
  * Verilen verideki anahtarların tabloda sütun olarak var olduğundan emin olur.
82
87
  * @private
83
88
  */
84
- _ensureColumns(table, data) {
85
- const columnsInfo = this.db.prepare(`PRAGMA table_info(\`${table}\`)`).all();
89
+ async _ensureColumns(table, data) {
90
+ const columnsInfo = await this.query(`PRAGMA table_info(\`${table}\`)`);
86
91
  const existingNames = columnsInfo.map(col => col.name);
87
92
 
88
93
  for (const key of Object.keys(data)) {
89
94
  if (!existingNames.includes(key)) {
90
- this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` TEXT`);
95
+ await this.query(`ALTER TABLE \`${table}\` ADD COLUMN \`${key}\` TEXT`);
91
96
  }
92
97
  }
93
98
  }
94
99
 
95
100
  /**
96
101
  * Bir tabloya yeni veri ekler.
97
- * @returns {number} Eklenen satırın ID'si.
102
+ * @returns {Promise<number>} Eklenen satırın ID'si.
98
103
  */
99
- insert(table, data) {
104
+ async insert(table, data) {
100
105
  const copy = { ...data };
101
- this.ensureTable(table, copy);
102
- this._ensureColumns(table, copy);
106
+ await this.ensureTable(table, copy);
107
+ await this._ensureColumns(table, copy);
103
108
 
104
109
  const keys = Object.keys(copy);
105
110
  const placeholders = keys.map(() => '?').join(',');
106
111
  const values = Object.values(copy);
107
112
  const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(',')}) VALUES (${placeholders})`;
108
113
 
109
- const result = this.query(sql, values);
110
- return result.lastInsertRowid; // SQLite'ta `insertId` yerine `lastInsertRowid` kullanılır.
114
+ const result = await this.query(sql, values);
115
+ return result.lastInsertRowid;
111
116
  }
112
117
 
113
118
  /**
114
119
  * Tablodaki verileri günceller.
115
- * @returns {number} Etkilenen satır sayısı.
120
+ * @returns {Promise<number>} Etkilenen satır sayısı.
116
121
  */
117
- update(table, data, where) {
118
- this.ensureTable(table, { ...data, ...where });
119
- this._ensureColumns(table, data);
122
+ async update(table, data, where) {
123
+ await this.ensureTable(table, { ...data, ...where });
124
+ await this._ensureColumns(table, data);
120
125
 
121
126
  const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(', ');
122
127
  const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
123
128
  const sql = `UPDATE \`${table}\` SET ${setString} WHERE ${whereString}`;
124
- const result = this.query(sql, [...Object.values(data), ...Object.values(where)]);
125
- return result.changes; // SQLite'ta `affectedRows` yerine `changes` kullanılır.
129
+ const result = await this.query(sql, [...Object.values(data), ...Object.values(where)]);
130
+ return result.changes;
126
131
  }
127
132
 
128
133
  /**
129
134
  * Tablodan veri siler.
130
- * @returns {number} Etkilenen satır sayısı.
135
+ * @returns {Promise<number>} Etkilenen satır sayısı.
131
136
  */
132
- delete(table, where) {
137
+ async delete(table, where) {
133
138
  if (!where || Object.keys(where).length === 0) return 0;
134
- this.ensureTable(table, { ...where });
139
+ await this.ensureTable(table, { ...where });
135
140
  const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
136
141
  const sql = `DELETE FROM \`${table}\` WHERE ${whereString}`;
137
- const result = this.query(sql, Object.values(where));
142
+ const result = await this.query(sql, Object.values(where));
138
143
  return result.changes;
139
144
  }
140
145
 
141
146
  /**
142
147
  * Tablodan veri seçer.
143
- * @returns {Array<object>} Sonuç satırları.
148
+ * @returns {Promise<Array<object>>} Sonuç satırları.
144
149
  */
145
- select(table, where = null) {
146
- this.ensureTable(table, where || {});
150
+ async select(table, where = null) {
151
+ await this.ensureTable(table, where || {});
147
152
  let sql = `SELECT * FROM \`${table}\``;
148
153
  let params = [];
149
154
 
@@ -153,92 +158,96 @@ class SQLiteDatabase extends IDatabase{
153
158
  params = Object.values(where);
154
159
  }
155
160
 
156
- return this.query(sql, params);
161
+ return await this.query(sql, params);
157
162
  }
158
163
 
159
164
  /**
160
165
  * Veri varsa günceller, yoksa ekler (upsert).
161
166
  */
162
- set(table, data, where) {
163
- this.ensureTable(table, { ...data, ...where });
164
- this._ensureColumns(table, data);
165
- const existing = this.select(table, where);
167
+ async set(table, data, where) {
168
+ await this.ensureTable(table, { ...data, ...where });
169
+ await this._ensureColumns(table, data);
170
+ const existing = await this.select(table, where);
166
171
  if (existing.length === 0) {
167
- return this.insert(table, { ...where, ...data });
172
+ return await this.insert(table, { ...where, ...data });
168
173
  } else {
169
- return this.update(table, data, where);
174
+ return await this.update(table, data, where);
170
175
  }
171
176
  }
172
177
 
173
178
  /**
174
179
  * Koşula uyan ilk veriyi seçer.
175
- * @returns {object|null} Bulunan satır veya null.
180
+ * @returns {Promise<object|null>} Bulunan satır veya null.
176
181
  */
177
- selectOne(table, where = null) {
178
- const results = this.select(table, where);
182
+ async selectOne(table, where = null) {
183
+ const results = await this.select(table, where);
179
184
  return results[0] || null;
180
185
  }
181
186
 
182
187
  /**
183
188
  * Koşula uyan ilk veriyi siler.
184
- * @returns {number} Etkilenen satır sayısı (0 veya 1).
189
+ * @returns {Promise<number>} Etkilenen satır sayısı (0 veya 1).
185
190
  */
186
- deleteOne(table, where) {
191
+ async deleteOne(table, where) {
187
192
  if (!where || Object.keys(where).length === 0) return 0;
188
- this.ensureTable(table, where);
193
+ await this.ensureTable(table, where);
189
194
  const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
190
195
  const sql = `DELETE FROM \`${table}\` WHERE rowid IN (SELECT rowid FROM \`${table}\` WHERE ${whereString} LIMIT 1)`;
191
- const result = this.query(sql, Object.values(where));
196
+ const result = await this.query(sql, Object.values(where));
192
197
  return result.changes;
193
198
  }
194
199
 
195
200
  /**
196
201
  * Koşula uyan ilk veriyi günceller.
197
- * @returns {number} Etkilenen satır sayısı (0 veya 1).
202
+ * @returns {Promise<number>} Etkilenen satır sayısı (0 veya 1).
198
203
  */
199
- updateOne(table, data, where) {
200
- this.ensureTable(table, { ...data, ...where });
201
- this._ensureColumns(table, data);
204
+ async updateOne(table, data, where) {
205
+ await this.ensureTable(table, { ...data, ...where });
206
+ await this._ensureColumns(table, data);
202
207
  const setString = Object.keys(data).map(k => `\`${k}\` = ?`).join(', ');
203
208
  const whereString = Object.keys(where).map(k => `\`${k}\` = ?`).join(' AND ');
204
209
  const sql = `UPDATE \`${table}\` SET ${setString} WHERE rowid IN (SELECT rowid FROM \`${table}\` WHERE ${whereString} LIMIT 1)`;
205
- const result = this.query(sql, [...Object.values(data), ...Object.values(where)]);
210
+ const result = await this.query(sql, [...Object.values(data), ...Object.values(where)]);
206
211
  return result.changes;
207
212
  }
208
213
 
209
214
  /**
210
215
  * Toplu veri ekleme.
211
- * @returns {number} Eklenen satır sayısı.
216
+ * @returns {Promise<number>} Eklenen satır sayısı.
212
217
  */
213
- bulkInsert(table, dataArray) {
218
+ async bulkInsert(table, dataArray) {
214
219
  if (!Array.isArray(dataArray) || dataArray.length === 0) return 0;
215
- this.ensureTable(table, dataArray[0]);
216
- this._ensureColumns(table, dataArray[0]);
220
+ await this.ensureTable(table, dataArray[0]);
221
+ await this._ensureColumns(table, dataArray[0]);
217
222
 
218
223
  const keys = Object.keys(dataArray[0]);
219
224
  const placeholders = keys.map(() => '?').join(',');
220
225
  const sql = `INSERT INTO \`${table}\` (${keys.map(k => `\`${k}\``).join(',')}) VALUES (${placeholders})`;
221
226
 
222
- // better-sqlite3'nin transaction özelliği toplu işlemlerde çok yüksek performans sağlar.
223
- const insertMany = this.db.transaction((items) => {
224
- const stmt = this.db.prepare(sql);
225
- for (const item of items) {
227
+ // sqlite3'te toplu ekleme için transaction kullanabiliriz
228
+ const stmt = this.db.prepare(sql);
229
+ this.db.serialize(() => {
230
+ this.db.run("BEGIN TRANSACTION;");
231
+ for (const item of dataArray) {
226
232
  stmt.run(Object.values(item));
227
233
  }
234
+ this.db.run("COMMIT;");
228
235
  });
229
236
 
230
- insertMany(dataArray);
231
237
  return dataArray.length;
232
238
  }
233
239
 
234
240
  /**
235
241
  * Veritabanı bağlantısını kapatır.
236
242
  */
237
- close() {
238
- if (this.db) {
239
- this.db.close();
240
- }
243
+ async close() {
244
+ return new Promise((resolve, reject) => {
245
+ this.db.close((err) => {
246
+ if (err) reject(err);
247
+ else resolve();
248
+ });
249
+ });
241
250
  }
242
251
  }
243
252
 
244
- module.exports = SQLiteDatabase;
253
+ module.exports = SQLiteDatabase;
@@ -124,15 +124,25 @@ function deepMerge(obj1, obj2) {
124
124
  }
125
125
 
126
126
  // Şifreleme ve Güvenlik
127
+ function getKeyFromSecret(secret) {
128
+ // Use a fixed salt for simplicity in testing. In production, use a unique salt per encryption.
129
+ const salt = Buffer.from('some_fixed_salt_for_testing_only', 'utf8');
130
+ return crypto.pbkdf2Sync(secret, salt, 100000, 32, 'sha512'); // 32 bytes for AES-256
131
+ }
132
+
127
133
  function encryptText(text, secret) {
128
- const cipher = crypto.createCipher("aes-256-cbc", secret);
134
+ const key = getKeyFromSecret(secret);
135
+ const iv = crypto.randomBytes(16); // Initialization vector
136
+ const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
129
137
  let encrypted = cipher.update(text, "utf8", "hex");
130
138
  encrypted += cipher.final("hex");
131
- return encrypted;
139
+ return { encryptedText: encrypted, iv: iv.toString('hex') };
132
140
  }
133
141
 
134
- function decryptText(encryptedText, secret) {
135
- const decipher = crypto.createDecipher("aes-256-cbc", secret);
142
+ function decryptText(encryptedText, secret, ivHex) {
143
+ const key = getKeyFromSecret(secret);
144
+ const iv = Buffer.from(ivHex, 'hex');
145
+ const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
136
146
  let decrypted = decipher.update(encryptedText, "hex", "utf8");
137
147
  decrypted += decipher.final("utf8");
138
148
  return decrypted;