@aetherframework/database 1.0.9 → 1.1.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.
Files changed (44) hide show
  1. package/package.json +1 -2
  2. package/src/DatabaseManager.js +0 -565
  3. package/src/core/ConnectionManager.js +0 -351
  4. package/src/core/DatabaseFactory.js +0 -188
  5. package/src/core/MongoQueryBuilder.js +0 -576
  6. package/src/core/PluginManager.js +0 -968
  7. package/src/core/QueryBuilder.js +0 -4398
  8. package/src/core/TransactionManager.js +0 -40
  9. package/src/drivers/clickhouse-driver.js +0 -272
  10. package/src/drivers/index.js +0 -273
  11. package/src/drivers/mongodb-driver.js +0 -87
  12. package/src/drivers/mssql-driver.js +0 -117
  13. package/src/drivers/mysql-driver.js +0 -169
  14. package/src/drivers/oracle-driver.js +0 -101
  15. package/src/drivers/postgres-driver.js +0 -234
  16. package/src/drivers/redis-driver.js +0 -52
  17. package/src/drivers/sqlite-driver.js +0 -67
  18. package/src/middleware/connection-pool.js +0 -455
  19. package/src/middleware/performance-monitor.js +0 -652
  20. package/src/middleware/query-cache.js +0 -500
  21. package/src/middleware/query-logger.js +0 -262
  22. package/src/plugins/AuditPlugin.js +0 -447
  23. package/src/plugins/BasePlugin.js +0 -418
  24. package/src/plugins/BatchOperationPlugin.js +0 -165
  25. package/src/plugins/CachePlugin.js +0 -407
  26. package/src/plugins/CtePlugin.js +0 -523
  27. package/src/plugins/DistributedPlugin.js +0 -543
  28. package/src/plugins/EncryptionPlugin.js +0 -211
  29. package/src/plugins/FullTextSearchPlugin.js +0 -164
  30. package/src/plugins/GeospatialPlugin.js +0 -219
  31. package/src/plugins/GraphQLPlugin.js +0 -162
  32. package/src/plugins/HookPlugin.js +0 -211
  33. package/src/plugins/JsonPlugin.js +0 -366
  34. package/src/plugins/OptimisticLockPlugin.js +0 -374
  35. package/src/plugins/PerformancePlugin.js +0 -175
  36. package/src/plugins/ResiliencePlugin.js +0 -114
  37. package/src/plugins/ShardingPlugin.js +0 -227
  38. package/src/plugins/SoftDeletePlugin.js +0 -258
  39. package/src/plugins/SyncPlugin.js +0 -373
  40. package/src/plugins/VersioningPlugin.js +0 -314
  41. package/src/plugins/WindowFunctionPlugin.js +0 -343
  42. package/src/utils/config-loader.js +0 -632
  43. package/src/utils/error-handler.js +0 -724
  44. package/src/utils/migration-runner.js +0 -1066
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aetherframework/database",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "Zero-dependency, multi-database integration for AetherJS API framework with advanced query builder and connection pooling",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -48,7 +48,6 @@
48
48
  "connection-pool.js",
49
49
  "query-builder.js",
50
50
  "drivers/",
51
- "src/",
52
51
  "types.js",
53
52
  "README.md",
54
53
  "LICENSE"
