@aetherframework/database 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +846 -0
  3. package/index.js +31 -0
  4. package/package.json +56 -0
  5. package/src/DatabaseManager.js +565 -0
  6. package/src/core/ConnectionManager.js +351 -0
  7. package/src/core/DatabaseFactory.js +188 -0
  8. package/src/core/MongoQueryBuilder.js +576 -0
  9. package/src/core/PluginManager.js +968 -0
  10. package/src/core/QueryBuilder.js +4398 -0
  11. package/src/core/TransactionManager.js +40 -0
  12. package/src/drivers/clickhouse-driver.js +272 -0
  13. package/src/drivers/index.js +273 -0
  14. package/src/drivers/mongodb-driver.js +87 -0
  15. package/src/drivers/mssql-driver.js +117 -0
  16. package/src/drivers/mysql-driver.js +169 -0
  17. package/src/drivers/oracle-driver.js +101 -0
  18. package/src/drivers/postgres-driver.js +234 -0
  19. package/src/drivers/redis-driver.js +52 -0
  20. package/src/drivers/sqlite-driver.js +67 -0
  21. package/src/middleware/connection-pool.js +455 -0
  22. package/src/middleware/performance-monitor.js +652 -0
  23. package/src/middleware/query-cache.js +500 -0
  24. package/src/middleware/query-logger.js +262 -0
  25. package/src/plugins/AuditPlugin.js +447 -0
  26. package/src/plugins/BasePlugin.js +418 -0
  27. package/src/plugins/BatchOperationPlugin.js +165 -0
  28. package/src/plugins/CachePlugin.js +407 -0
  29. package/src/plugins/CtePlugin.js +523 -0
  30. package/src/plugins/DistributedPlugin.js +543 -0
  31. package/src/plugins/EncryptionPlugin.js +211 -0
  32. package/src/plugins/FullTextSearchPlugin.js +164 -0
  33. package/src/plugins/GeospatialPlugin.js +219 -0
  34. package/src/plugins/GraphQLPlugin.js +162 -0
  35. package/src/plugins/HookPlugin.js +211 -0
  36. package/src/plugins/JsonPlugin.js +366 -0
  37. package/src/plugins/OptimisticLockPlugin.js +374 -0
  38. package/src/plugins/PerformancePlugin.js +175 -0
  39. package/src/plugins/ResiliencePlugin.js +114 -0
  40. package/src/plugins/ShardingPlugin.js +227 -0
  41. package/src/plugins/SoftDeletePlugin.js +258 -0
  42. package/src/plugins/SyncPlugin.js +373 -0
  43. package/src/plugins/VersioningPlugin.js +314 -0
  44. package/src/plugins/WindowFunctionPlugin.js +343 -0
  45. package/src/utils/config-loader.js +632 -0
  46. package/src/utils/error-handler.js +724 -0
  47. package/src/utils/migration-runner.js +1066 -0
  48. package/types.js +129 -0
