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