@@ -1,565 +0,0 @@
1
- /**
2
- * @license MIT
3
- * Copyright (c) 2026-present AetherFramework Contributors.
4
- * SPDX-License-Identifier: MIT
5
- * @module @aetherframework/src/DatabaseManager
6
- */
7
- import { getDriver } from "./drivers/index.js";
8
- import ConnectionManager from "./core/ConnectionManager.js";
9
- import TransactionManager from "./core/TransactionManager.js";
10
- import QueryBuilder from "./core/QueryBuilder.js";
11
- import MongoQueryBuilder from "./core/MongoQueryBuilder.js";
12
- import { PluginManager } from "./core/PluginManager.js";
13
-
14
- // Import all plugins
15
- import { CachePlugin } from "./plugins/CachePlugin.js";
16
- // import { AuditPlugin } from "./plugins/AuditPlugin.js";
17
- import { EncryptionPlugin } from "./plugins/EncryptionPlugin.js";
18
- import { SyncPlugin } from "./plugins/SyncPlugin.js";
19
- import { HookPlugin } from "./plugins/HookPlugin.js";
20
- import { OptimisticLockPlugin } from "./plugins/OptimisticLockPlugin.js";
21
- import { SoftDeletePlugin } from "./plugins/SoftDeletePlugin.js";
22
- import { ShardingPlugin } from "./plugins/ShardingPlugin.js";
23
- import { VersioningPlugin } from "./plugins/VersioningPlugin.js";
24
- import { JsonPlugin } from "./plugins/JsonPlugin.js";
25
- import { PerformancePlugin } from "./plugins/PerformancePlugin.js";
26
- import { GraphQLPlugin } from "./plugins/GraphQLPlugin.js";
27
- import { ResiliencePlugin } from "./plugins/ResiliencePlugin.js";
28
- import { BatchOperationPlugin } from "./plugins/BatchOperationPlugin.js";
29
- import { CtePlugin } from "./plugins/CtePlugin.js";
30
- import { WindowFunctionPlugin } from "./plugins/WindowFunctionPlugin.js";
31
- import { FullTextSearchPlugin } from "./plugins/FullTextSearchPlugin.js";
32
- import { GeospatialPlugin } from "./plugins/GeospatialPlugin.js";
33
- import { DistributedPlugin } from "./plugins/DistributedPlugin.js";
34
-
35
- /**
36
- * DatabaseManager - Main database management class with comprehensive plugin support
37
- * Manages database connections, transactions, and plugin integration
38
- */
39
- class DatabaseManager {
40
- /**
41
- * Constructor for DatabaseManager
42
- * @param {Object} config - Configuration object
43
- * @param {Object} config.connections - Database connections configuration
44
- * @param {string} config.default - Default connection name
45
- * @param {Object} config.plugins - Plugins configuration
46
- * @param {Object} config.pluginManager - Plugin manager configuration
47
- */
48
- constructor(config = {}) {
49
- this.config = config;
50
- this.connections = {};
51
- this.connectionManagers = {};
52
- this.transactionManagers = {};
53
- this.isInitialized = false;
54
- this.pluginManager = new PluginManager();
55
- }
56
-
57
- /**
58
- * Initialize DatabaseManager with connections and plugins
59
- * @returns {Promise<DatabaseManager>} Initialized DatabaseManager instance
60
- */
61
- async init() {
62
- if (this.isInitialized) return this;
63
- const {
64
- connections = {},
65
- default: defaultConnection = "primary",
66
- plugins = {},
67
- pluginManager = {}
68
- } = this.config;
69
-
70
- // Initialize plugin manager
71
- this.pluginManager.initialize(pluginManager);
72
-
73
- // Initialize plugins if configured
74
- if (plugins.enabled !== false) {
75
- this._initializePlugins(plugins);
76
- }
77
-
78
- // Initialize database connections
79
- for (const [name, connectionConfig] of Object.entries(connections)) {
80
- if (connectionConfig.enabled === false) {
81
- continue;
82
- }
83
-
84
- try {
85
- const DriverClass = await getDriver(connectionConfig.type);
86
- if (!DriverClass) {
87
- throw new Error(`Unsupported database type: ${connectionConfig.type}`);
88
- }
89
-
90
- const driver = new DriverClass(connectionConfig);
91
- const connectionManager = new ConnectionManager(driver, connectionConfig);
92
-
93
- await connectionManager.connect();
94
-
95
- const transactionManager = new TransactionManager(connectionManager, connectionConfig.type);
96
-
97
- this.connectionManagers[name] = connectionManager;
98
- this.transactionManagers[name] = transactionManager;
99
- this.connections[name] = connectionManager.connection;
100
-
101
- } catch (error) {
102
- throw error;
103
- }
104
- }
105
-
106
- if (!this.connectionManagers[defaultConnection]) {
107
- throw new Error(`Default connection "${defaultConnection}" not found`);
108
- }
109
-
110
- this.defaultConnectionName = defaultConnection;
111
- this.defaultConnectionManager = this.connectionManagers[defaultConnection];
112
- this.defaultTransactionManager = this.transactionManagers[defaultConnection];
113
-
114
- this.isInitialized = true;
115
- return this;
116
- }
117
-
118
- /**
119
- * Initialize all plugins based on configuration
120
- * @param {Object} pluginsConfig - Plugins configuration
121
- * @private
122
- */
123
- _initializePlugins(pluginsConfig) {
124
- // Core plugins
125
- const corePlugins = {
126
- cache: CachePlugin,
127
- // audit: AuditPlugin,
128
- encryption: EncryptionPlugin,
129
- sync: SyncPlugin,
130
- hook: HookPlugin,
131
- optimisticLock: OptimisticLockPlugin,
132
- softDelete: SoftDeletePlugin,
133
- sharding: ShardingPlugin,
134
- versioning: VersioningPlugin,
135
- json: JsonPlugin,
136
- };
137
-
138
- // Advanced plugins
139
- const advancedPlugins = {
140
- performance: PerformancePlugin,
141
- graphql: GraphQLPlugin,
142
- resilience: ResiliencePlugin,
143
- batch: BatchOperationPlugin,
144
- cte: CtePlugin,
145
- window: WindowFunctionPlugin,
146
- fullTextSearch: FullTextSearchPlugin,
147
- geospatial: GeospatialPlugin,
148
- distributed: DistributedPlugin,
149
- };
150
-
151
- // Register core plugins
152
- for (const [name, PluginClass] of Object.entries(corePlugins)) {
153
- if (pluginsConfig[name] !== false) {
154
- this.pluginManager.register(name, PluginClass, {
155
- enabled: true,
156
- priority: 100,
157
- config: pluginsConfig[name] || {},
158
- });
159
- }
160
- }
161
-
162
- // Register advanced plugins
163
- for (const [name, PluginClass] of Object.entries(advancedPlugins)) {
164
- if (pluginsConfig[name] !== false) {
165
- this.pluginManager.register(name, PluginClass, {
166
- enabled: true,
167
- priority: 90,
168
- config: pluginsConfig[name] || {},
169
- });
170
- }
171
- }
172
-
173
- // Initialize all registered plugins
174
- this.pluginManager.initializeAll();
175
- }
176
-
177
- /**
178
- * Get QueryBuilder with all plugins attached
179
- * @param {string} tableName - Table name
180
- * @param {string} connectionName - Connection name (optional)
181
- * @returns {QueryBuilder} QueryBuilder instance with all plugins
182
- */
183
- table(tableName, connectionName = this.defaultConnectionName) {
184
- if (!this.isInitialized) {
185
- throw new Error("DatabaseManager must be initialized before use");
186
- }
187
-
188
- const connectionManager = this.getConnectionManager(connectionName);
189
-
190
- const driver =
191
- typeof connectionManager.getDriver === "function"
192
- ? connectionManager.getDriver()
193
- : null;
194
-
195
- const dialect =
196
- typeof connectionManager.getDialect === "function"
197
- ? connectionManager.getDialect()
198
- : connectionManager.type || "mysql";
199
-
200
- // Create QueryBuilder instance
201
- const qb = new QueryBuilder(tableName, driver, dialect);
202
-
203
- // Attach all plugins to QueryBuilder
204
- this._attachAllPluginsToQueryBuilder(qb, connectionManager);
205
-
206
- // Unified execute method - all SELECT queries return array
207
- qb.execute = async () => {
208
- let sql = "";
209
- let bindings = [];
210
-
211
- if (typeof qb.toSQL === "function") {
212
- const result = qb.toSQL();
213
- sql =
214
- typeof result === "string"
215
- ? result
216
- : result.sql || result.query || "";
217
- bindings = Array.isArray(result?.bindings)
218
- ? result.bindings
219
- : qb.getBindings?.() || qb.bindings || [];
220
- } else if (typeof qb.build === "function") {
221
- sql = qb.build();
222
- bindings = qb.getBindings?.() || qb.bindings || [];
223
- }
224
-
225
- if (!sql) {
226
- throw new Error("QueryBuilder: Unable to generate SQL statement");
227
- }
228
-
229
- const sqlUpper = String(sql).trim().toUpperCase();
230
- const isSelect =
231
- qb.type === "select" ||
232
- (typeof qb.isSelect === "function" && qb.isSelect()) ||
233
- sqlUpper.startsWith("SELECT") ||
234
- sqlUpper.startsWith("SHOW");
235
-
236
- const result = isSelect
237
- ? await connectionManager.query(sql, bindings)
238
- : await connectionManager.execute(sql, bindings);
239
-
240
- // Key: SELECT queries uniformly return array
241
- if (isSelect) {
242
- return Array.isArray(result) ? result : result.rows || result;
243
- }
244
-
245
- return result; // INSERT/UPDATE/DELETE return original result object
246
- };
247
-
248
- return qb;
249
- }
250
-
251
- /**
252
- * Attach all plugins to QueryBuilder instance
253
- * @param {QueryBuilder} qb - QueryBuilder instance
254
- * @param {ConnectionManager} connectionManager - Connection manager
255
- * @private
256
- */
257
- _attachAllPluginsToQueryBuilder(qb, connectionManager) {
258
- // Get all enabled plugins from plugin manager
259
- const enabledPlugins = this.pluginManager.getEnabledPlugins();
260
-
261
- // Attach each plugin to QueryBuilder
262
- for (const [pluginName, pluginClass] of Object.entries(enabledPlugins)) {
263
- try {
264
- const pluginInstance = new pluginClass(qb);
265
- pluginInstance.init();
266
-
267
- // Store plugin reference on QueryBuilder
268
- qb[`${pluginName}Plugin`] = pluginInstance;
269
-
270
- } catch (error) {
271
- console.error(`❌ Failed to attach ${pluginName} plugin:`, error.message);
272
- }
273
- }
274
- }
275
-
276
- /**
277
- * Get connection manager by name
278
- * @param {string} name - Connection name
279
- * @returns {ConnectionManager} Connection manager instance
280
- */
281
- getConnectionManager(name = this.defaultConnectionName) {
282
- const manager = this.connectionManagers[name];
283
- if (!manager) throw new Error(`Connection "${name}" not found`);
284
- return manager;
285
- }
286
-
287
- /**
288
- * Get transaction manager by name
289
- * @param {string} name - Connection name
290
- * @returns {TransactionManager} Transaction manager instance
291
- */
292
- getTransactionManager(name = this.defaultConnectionName) {
293
- const manager = this.transactionManagers[name];
294
- if (!manager)
295
- throw new Error(`Transaction manager for "${name}" not found`);
296
- return manager;
297
- }
298
-
299
- /**
300
- * Execute raw SQL query
301
- * @param {string} sql - SQL query
302
- * @param {Array} params - Query parameters
303
- * @param {string} connectionName - Connection name
304
- * @returns {Promise} Query result
305
- */
306
- async query(sql, params = [], connectionName) {
307
- const manager = this.getConnectionManager(connectionName);
308
- return await manager.query(sql, params);
309
- }
310
-
311
- /**
312
- * Execute raw SQL statement
313
- * @param {string} sql - SQL statement
314
- * @param {Array} params - Statement parameters
315
- * @param {string} connectionName - Connection name
316
- * @returns {Promise} Execution result
317
- */
318
- async execute(sql, params = [], connectionName) {
319
- const manager = this.getConnectionManager(connectionName);
320
- return await manager.execute(sql, params);
321
- }
322
-
323
- /**
324
- * Execute transaction
325
- * @param {Function} callback - Transaction callback
326
- * @param {string} connectionName - Connection name
327
- * @returns {Promise} Transaction result
328
- */
329
- async transaction(callback, connectionName = this.defaultConnectionName) {
330
- const manager = this.getTransactionManager(connectionName);
331
- return await manager.transaction(callback);
332
- }
333
-
334
- /**
335
- * Close all database connections
336
- * @returns {Promise<void>}
337
- */
338
- async close() {
339
- for (const [name, manager] of Object.entries(this.connectionManagers)) {
340
- try {
341
- await manager.close();
342
- } catch (e) {
343
- console.error(`❌ Failed to close ${name}:`, e.message);
344
- }
345
- }
346
- this.isInitialized = false;
347
- }
348
-
349
- /**
350
- * Health check for all connections
351
- * @returns {Promise<Object>} Health status for each connection
352
- */
353
- async healthCheck() {
354
- const health = {};
355
- for (const [name, manager] of Object.entries(this.connectionManagers)) {
356
- try {
357
- health[name] = await manager.healthCheck();
358
- } catch (error) {
359
- health[name] = { status: "error", error: error.message };
360
- }
361
- }
362
- return health;
363
- }
364
-
365
- /**
366
- * Get metrics for all connections
367
- * @returns {Object} Connection metrics
368
- */
369
- getMetrics() {
370
- const metrics = {};
371
- for (const [name, manager] of Object.entries(this.connectionManagers)) {
372
- metrics[name] = manager.getMetrics?.() || {};
373
- }
374
- return metrics;
375
- }
376
-
377
- /**
378
- * Get plugin manager instance
379
- * @returns {PluginManager} Plugin manager instance
380
- */
381
- getPluginManager() {
382
- return this.pluginManager;
383
- }
384
-
385
- /**
386
- * Register custom plugin
387
- * @param {string} name - Plugin name
388
- * @param {BasePlugin} pluginClass - Plugin class
389
- * @param {Object} options - Plugin options
390
- * @returns {DatabaseManager} DatabaseManager instance for chaining
391
- */
392
- registerPlugin(name, pluginClass, options = {}) {
393
- if (!pluginClass || typeof pluginClass !== 'function') {
394
- throw new Error("Plugin must be a class constructor");
395
- }
396
-
397
- this.pluginManager.register(name, pluginClass, options);
398
- return this;
399
- }
400
-
401
- /**
402
- * Enable specific plugin
403
- * @param {string} pluginName - Plugin name
404
- * @param {Object} options - Plugin options
405
- * @returns {DatabaseManager} DatabaseManager instance for chaining
406
- */
407
- enablePlugin(pluginName, options = {}) {
408
- this.pluginManager.enable(pluginName, options);
409
- return this;
410
- }
411
-
412
- /**
413
- * Disable specific plugin
414
- * @param {string} pluginName - Plugin name
415
- * @returns {DatabaseManager} DatabaseManager instance for chaining
416
- */
417
- disablePlugin(pluginName) {
418
- this.pluginManager.disable(pluginName);
419
- return this;
420
- }
421
-
422
- /**
423
- * Unregister plugin
424
- * @param {string} pluginName - Plugin name
425
- * @returns {DatabaseManager} DatabaseManager instance for chaining
426
- */
427
- unregisterPlugin(pluginName) {
428
- this.pluginManager.unregister(pluginName);
429
- return this;
430
- }
431
-
432
- /**
433
- * Get plugin by name
434
- * @param {string} pluginName - Plugin name
435
- * @returns {BasePlugin|null} Plugin instance or null
436
- */
437
- getPlugin(pluginName) {
438
- return this.pluginManager.get(pluginName);
439
- }
440
-
441
- /**
442
- * Get all registered plugins
443
- * @returns {Object} All registered plugins
444
- */
445
- getPlugins() {
446
- return this.pluginManager.getAll();
447
- }
448
-
449
- /**
450
- * Get enabled plugins
451
- * @returns {Array} Enabled plugins
452
- */
453
- getEnabledPlugins() {
454
- return this.pluginManager.getEnabled();
455
- }
456
-
457
- /**
458
- * Check if plugin is enabled
459
- * @param {string} pluginName - Plugin name
460
- * @returns {boolean} True if plugin is enabled
461
- */
462
- isPluginEnabled(pluginName) {
463
- return this.pluginManager.isEnabled(pluginName);
464
- }
465
-
466
- /**
467
- * Get plugin information
468
- * @param {string} pluginName - Plugin name
469
- * @returns {Object} Plugin information
470
- */
471
- getPluginInfo(pluginName) {
472
- return this.pluginManager.getPluginInfo(pluginName);
473
- }
474
-
475
- /**
476
- * Get plugin status
477
- * @returns {Object} Plugin status
478
- */
479
- getPluginStatus() {
480
- return this.pluginManager.getStatus();
481
- }
482
-
483
- /**
484
- * Load plugin configuration
485
- * @param {Object} config - Plugin configuration
486
- * @returns {DatabaseManager} DatabaseManager instance for chaining
487
- */
488
- loadPluginConfig(config) {
489
- this.pluginManager.loadConfig(config);
490
- return this;
491
- }
492
-
493
- /**
494
- * Save plugin configuration
495
- * @returns {Object} Plugin configuration
496
- */
497
- savePluginConfig() {
498
- return this.pluginManager.saveConfig();
499
- }
500
-
501
- /**
502
- * Hot reload plugin
503
- * @param {string} pluginName - Plugin name
504
- * @param {BasePlugin} newPluginClass - New plugin class
505
- * @returns {DatabaseManager} DatabaseManager instance for chaining
506
- */
507
- hotReloadPlugin(pluginName, newPluginClass) {
508
- this.pluginManager.hotReload(pluginName, newPluginClass);
509
- return this;
510
- }
511
-
512
- /**
513
- * Check plugin dependencies
514
- * @param {string} pluginName - Plugin name
515
- * @returns {Object} Dependency check result
516
- */
517
- checkPluginDependencies(pluginName) {
518
- return this.pluginManager.checkDependencies(pluginName);
519
- }
520
-
521
- /**
522
- * Get plugin dependency graph
523
- * @returns {Object} Dependency graph
524
- */
525
- getPluginDependencyGraph() {
526
- return this.pluginManager.getDependencyGraph();
527
- }
528
-
529
- /**
530
- * Validate plugin
531
- * @param {BasePlugin} pluginClass - Plugin class
532
- * @returns {Object} Validation result
533
- */
534
- validatePlugin(pluginClass) {
535
- return this.pluginManager.validatePlugin(pluginClass);
536
- }
537
-
538
- /**
539
- * Register all plugins at once
540
- * @param {Array} plugins - Array of plugin configurations
541
- * @returns {DatabaseManager} DatabaseManager instance for chaining
542
- */
543
- registerAllPlugins(plugins) {
544
- this.pluginManager.registerAll(plugins);
545
- return this;
546
- }
547
-
548
- /**
549
- * Get plugins by priority
550
- * @returns {Array} Plugins sorted by priority
551
- */
552
- getPluginsByPriority() {
553
- return this.pluginManager.getPluginsByPriority();
554
- }
555
-
556
- /**
557
- * Cleanup plugin system
558
- * @returns {Promise<void>}
559
- */
560
- async cleanupPlugins() {
561
- await this.pluginManager.cleanup();
562
- }
563
- }
564
-
565
- export default DatabaseManager;