package/README.md ADDED
@@ -0,0 +1,846 @@
1
+ AetherFramework Database - Zero-Dependency Multi-Database Integration for Node.js
2
+
3
+ 🚀 Why Choose AetherFramework Database?
4
+
5
+ AetherFramework Database is a revolutionary database integration solution designed specifically for the AetherJS API framework, but flexible enough to work with any Node.js application. In a world of bloated dependencies and complex ORMs, we offer a refreshing alternative that prioritizes performance, simplicity, and developer experience.
6
+
7
+ 📊 Key Advantages Over Other Solutions
8
+
9
+ | Feature | AetherFramework Database | TypeORM | Sequelize | Knex.js | Prisma |
10
+ |---------|-----------------------------|---------|-----------|---------|--------|
11
+ | Zero Dependencies | ✅ No external dependencies | ❌ 50+ dependencies | ❌ 40+ dependencies | ❌ 15+ dependencies | ❌ 100+ dependencies |
12
+ | Bundle Size | ✅ ~100KB | ❌ ~10MB | ❌ ~8MB | ❌ ~2MB | ❌ ~20MB |
13
+ | Multi-Database Support | ✅ 8+ databases unified API | ✅ 7+ databases | ✅ 6+ databases | ✅ 7+ databases | ✅ 5+ databases |
14
+ | Built-in Features | ✅ Pooling, Caching, Monitoring, Migrations | ❌ Requires plugins | ❌ Requires plugins | ❌ Basic only | ❌ Limited |
15
+ | TypeScript Support | ✅ First-class with full types | ✅ Excellent | ✅ Good | ✅ Basic | ✅ Excellent |
16
+ | Learning Curve | ✅ Gentle, intuitive API | 🔴 Complex | 🟡 Moderate | 🟢 Simple | 🔴 Complex |
17
+ | Performance | ✅ Native speed, no overhead | 🟡 Good | 🟡 Good | 🟢 Excellent | 🟢 Good |
18
+
19
+
20
+ 📦 Installation
21
+
22
+ ```bash
23
+ Using npm
24
+ npm install @aetherframework/database
25
+ ```
26
+
27
+ 🚀 Quick Start
28
+
29
+ With AetherJS
30
+
31
+ ```javascript
32
+ // In your AetherJS project
33
+ import { Database } from '@aetherframework/database';
34
+
35
+ // Minimal configuration
36
+ const db = new Database({
37
+ connections: {
38
+ primary: {
39
+ type: 'sqlite',
40
+ database: './data/app.db'
41
+ }
42
+ }
43
+ });
44
+
45
+ // Initialize
46
+ await db.init();
47
+
48
+ // Start using immediately
49
+ const users = await db.table('users').select('*').execute();
50
+ console.log(users.rows);
51
+ ```
52
+
53
+ With Express.js
54
+
55
+ ```javascript
56
+ import express from 'express';
57
+ import { Database } from '@aetherframework/database';
58
+
59
+ const app = express();
60
+ const db = new Database({
61
+ connections: {
62
+ primary: {
63
+ type: 'mysql',
64
+ host: 'localhost',
65
+ user: 'root',
66
+ password: 'password',
67
+ database: 'myapp'
68
+ }
69
+ }
70
+ });
71
+
72
+ await db.init();
73
+
74
+ app.get('/users', async (req, res) => {
75
+ const users = await db.table('users').select('*').execute();
76
+ res.json(users.rows);
77
+ });
78
+
79
+ app.listen(3000, () => {
80
+ console.log('Server running with @aetherframework/database');
81
+ });
82
+ ```
83
+
84
+ With Fastify
85
+
86
+ ```javascript
87
+ import Fastify from 'fastify';
88
+ import { Database } from '@aetherframework/database';
89
+
90
+ const fastify = Fastify();
91
+ const db = new Database({
92
+ connections: {
93
+ primary: {
94
+ type: 'postgresql',
95
+ host: 'localhost',
96
+ user: 'postgres',
97
+ password: 'password',
98
+ database: 'myapp'
99
+ }
100
+ }
101
+ });
102
+
103
+ await db.init();
104
+
105
+ fastify.get('/users', async (request, reply) => {
106
+ const users = await db.table('users').select('*').execute();
107
+ return users.rows;
108
+ });
109
+
110
+ fastify.listen({ port: 3000 }, (err) => {
111
+ if (err) throw err;
112
+ console.log('Fastify server running with @aetherframework/database');
113
+ });
114
+ ```
115
+
116
+ With NestJS
117
+
118
+ ```javascript
119
+ // database.module.ts
120
+ import { Module } from '@nestjs/common';
121
+ import { Database } from '@aetherframework/database';
122
+
123
+ @Module({
124
+ providers: [
125
+ {
126
+ provide: 'DATABASE',
127
+ useFactory: async () => {
128
+ const db = new Database({
129
+ connections: {
130
+ primary: {
131
+ type: 'mysql',
132
+ host: 'localhost',
133
+ user: 'root',
134
+ password: 'password',
135
+ database: 'myapp'
136
+ }
137
+ }
138
+ });
139
+ await db.init();
140
+ return db;
141
+ }
142
+ }
143
+ ],
144
+ exports: ['DATABASE']
145
+ })
146
+ export class DatabaseModule {}
147
+
148
+ // users.service.ts
149
+ import { Injectable, Inject } from '@nestjs/common';
150
+
151
+ @Injectable()
152
+ export class UsersService {
153
+ constructor(@Inject('DATABASE') private db) {}
154
+
155
+ async findAll() {
156
+ return await this.db.table('users').select('*').execute();
157
+ }
158
+ }
159
+ ```
160
+
161
+ 📚 Basic Usage Guide
162
+
163
+ 1. Simple Configuration
164
+
165
+ ```javascript
166
+ import { Database } from '@aetherframework/database';
167
+
168
+ // Basic setup for a single database
169
+ const db = new Database({
170
+ connections: {
171
+ primary: {
172
+ type: 'sqlite', // or 'mysql', 'postgresql', 'mongodb', 'redis'
173
+ database: './data/myapp.db' // SQLite file path
174
+ }
175
+ }
176
+ });
177
+
178
+ await db.init();
179
+ ```
180
+
181
+ 2. Creating Tables
182
+
183
+ ```javascript
184
+ // Create a simple users table
185
+ await db.query(`
186
+ CREATE TABLE IF NOT EXISTS users (
187
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
188
+ name TEXT NOT NULL,
189
+ email TEXT UNIQUE NOT NULL,
190
+ age INTEGER,
191
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
192
+ )
193
+ `);
194
+ ```
195
+
196
+ 3. Basic CRUD Operations
197
+
198
+ Create (Insert)
199
+
200
+ ```javascript
201
+ // Insert a single record
202
+ const result = await db.table('users')
203
+ .insert({
204
+ name: 'John Doe',
205
+ email: 'john@example.com',
206
+ age: 30
207
+ })
208
+ .execute();
209
+
210
+ console.log(`Inserted user with ID: ${result.lastID}`);
211
+
212
+ // Insert multiple records
213
+ const batchResult = await db.table('users')
214
+ .insert([
215
+ { name: 'Alice', email: 'alice@example.com', age: 25 },
216
+ { name: 'Bob', email: 'bob@example.com', age: 35 },
217
+ { name: 'Charlie', email: 'charlie@example.com', age: 28 }
218
+ ])
219
+ .execute();
220
+
221
+ console.log(`Inserted ${batchResult.affectedRows} users`);
222
+ ```
223
+
224
+ Read (Select)
225
+
226
+ ```javascript
227
+ // Get all users
228
+ const allUsers = await db.table('users').select('*').execute();
229
+ console.log(`Total users: ${allUsers.rows.length}`);
230
+
231
+ // Get specific columns
232
+ const names = await db.table('users')
233
+ .select('id', 'name', 'email')
234
+ .execute();
235
+
236
+ // Get with conditions
237
+ const adults = await db.table('users')
238
+ .select('*')
239
+ .where('age', '>=', 18)
240
+ .execute();
241
+
242
+ // Get with multiple conditions
243
+ const activeUsers = await db.table('users')
244
+ .select('*')
245
+ .where('age', '>=', 18)
246
+ .where('status', '=', 'active')
247
+ .execute();
248
+
249
+ // Get with OR conditions
250
+ const specificUsers = await db.table('users')
251
+ .select('*')
252
+ .where('name', '=', 'John')
253
+ .orWhere('name', '=', 'Jane')
254
+ .execute();
255
+
256
+ // Get with ordering and limits
257
+ const recentUsers = await db.table('users')
258
+ .select('*')
259
+ .orderBy('created_at', 'desc')
260
+ .limit(10)
261
+ .execute();
262
+
263
+ // Get single record
264
+ const user = await db.table('users')
265
+ .where('id', '=', 1)
266
+ .first();
267
+ ```
268
+
269
+ Update
270
+
271
+ ```javascript
272
+ // Update single record
273
+ const updateResult = await db.table('users')
274
+ .where('id', '=', 1)
275
+ .update({
276
+ name: 'John Updated',
277
+ age: 31
278
+ })
279
+ .execute();
280
+
281
+ console.log(`Updated ${updateResult.affectedRows} user(s)`);
282
+
283
+ // Update multiple records
284
+ const bulkUpdate = await db.table('users')
285
+ .where('status', '=', 'inactive')
286
+ .update({ status: 'active' })
287
+ .execute();
288
+
289
+ // Increment/decrement values
290
+ await db.table('users')
291
+ .where('id', '=', 1)
292
+ .increment('login_count', 1)
293
+ .execute();
294
+
295
+ await db.table('users')
296
+ .where('id', '=', 2)
297
+ .decrement('balance', 100)
298
+ .execute();
299
+ ```
300
+
301
+ Delete
302
+
303
+ ```javascript
304
+ // Delete single record
305
+ const deleteResult = await db.table('users')
306
+ .where('id', '=', 1)
307
+ .delete()
308
+ .execute();
309
+
310
+ console.log(`Deleted ${deleteResult.affectedRows} user(s)`);
311
+
312
+ // Delete with conditions
313
+ await db.table('users')
314
+ .where('status', '=', 'banned')
315
+ .where('last_login', '<', new Date('2023-01-01'))
316
+ .delete()
317
+ .execute();
318
+ ```
319
+
320
+ 4. Working with Different Databases
321
+
322
+ MySQL
323
+
324
+ ```javascript
325
+ const mysqlDB = new Database({
326
+ connections: {
327
+ primary: {
328
+ type: 'mysql',
329
+ host: 'localhost',
330
+ port: 3306,
331
+ user: 'root',
332
+ password: 'password',
333
+ database: 'myapp',
334
+ charset: 'utf8mb4'
335
+ }
336
+ }
337
+ });
338
+ ```
339
+
340
+ PostgreSQL
341
+
342
+ ```javascript
343
+ const pgDB = new Database({
344
+ connections: {
345
+ primary: {
346
+ type: 'postgresql',
347
+ host: 'localhost',
348
+ port: 5432,
349
+ user: 'postgres',
350
+ password: 'password',
351
+ database: 'myapp',
352
+ ssl: false
353
+ }
354
+ }
355
+ });
356
+ ```
357
+
358
+ SQLite
359
+
360
+ ```javascript
361
+ const sqliteDB = new Database({
362
+ connections: {
363
+ primary: {
364
+ type: 'sqlite',
365
+ database: './data/app.db' // File path
366
+ // or ':memory:' for in-memory database
367
+ }
368
+ }
369
+ });
370
+ ```
371
+
372
+ MongoDB
373
+
374
+ ```javascript
375
+ const mongoDB = new Database({
376
+ connections: {
377
+ primary: {
378
+ type: 'mongodb',
379
+ host: 'localhost',
380
+ port: 27017,
381
+ database: 'myapp',
382
+ // Optional authentication
383
+ username: 'admin',
384
+ password: 'password'
385
+ }
386
+ }
387
+ });
388
+
389
+ // MongoDB specific operations
390
+ const users = await mongoDB.collection('users')
391
+ .find({ age: { $gt: 18 } })
392
+ .sort({ name: 1 })
393
+ .limit(10)
394
+ .execute();
395
+ ```
396
+
397
+ Redis
398
+
399
+ ```javascript
400
+ const redisDB = new Database({
401
+ connections: {
402
+ cache: {
403
+ type: 'redis',
404
+ host: 'localhost',
405
+ port: 6379,
406
+ // Optional authentication
407
+ password: 'password',
408
+ db: 0,
409
+ keyPrefix: 'myapp:'
410
+ }
411
+ }
412
+ });
413
+
414
+ // Redis operations
415
+ await redisDB.getConnection('cache').set('user:1', JSON.stringify(user));
416
+ const cachedUser = await redisDB.getConnection('cache').get('user:1');
417
+ ```
418
+
419
+ 5. Simple Joins and Relationships
420
+
421
+ ```javascript
422
+ // Basic join
423
+ const usersWithOrders = await db.table('users')
424
+ .select('users.*', 'orders.total_amount')
425
+ .join('orders', 'users.id', '=', 'orders.user_id')
426
+ .execute();
427
+
428
+ // Left join
429
+ const allUsersWithOrders = await db.table('users')
430
+ .select('users.*', 'orders.total_amount')
431
+ .leftJoin('orders', 'users.id', '=', 'orders.user_id')
432
+ .execute();
433
+
434
+ // Multiple joins
435
+ const detailedData = await db.table('users')
436
+ .select(
437
+ 'users.name',
438
+ 'orders.order_number',
439
+ 'products.name as product_name',
440
+ 'order_items.quantity'
441
+ )
442
+ .join('orders', 'users.id', '=', 'orders.user_id')
443
+ .join('order_items', 'orders.id', '=', 'order_items.order_id')
444
+ .join('products', 'order_items.product_id', '=', 'products.id')
445
+ .where('users.status', '=', 'active')
446
+ .execute();
447
+ ```
448
+
449
+ 6. Aggregation Functions
450
+
451
+ ```javascript
452
+ // Count records
453
+ const userCount = await db.table('users').count().execute();
454
+ console.log(`Total users: ${userCount.rows.count}`);
455
+
456
+ // Count with condition
457
+ const activeUsers = await db.table('users')
458
+ .where('status', '=', 'active')
459
+ .count()
460
+ .execute();
461
+
462
+ // Sum values
463
+ const totalSales = await db.table('orders')
464
+ .where('status', '=', 'completed')
465
+ .sum('amount')
466
+ .execute();
467
+
468
+ // Average values
469
+ const avgAge = await db.table('users').avg('age').execute();
470
+
471
+ // Minimum and maximum
472
+ const youngest = await db.table('users').min('age').execute();
473
+ const oldest = await db.table('users').max('age').execute();
474
+
475
+ // Group by
476
+ const salesByMonth = await db.table('orders')
477
+ .select(
478
+ db.raw('YEAR(created_at) as year'),
479
+ db.raw('MONTH(created_at) as month'),
480
+ db.raw('SUM(amount) as total_sales')
481
+ )
482
+ .where('status', '=', 'completed')
483
+ .groupBy('year', 'month')
484
+ .orderBy('year', 'desc')
485
+ .orderBy('month', 'desc')
486
+ .execute();
487
+ ```
488
+
489
+ 7. Simple Transactions
490
+
491
+ ```javascript
492
+ // Basic transaction
493
+ try {
494
+ const result = await db.transaction(async (trx) => {
495
+ // Insert user
496
+ const user = await trx.table('users')
497
+ .insert({
498
+ name: 'John',
499
+ email: 'john@example.com'
500
+ })
501
+ .execute();
502
+
503
+ // Insert user profile
504
+ await trx.table('profiles')
505
+ .insert({
506
+ user_id: user.lastID,
507
+ bio: 'Software Developer'
508
+ })
509
+ .execute();
510
+
511
+ return user;
512
+ });
513
+
514
+ console.log('Transaction completed:', result);
515
+ } catch (error) {
516
+ console.error('Transaction failed:', error);
517
+ }
518
+ ```
519
+
520
+ 8. Error Handling
521
+
522
+ ```javascript
523
+ try {
524
+ const result = await db.table('users')
525
+ .where('id', '=', 999)
526
+ .first();
527
+
528
+ if (!result) {
529
+ console.log('User not found');
530
+ }
531
+ } catch (error) {
532
+ console.error('Database error:', {
533
+ message: error.message,
534
+ code: error.code,
535
+ sql: error.sql,
536
+ params: error.params
537
+ });
538
+
539
+ // Handle specific error types
540
+ if (error.code === 'ER_DUP_ENTRY') {
541
+ console.log('Duplicate entry error');
542
+ } else if (error.code === 'ER_NO_SUCH_TABLE') {
543
+ console.log('Table does not exist');
544
+ }
545
+ }
546
+ ```
547
+
548
+ 9. Connection Management
549
+
550
+ ```javascript
551
+ // Check connection status
552
+ const health = await db.getAllHealthChecks();
553
+ console.log('Database health:', health);
554
+
555
+ // Get connection statistics
556
+ const stats = db.getMetrics();
557
+ console.log('Query statistics:', {
558
+ totalQueries: stats.totalQueries,
559
+ successfulQueries: stats.successfulQueries,
560
+ failedQueries: stats.failedQueries,
561
+ avgQueryTime: stats.avgQueryTime
562
+ });
563
+
564
+ // Close connections when done
565
+ await db.close();
566
+ console.log('Database connections closed');
567
+ ```
568
+
569
+ 🔧 Common Patterns
570
+
571
+ 1. Pagination
572
+
573
+ ```javascript
574
+ async function getUsers(page = 1, limit = 10) {
575
+ const offset = (page - 1) * limit;
576
+
577
+ const users = await db.table('users')
578
+ .select('*')
579
+ .orderBy('created_at', 'desc')
580
+ .limit(limit)
581
+ .offset(offset)
582
+ .execute();
583
+
584
+ const total = await db.table('users').count().execute();
585
+
586
+ return {
587
+ data: users.rows,
588
+ pagination: {
589
+ page,
590
+ limit,
591
+ total: total.rows.count,
592
+ pages: Math.ceil(total.rows.count / limit)
593
+ }
594
+ };
595
+ }
596
+ ```
597
+
598
+ 2. Search Functionality
599
+
600
+ ```javascript
601
+ async function searchUsers(query, filters = {}) {
602
+ let builder = db.table('users').select('*');
603
+
604
+ // Search in multiple fields
605
+ if (query) {
606
+ builder = builder.where(function(qb) {
607
+ qb.where('name', 'LIKE', `%${query}%`)
608
+ .orWhere('email', 'LIKE', `%${query}%`)
609
+ .orWhere('bio', 'LIKE', `%${query}%`);
610
+ });
611
+ }
612
+
613
+ // Apply filters
614
+ if (filters.status) {
615
+ builder = builder.where('status', '=', filters.status);
616
+ }
617
+
618
+ if (filters.minAge) {
619
+ builder = builder.where('age', '>=', filters.minAge);
620
+ }
621
+
622
+ if (filters.maxAge) {
623
+ builder = builder.where('age', '<=', filters.maxAge);
624
+ }
625
+
626
+ // Order and paginate
627
+ const result = await builder
628
+ .orderBy(filters.sortBy || 'created_at', filters.sortOrder || 'desc')
629
+ .limit(filters.limit || 20)
630
+ .offset(filters.offset || 0)
631
+ .execute();
632
+
633
+ return result.rows;
634
+ }
635
+ ```
636
+
637
+ 3. Batch Operations
638
+
639
+ ```javascript
640
+ // Batch insert with validation
641
+ async function batchCreateUsers(users) {
642
+ const validUsers = users.filter(user =>
643
+ user.name && user.email && user.age > 0
644
+ );
645
+
646
+ if (validUsers.length === 0) {
647
+ return { success: false, message: 'No valid users to insert' };
648
+ }
649
+
650
+ try {
651
+ const result = await db.table('users')
652
+ .insert(validUsers)
653
+ .execute();
654
+
655
+ return {
656
+ success: true,
657
+ inserted: result.affectedRows,
658
+ skipped: users.length - validUsers.length
659
+ };
660
+ } catch (error) {
661
+ console.error('Batch insert failed:', error);
662
+ return { success: false, error: error.message };
663
+ }
664
+ }
665
+ ```
666
+
667
+ ⚙️ Configuration Examples
668
+
669
+ Minimal Configuration
670
+
671
+ ```javascript
672
+ const minimalConfig = {
673
+ connections: {
674
+ primary: {
675
+ type: 'sqlite',
676
+ database: './data/app.db'
677
+ }
678
+ }
679
+ };
680
+ ```
681
+
682
+ Production Configuration
683
+
684
+ ```javascript
685
+ const productionConfig = {
686
+ enabled: true,
687
+ crossDb: true,
688
+ default: 'primary',
689
+
690
+ connections: {
691
+ primary: {
692
+ type: 'mysql',
693
+ host: process.env.DB_HOST,
694
+ port: parseInt(process.env.DB_PORT),
695
+ user: process.env.DB_USER,
696
+ password: process.env.DB_PASSWORD,
697
+ database: process.env.DB_NAME,
698
+ charset: 'utf8mb4',
699
+ timezone: '+00:00',
700
+ pool: {
701
+ min: 2,
702
+ max: 10,
703
+ idleTimeout: 30000,
704
+ acquireTimeout: 10000
705
+ }
706
+ },
707
+ cache: {
708
+ type: 'redis',
709
+ host: process.env.REDIS_HOST,
710
+ port: parseInt(process.env.REDIS_PORT),
711
+ password: process.env.REDIS_PASSWORD,
712
+ db: 0,
713
+ keyPrefix: 'app:'
714
+ }
715
+ },
716
+
717
+ driverModules: {
718
+ mysql: true,
719
+ redis: true,
720
+ sqlite: false,
721
+ postgres: false,
722
+ mongodb: false,
723
+ mssql: false,
724
+ oracle: false
725
+ },
726
+
727
+ middleware: {
728
+ queryLogger: {
729
+ enabled: process.env.NODE_ENV !== 'production',
730
+ logLevel: 'info',
731
+ slowQueryThreshold: 1000
732
+ },
733
+ connectionPool: {
734
+ enabled: true,
735
+ maxConnections: 10,
736
+ minConnections: 2
737
+ },
738
+ queryCache: {
739
+ enabled: true,
740
+ ttl: 300000
741
+ }
742
+ }
743
+ };
744
+ ```
745
+
746
+ 🔄 Migration from Other Libraries
747
+
748
+ From Knex.js
749
+
750
+ ```javascript
751
+ // Knex.js
752
+ knex('users').where('id', 1).first();
753
+
754
+ // @aetherframework/database
755
+ db.table('users').where('id', '=', 1).first();
756
+ ```
757
+
758
+ From Sequelize
759
+
760
+ ```javascript
761
+ // Sequelize
762
+ User.findAll({ where: { status: 'active' } });
763
+
764
+ // @aetherframework/database
765
+ db.table('users').where('status', '=', 'active').execute();
766
+ ```
767
+
768
+ From TypeORM
769
+
770
+ ```javascript
771
+ // TypeORM
772
+ userRepository.find({ where: { age: MoreThan(18) } });
773
+
774
+ // @aetherframework/database
775
+ db.table('users').where('age', '>', 18).execute();
776
+ ```
777
+
778
+ 🏆 Best Practices
779
+
780
+ 1. Always use parameterized queries - Prevents SQL injection
781
+ 2. Close connections when done - Prevents connection leaks
782
+ 3. Use transactions for multiple operations - Ensures data consistency
783
+ 4. Enable query logging in development - Helps with debugging
784
+ 5. Use connection pooling in production - Improves performance
785
+ 6. Implement proper error handling - Graceful degradation
786
+ 7. Use TypeScript for type safety - Catches errors at compile time
787
+
788
+ 🔧 Troubleshooting
789
+
790
+ Common Issues
791
+
792
+ 1. Connection refused
793
+ ```javascript
794
+ // Check your connection settings
795
+ const db = new Database({
796
+ connections: {
797
+ primary: {
798
+ type: 'mysql',
799
+ host: 'localhost', // Make sure this is correct
800
+ port: 3306, // Default MySQL port
801
+ user: 'root', // Check username
802
+ password: 'password', // Check password
803
+ database: 'myapp' // Database must exist
804
+ }
805
+ }
806
+ });
807
+ ```
808
+
809
+ 2. Table doesn't exist
810
+ ```javascript
811
+ // Create the table first
812
+ await db.query(`
813
+ CREATE TABLE IF NOT EXISTS users (
814
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
815
+ name TEXT NOT NULL
816
+ )
817
+ `);
818
+ ```
819
+
820
+ 3. Slow queries
821
+ ```javascript
822
+ // Enable query logging to identify slow queries
823
+ const db = new Database({
824
+ middleware: {
825
+ queryLogger: {
826
+ enabled: true,
827
+ slowQueryThreshold: 100 // Log queries slower than 100ms
828
+ }
829
+ }
830
+ });
831
+ ```
832
+
833
+ 🚀 Next Steps
834
+
835
+ Once you're comfortable with the basics, explore these advanced features:
836
+
837
+ 1. Query Caching - Improve performance with built-in caching
838
+ 2. Performance Monitoring - Track and optimize query performance
839
+ 3. Database Migrations - Version control for your database schema
840
+ 4. Multiple Database Connections - Work with different databases simultaneously
841
+ 5. Custom Drivers - Extend support for other database systems
842
+
843
+
844
+ 📄 License
845
+
846
+ MIT © AetherJS Team