noormme 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -65
- package/dist/cjs/agentic/ActionJournal.js +13 -9
- package/dist/cjs/agentic/CapabilityManager.js +35 -21
- package/dist/cjs/agentic/CognitiveRepository.js +19 -9
- package/dist/cjs/agentic/ContextBuffer.js +24 -12
- package/dist/cjs/agentic/Cortex.js +11 -4
- package/dist/cjs/agentic/EpisodicMemory.js +7 -5
- package/dist/cjs/agentic/PersonaManager.js +16 -8
- package/dist/cjs/agentic/PolicyEnforcer.js +31 -12
- package/dist/cjs/agentic/ResourceMonitor.js +4 -4
- package/dist/cjs/agentic/SessionCompressor.js +22 -14
- package/dist/cjs/agentic/SessionManager.js +36 -18
- package/dist/cjs/agentic/VectorIndexer.js +22 -18
- package/dist/cjs/agentic/improvement/AblationEngine.js +22 -15
- package/dist/cjs/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/cjs/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/cjs/agentic/improvement/CortexJanitor.js +30 -9
- package/dist/cjs/agentic/improvement/CuriosityEngine.js +27 -23
- package/dist/cjs/agentic/improvement/EvolutionRitual.js +4 -4
- package/dist/cjs/agentic/improvement/EvolutionaryPilot.js +16 -6
- package/dist/cjs/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/cjs/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/cjs/agentic/improvement/GovernanceManager.js +19 -11
- package/dist/cjs/agentic/improvement/HiveLink.js +22 -15
- package/dist/cjs/agentic/improvement/KnowledgeDistiller.js +48 -32
- package/dist/cjs/agentic/improvement/RecursiveReasoner.js +40 -17
- package/dist/cjs/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/cjs/agentic/improvement/RitualOrchestrator.js +28 -22
- package/dist/cjs/agentic/improvement/RuleEngine.js +22 -17
- package/dist/cjs/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/cjs/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/cjs/agentic/improvement/SkillSynthesizer.js +42 -27
- package/dist/cjs/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/cjs/agentic/improvement/StrategicPlanner.js +120 -55
- package/dist/cjs/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/cjs/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/cjs/agentic/telemetry/ResearchAlchemist.js +5 -2
- package/dist/cjs/cache/cache-manager.js +7 -4
- package/dist/cjs/cli/commands/analyze.js +5 -4
- package/dist/cjs/cli/commands/generate.js +81 -44
- package/dist/cjs/cli/commands/init.js +7 -3
- package/dist/cjs/cli/commands/inspect.js +139 -36
- package/dist/cjs/cli/commands/migrate.js +5 -4
- package/dist/cjs/cli/commands/optimize.js +4 -4
- package/dist/cjs/cli/commands/status.js +9 -7
- package/dist/cjs/cli/commands/watch.js +7 -6
- package/dist/cjs/cli/index.js +2 -2
- package/dist/cjs/cli/ui/spinner.d.ts +15 -0
- package/dist/cjs/cli/ui/spinner.js +76 -0
- package/dist/cjs/dialect/database-introspector.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/cjs/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/cjs/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/cjs/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/cjs/edge-runtime/edge-config.js +21 -19
- package/dist/cjs/errors/NoormError.js +22 -20
- package/dist/cjs/helpers/agent-schema.js +2 -0
- package/dist/cjs/helpers/postgresql.js +7 -4
- package/dist/cjs/helpers/schema-evolution.js +31 -6
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/logging/logger.js +8 -4
- package/dist/cjs/migration/data_migrator.js +12 -11
- package/dist/cjs/migration/database_migration_manager.js +17 -13
- package/dist/cjs/migration/schema_differ.js +22 -14
- package/dist/cjs/migration/schema_introspector.js +8 -8
- package/dist/cjs/migration/type_mapper.js +68 -67
- package/dist/cjs/noormme.js +52 -37
- package/dist/cjs/performance/index.js +5 -5
- package/dist/cjs/performance/query-optimizer.js +26 -21
- package/dist/cjs/performance/services/cache-service.js +26 -16
- package/dist/cjs/performance/services/connection-factory.js +28 -23
- package/dist/cjs/performance/services/metrics-collector.js +41 -36
- package/dist/cjs/performance/utils/query-parser.js +15 -16
- package/dist/cjs/relationships/relationship-engine.js +10 -8
- package/dist/cjs/repository/repository-factory.js +97 -38
- package/dist/cjs/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/cjs/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/cjs/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/cjs/schema/core/discovery/view-discovery.js +5 -4
- package/dist/cjs/schema/core/factories/discovery-factory.js +4 -4
- package/dist/cjs/schema/core/utils/name-generator.js +14 -5
- package/dist/cjs/schema/core/utils/type-mapper.js +24 -24
- package/dist/cjs/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/cjs/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/cjs/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/cjs/schema/test/basic-schema-test.js +11 -9
- package/dist/cjs/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/cjs/schema/test/discovery-factory.test.js +2 -2
- package/dist/cjs/schema/test/error-handling.test.js +8 -6
- package/dist/cjs/schema/test/integration.test.js +24 -18
- package/dist/cjs/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/cjs/schema/test/simple-schema-test.js +9 -9
- package/dist/cjs/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/cjs/schema/test/test-runner.js +3 -3
- package/dist/cjs/sqlite-migration/index.d.ts +2 -2
- package/dist/cjs/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/cjs/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/cjs/testing/test-utils.js +36 -34
- package/dist/cjs/types/index.d.ts +5 -2
- package/dist/cjs/types/index.js +6 -3
- package/dist/cjs/types/type-generator.js +46 -42
- package/dist/cjs/util/safe-sql-helpers.js +1 -1
- package/dist/cjs/util/security-validator.js +20 -9
- package/dist/cjs/utils/errorHelpers.js +20 -10
- package/dist/cjs/watch/schema-watcher.js +22 -23
- package/dist/esm/agentic/ActionJournal.js +13 -9
- package/dist/esm/agentic/CapabilityManager.js +35 -21
- package/dist/esm/agentic/CognitiveRepository.js +19 -9
- package/dist/esm/agentic/ContextBuffer.js +24 -12
- package/dist/esm/agentic/Cortex.js +11 -4
- package/dist/esm/agentic/EpisodicMemory.js +7 -5
- package/dist/esm/agentic/PersonaManager.js +16 -8
- package/dist/esm/agentic/PolicyEnforcer.js +31 -12
- package/dist/esm/agentic/ResourceMonitor.js +4 -4
- package/dist/esm/agentic/SessionCompressor.js +22 -14
- package/dist/esm/agentic/SessionManager.js +36 -18
- package/dist/esm/agentic/VectorIndexer.js +22 -18
- package/dist/esm/agentic/improvement/AblationEngine.js +22 -15
- package/dist/esm/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/esm/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/esm/agentic/improvement/CortexJanitor.js +30 -9
- package/dist/esm/agentic/improvement/CuriosityEngine.js +27 -23
- package/dist/esm/agentic/improvement/EvolutionRitual.js +4 -4
- package/dist/esm/agentic/improvement/EvolutionaryPilot.js +16 -6
- package/dist/esm/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/esm/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/esm/agentic/improvement/GovernanceManager.js +19 -11
- package/dist/esm/agentic/improvement/HiveLink.js +22 -15
- package/dist/esm/agentic/improvement/KnowledgeDistiller.js +48 -32
- package/dist/esm/agentic/improvement/RecursiveReasoner.js +40 -17
- package/dist/esm/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/esm/agentic/improvement/RitualOrchestrator.js +28 -22
- package/dist/esm/agentic/improvement/RuleEngine.js +22 -17
- package/dist/esm/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/esm/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/esm/agentic/improvement/SkillSynthesizer.js +42 -27
- package/dist/esm/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/esm/agentic/improvement/StrategicPlanner.js +120 -55
- package/dist/esm/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/esm/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/esm/agentic/telemetry/ResearchAlchemist.js +5 -2
- package/dist/esm/cache/cache-manager.js +7 -4
- package/dist/esm/cli/commands/analyze.js +5 -4
- package/dist/esm/cli/commands/generate.js +82 -45
- package/dist/esm/cli/commands/init.js +8 -4
- package/dist/esm/cli/commands/inspect.js +140 -37
- package/dist/esm/cli/commands/migrate.js +5 -4
- package/dist/esm/cli/commands/optimize.js +4 -4
- package/dist/esm/cli/commands/status.js +9 -7
- package/dist/esm/cli/commands/watch.js +7 -6
- package/dist/esm/cli/index.js +2 -2
- package/dist/esm/cli/ui/spinner.d.ts +15 -0
- package/dist/esm/cli/ui/spinner.js +70 -0
- package/dist/esm/dialect/database-introspector.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/esm/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/esm/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/esm/dynamic/dynamic.js +1 -1
- package/dist/esm/edge-runtime/edge-config.js +21 -19
- package/dist/esm/errors/NoormError.js +22 -20
- package/dist/esm/helpers/agent-schema.js +2 -0
- package/dist/esm/helpers/postgresql.js +7 -4
- package/dist/esm/helpers/schema-evolution.js +31 -6
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +2 -2
- package/dist/esm/logging/logger.js +8 -4
- package/dist/esm/migration/data_migrator.js +12 -11
- package/dist/esm/migration/database_migration_manager.js +18 -14
- package/dist/esm/migration/schema_differ.js +22 -14
- package/dist/esm/migration/schema_introspector.js +8 -8
- package/dist/esm/migration/type_mapper.js +68 -67
- package/dist/esm/noormme.js +52 -37
- package/dist/esm/performance/index.js +5 -5
- package/dist/esm/performance/query-optimizer.js +26 -21
- package/dist/esm/performance/services/cache-service.js +26 -16
- package/dist/esm/performance/services/connection-factory.js +28 -23
- package/dist/esm/performance/services/metrics-collector.js +41 -36
- package/dist/esm/performance/utils/query-parser.js +15 -16
- package/dist/esm/raw-builder/sql.js +1 -1
- package/dist/esm/relationships/relationship-engine.js +10 -8
- package/dist/esm/repository/repository-factory.js +98 -39
- package/dist/esm/schema/builders/alter-table-add-index-builder.js +1 -1
- package/dist/esm/schema/builders/create-index-builder.js +2 -2
- package/dist/esm/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/esm/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/esm/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/esm/schema/core/discovery/view-discovery.js +5 -4
- package/dist/esm/schema/core/factories/discovery-factory.js +4 -4
- package/dist/esm/schema/core/utils/name-generator.js +14 -5
- package/dist/esm/schema/core/utils/type-mapper.js +24 -24
- package/dist/esm/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/esm/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/esm/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/esm/schema/test/basic-schema-test.js +11 -9
- package/dist/esm/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/esm/schema/test/discovery-factory.test.js +2 -2
- package/dist/esm/schema/test/error-handling.test.js +8 -6
- package/dist/esm/schema/test/integration.test.js +24 -18
- package/dist/esm/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/esm/schema/test/simple-schema-test.js +9 -9
- package/dist/esm/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/esm/schema/test/test-runner.js +3 -3
- package/dist/esm/sqlite-migration/index.d.ts +2 -2
- package/dist/esm/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/esm/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/esm/testing/test-utils.js +36 -34
- package/dist/esm/types/index.d.ts +5 -2
- package/dist/esm/types/index.js +6 -3
- package/dist/esm/types/type-generator.js +46 -42
- package/dist/esm/util/safe-sql-helpers.js +1 -1
- package/dist/esm/util/security-validator.js +20 -9
- package/dist/esm/utils/errorHelpers.js +21 -11
- package/dist/esm/watch/schema-watcher.js +22 -23
- package/package.json +40 -44
|
@@ -35,7 +35,7 @@ exports.defaultPerformanceConfig = {
|
|
|
35
35
|
maxSize: 1000,
|
|
36
36
|
defaultTtl: 300000, // 5 minutes
|
|
37
37
|
cleanupInterval: 60000, // 1 minute
|
|
38
|
-
enableMetrics: true
|
|
38
|
+
enableMetrics: true,
|
|
39
39
|
},
|
|
40
40
|
metrics: {
|
|
41
41
|
enabled: true,
|
|
@@ -44,14 +44,14 @@ exports.defaultPerformanceConfig = {
|
|
|
44
44
|
missingIndexDetection: true,
|
|
45
45
|
largeResultSetThreshold: 1000,
|
|
46
46
|
maxHistorySize: 10000,
|
|
47
|
-
warningRetentionDays: 7
|
|
47
|
+
warningRetentionDays: 7,
|
|
48
48
|
},
|
|
49
49
|
connectionPool: {
|
|
50
50
|
minConnections: 2,
|
|
51
51
|
maxConnections: 10,
|
|
52
52
|
acquireTimeout: 30000,
|
|
53
53
|
idleTimeout: 300000,
|
|
54
|
-
validationInterval: 60000
|
|
54
|
+
validationInterval: 60000,
|
|
55
55
|
},
|
|
56
56
|
optimizer: {
|
|
57
57
|
enableQueryCache: true,
|
|
@@ -59,6 +59,6 @@ exports.defaultPerformanceConfig = {
|
|
|
59
59
|
enableQueryRewriting: true,
|
|
60
60
|
slowQueryThreshold: 1000,
|
|
61
61
|
cacheSize: 1000,
|
|
62
|
-
maxCacheAge: 300000
|
|
63
|
-
}
|
|
62
|
+
maxCacheAge: 300000,
|
|
63
|
+
},
|
|
64
64
|
};
|
|
@@ -28,20 +28,20 @@ class QueryOptimizer {
|
|
|
28
28
|
slowQueryThreshold: 1000,
|
|
29
29
|
cacheSize: 1000,
|
|
30
30
|
maxCacheAge: 300000,
|
|
31
|
-
...options
|
|
31
|
+
...options,
|
|
32
32
|
};
|
|
33
33
|
// Initialize services
|
|
34
34
|
this.cacheService = new cache_service_1.QueryCacheService({
|
|
35
35
|
maxSize: this.options.cacheSize,
|
|
36
36
|
defaultTtl: this.options.maxCacheAge,
|
|
37
|
-
enableMetrics: true
|
|
37
|
+
enableMetrics: true,
|
|
38
38
|
}, this.logger);
|
|
39
39
|
this.metricsCollector = new metrics_collector_1.MetricsCollector({
|
|
40
40
|
enabled: true,
|
|
41
41
|
slowQueryThreshold: this.options.slowQueryThreshold,
|
|
42
42
|
nPlusOneDetection: true,
|
|
43
43
|
missingIndexDetection: this.options.enableIndexRecommendations,
|
|
44
|
-
largeResultSetThreshold: 1000
|
|
44
|
+
largeResultSetThreshold: 1000,
|
|
45
45
|
}, this.logger);
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
@@ -62,7 +62,7 @@ class QueryOptimizer {
|
|
|
62
62
|
executionTime,
|
|
63
63
|
improvement: 100,
|
|
64
64
|
suggestions: ['Query served from cache'],
|
|
65
|
-
result: cachedResult
|
|
65
|
+
result: cachedResult,
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -82,7 +82,7 @@ class QueryOptimizer {
|
|
|
82
82
|
this.metricsCollector.recordQuery(query, executionTime, {
|
|
83
83
|
table: context?.table,
|
|
84
84
|
operation: context?.operation,
|
|
85
|
-
resultCount: Array.isArray(result) ? result.length : 1
|
|
85
|
+
resultCount: Array.isArray(result) ? result.length : 1,
|
|
86
86
|
});
|
|
87
87
|
// Generate suggestions
|
|
88
88
|
const suggestions = this.generateSuggestions(parsedQuery, executionTime, context);
|
|
@@ -93,7 +93,7 @@ class QueryOptimizer {
|
|
|
93
93
|
executionTime,
|
|
94
94
|
improvement: optimization.improvement,
|
|
95
95
|
suggestions,
|
|
96
|
-
result
|
|
96
|
+
result,
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
catch (error) {
|
|
@@ -103,11 +103,11 @@ class QueryOptimizer {
|
|
|
103
103
|
this.metricsCollector.recordQuery(query, executionTime, {
|
|
104
104
|
table: context?.table,
|
|
105
105
|
operation: context?.operation,
|
|
106
|
-
error: errorMessage
|
|
106
|
+
error: errorMessage,
|
|
107
107
|
});
|
|
108
108
|
this.logger.error(`Query optimization failed: ${errorMessage}`, {
|
|
109
109
|
query,
|
|
110
|
-
executionTime
|
|
110
|
+
executionTime,
|
|
111
111
|
});
|
|
112
112
|
throw error;
|
|
113
113
|
}
|
|
@@ -137,7 +137,7 @@ class QueryOptimizer {
|
|
|
137
137
|
return {
|
|
138
138
|
...metricsStats,
|
|
139
139
|
cache: cacheStats,
|
|
140
|
-
indexRecommendations: 0 // Would be populated by recommendations
|
|
140
|
+
indexRecommendations: 0, // Would be populated by recommendations
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
@@ -198,7 +198,7 @@ class QueryOptimizer {
|
|
|
198
198
|
return {
|
|
199
199
|
optimizedQuery,
|
|
200
200
|
type,
|
|
201
|
-
improvement
|
|
201
|
+
improvement,
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
@@ -208,7 +208,8 @@ class QueryOptimizer {
|
|
|
208
208
|
let optimizedQuery = originalQuery;
|
|
209
209
|
let improvement = 0;
|
|
210
210
|
// Add LIMIT if missing and query could return many rows
|
|
211
|
-
if (!parsedQuery.hasLimit &&
|
|
211
|
+
if (!parsedQuery.hasLimit &&
|
|
212
|
+
query_parser_1.QueryParser.couldReturnManyRows(originalQuery)) {
|
|
212
213
|
optimizedQuery = `${originalQuery} LIMIT 1000`;
|
|
213
214
|
improvement = 10;
|
|
214
215
|
}
|
|
@@ -222,7 +223,7 @@ class QueryOptimizer {
|
|
|
222
223
|
}
|
|
223
224
|
return {
|
|
224
225
|
optimizedQuery,
|
|
225
|
-
improvement
|
|
226
|
+
improvement,
|
|
226
227
|
};
|
|
227
228
|
}
|
|
228
229
|
/**
|
|
@@ -247,13 +248,14 @@ class QueryOptimizer {
|
|
|
247
248
|
// Check for missing indexes on GROUP BY columns
|
|
248
249
|
if (parsedQuery.hasAggregates && parsedQuery.groupByColumns.length > 0) {
|
|
249
250
|
const table = parsedQuery.tables[0];
|
|
250
|
-
if (table &&
|
|
251
|
+
if (table &&
|
|
252
|
+
parsedQuery.groupByColumns.every((col) => this.hasIndexOnColumn(table, col))) {
|
|
251
253
|
improvement = Math.max(improvement, 25);
|
|
252
254
|
}
|
|
253
255
|
}
|
|
254
256
|
return {
|
|
255
257
|
optimizedQuery,
|
|
256
|
-
improvement
|
|
258
|
+
improvement,
|
|
257
259
|
};
|
|
258
260
|
}
|
|
259
261
|
/**
|
|
@@ -274,7 +276,7 @@ class QueryOptimizer {
|
|
|
274
276
|
type: 'btree',
|
|
275
277
|
reason: `WHERE clause on ${column}`,
|
|
276
278
|
estimatedImprovement: 20,
|
|
277
|
-
priority: 'medium'
|
|
279
|
+
priority: 'medium',
|
|
278
280
|
});
|
|
279
281
|
}
|
|
280
282
|
}
|
|
@@ -287,7 +289,7 @@ class QueryOptimizer {
|
|
|
287
289
|
type: 'btree',
|
|
288
290
|
reason: `JOIN condition on ${column}`,
|
|
289
291
|
estimatedImprovement: 30,
|
|
290
|
-
priority: 'high'
|
|
292
|
+
priority: 'high',
|
|
291
293
|
});
|
|
292
294
|
}
|
|
293
295
|
}
|
|
@@ -300,7 +302,7 @@ class QueryOptimizer {
|
|
|
300
302
|
type: 'btree',
|
|
301
303
|
reason: `ORDER BY clause on ${column}`,
|
|
302
304
|
estimatedImprovement: 15,
|
|
303
|
-
priority: 'medium'
|
|
305
|
+
priority: 'medium',
|
|
304
306
|
});
|
|
305
307
|
}
|
|
306
308
|
}
|
|
@@ -359,7 +361,10 @@ class QueryOptimizer {
|
|
|
359
361
|
}
|
|
360
362
|
catch (error) {
|
|
361
363
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
362
|
-
this.logger.error(`Query execution failed: ${errorMessage}`, {
|
|
364
|
+
this.logger.error(`Query execution failed: ${errorMessage}`, {
|
|
365
|
+
query,
|
|
366
|
+
params,
|
|
367
|
+
});
|
|
363
368
|
throw error;
|
|
364
369
|
}
|
|
365
370
|
}
|
|
@@ -367,15 +372,15 @@ class QueryOptimizer {
|
|
|
367
372
|
* Check if column has an index
|
|
368
373
|
*/
|
|
369
374
|
hasIndexOnColumn(table, column) {
|
|
370
|
-
const tableInfo = this.schemaInfo.tables.find(t => t.name === table);
|
|
375
|
+
const tableInfo = this.schemaInfo.tables.find((t) => t.name === table);
|
|
371
376
|
if (!tableInfo)
|
|
372
377
|
return false;
|
|
373
378
|
// Check if column is primary key
|
|
374
|
-
const columnInfo = tableInfo.columns.find(col => col.name === column);
|
|
379
|
+
const columnInfo = tableInfo.columns.find((col) => col.name === column);
|
|
375
380
|
if (columnInfo?.isPrimaryKey)
|
|
376
381
|
return true;
|
|
377
382
|
// Check if column has an index
|
|
378
|
-
return tableInfo.indexes.some(idx => idx.columns.includes(column));
|
|
383
|
+
return tableInfo.indexes.some((idx) => idx.columns.includes(column));
|
|
379
384
|
}
|
|
380
385
|
}
|
|
381
386
|
exports.QueryOptimizer = QueryOptimizer;
|
|
@@ -21,7 +21,7 @@ class CacheService {
|
|
|
21
21
|
cleanupInterval: 60000, // 1 minute
|
|
22
22
|
enableCompression: false,
|
|
23
23
|
enableMetrics: true,
|
|
24
|
-
...config
|
|
24
|
+
...config,
|
|
25
25
|
};
|
|
26
26
|
this.stats = {
|
|
27
27
|
size: 0,
|
|
@@ -31,25 +31,25 @@ class CacheService {
|
|
|
31
31
|
hitRate: 0,
|
|
32
32
|
totalSize: 0,
|
|
33
33
|
evictions: 0,
|
|
34
|
-
lastCleanup: new Date()
|
|
34
|
+
lastCleanup: new Date(),
|
|
35
35
|
};
|
|
36
36
|
this.metrics = {
|
|
37
37
|
operations: {
|
|
38
38
|
get: 0,
|
|
39
39
|
set: 0,
|
|
40
40
|
delete: 0,
|
|
41
|
-
clear: 0
|
|
41
|
+
clear: 0,
|
|
42
42
|
},
|
|
43
43
|
performance: {
|
|
44
44
|
averageGetTime: 0,
|
|
45
45
|
averageSetTime: 0,
|
|
46
|
-
slowestOperation: 0
|
|
46
|
+
slowestOperation: 0,
|
|
47
47
|
},
|
|
48
48
|
memory: {
|
|
49
49
|
totalSize: 0,
|
|
50
50
|
averageEntrySize: 0,
|
|
51
|
-
largestEntry: 0
|
|
52
|
-
}
|
|
51
|
+
largestEntry: 0,
|
|
52
|
+
},
|
|
53
53
|
};
|
|
54
54
|
this.startCleanupTimer();
|
|
55
55
|
}
|
|
@@ -106,7 +106,7 @@ class CacheService {
|
|
|
106
106
|
timestamp: Date.now(),
|
|
107
107
|
ttl: entryTtl,
|
|
108
108
|
hitCount: 0,
|
|
109
|
-
size: entrySize
|
|
109
|
+
size: entrySize,
|
|
110
110
|
};
|
|
111
111
|
this.cache.set(key, entry);
|
|
112
112
|
this.updateStats();
|
|
@@ -192,7 +192,10 @@ class CacheService {
|
|
|
192
192
|
* Get cache entries (for debugging)
|
|
193
193
|
*/
|
|
194
194
|
entries() {
|
|
195
|
-
return Array.from(this.cache.entries()).map(([key, entry]) => ({
|
|
195
|
+
return Array.from(this.cache.entries()).map(([key, entry]) => ({
|
|
196
|
+
key,
|
|
197
|
+
entry,
|
|
198
|
+
}));
|
|
196
199
|
}
|
|
197
200
|
/**
|
|
198
201
|
* Warm cache with multiple entries
|
|
@@ -219,19 +222,23 @@ class CacheService {
|
|
|
219
222
|
recommendations.push('Consider increasing TTL or cache size');
|
|
220
223
|
}
|
|
221
224
|
// Check memory usage
|
|
222
|
-
if (this.stats.totalSize > 100 * 1024 * 1024) {
|
|
225
|
+
if (this.stats.totalSize > 100 * 1024 * 1024) {
|
|
226
|
+
// 100MB
|
|
223
227
|
issues.push(`High memory usage: ${(this.stats.totalSize / 1024 / 1024).toFixed(1)}MB`);
|
|
224
228
|
recommendations.push('Consider reducing cache size or enabling compression');
|
|
225
229
|
}
|
|
226
230
|
// Check eviction rate
|
|
227
|
-
const evictionRate = this.stats.evictions /
|
|
231
|
+
const evictionRate = this.stats.evictions /
|
|
232
|
+
Math.max(this.stats.hitCount + this.stats.missCount, 1);
|
|
228
233
|
if (evictionRate > 0.1) {
|
|
229
234
|
issues.push(`High eviction rate: ${(evictionRate * 100).toFixed(1)}%`);
|
|
230
235
|
recommendations.push('Consider increasing cache size');
|
|
231
236
|
}
|
|
232
237
|
let status = 'healthy';
|
|
233
238
|
if (issues.length > 0) {
|
|
234
|
-
status = issues.some(issue => issue.includes('critical'))
|
|
239
|
+
status = issues.some((issue) => issue.includes('critical'))
|
|
240
|
+
? 'critical'
|
|
241
|
+
: 'warning';
|
|
235
242
|
}
|
|
236
243
|
return { status, issues, recommendations };
|
|
237
244
|
}
|
|
@@ -300,7 +307,8 @@ class CacheService {
|
|
|
300
307
|
this.stats.totalSize = totalSize;
|
|
301
308
|
this.metrics.memory.totalSize = totalSize;
|
|
302
309
|
this.metrics.memory.largestEntry = largestEntry;
|
|
303
|
-
this.metrics.memory.averageEntrySize =
|
|
310
|
+
this.metrics.memory.averageEntrySize =
|
|
311
|
+
this.cache.size > 0 ? totalSize / this.cache.size : 0;
|
|
304
312
|
}
|
|
305
313
|
/**
|
|
306
314
|
* Update hit rate
|
|
@@ -319,12 +327,14 @@ class CacheService {
|
|
|
319
327
|
if (operation === 'get') {
|
|
320
328
|
const totalGets = this.metrics.operations.get;
|
|
321
329
|
this.metrics.performance.averageGetTime =
|
|
322
|
-
(this.metrics.performance.averageGetTime * (totalGets - 1) + duration) /
|
|
330
|
+
(this.metrics.performance.averageGetTime * (totalGets - 1) + duration) /
|
|
331
|
+
totalGets;
|
|
323
332
|
}
|
|
324
333
|
else if (operation === 'set') {
|
|
325
334
|
const totalSets = this.metrics.operations.set;
|
|
326
335
|
this.metrics.performance.averageSetTime =
|
|
327
|
-
(this.metrics.performance.averageSetTime * (totalSets - 1) + duration) /
|
|
336
|
+
(this.metrics.performance.averageSetTime * (totalSets - 1) + duration) /
|
|
337
|
+
totalSets;
|
|
328
338
|
}
|
|
329
339
|
}
|
|
330
340
|
/**
|
|
@@ -371,7 +381,7 @@ class QueryCacheService extends CacheService {
|
|
|
371
381
|
defaultTtl: 300000, // 5 minutes
|
|
372
382
|
cleanupInterval: 60000, // 1 minute
|
|
373
383
|
enableMetrics: true,
|
|
374
|
-
...config
|
|
384
|
+
...config,
|
|
375
385
|
}, logger);
|
|
376
386
|
}
|
|
377
387
|
/**
|
|
@@ -393,7 +403,7 @@ class QueryCacheService extends CacheService {
|
|
|
393
403
|
*/
|
|
394
404
|
generateQueryKey(query, params) {
|
|
395
405
|
const normalizedQuery = query.replace(/\s+/g, ' ').trim();
|
|
396
|
-
const paramsKey = params.map(p => String(p)).join('|');
|
|
406
|
+
const paramsKey = params.map((p) => String(p)).join('|');
|
|
397
407
|
return `query:${normalizedQuery}:${paramsKey}`;
|
|
398
408
|
}
|
|
399
409
|
/**
|
|
@@ -19,7 +19,7 @@ class ConnectionFactory {
|
|
|
19
19
|
activeConnections: 0,
|
|
20
20
|
failedCreations: 0,
|
|
21
21
|
averageCreationTime: 0,
|
|
22
|
-
averageValidationTime: 0
|
|
22
|
+
averageValidationTime: 0,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
@@ -39,7 +39,7 @@ class ConnectionFactory {
|
|
|
39
39
|
lastUsed: new Date(),
|
|
40
40
|
isActive: true,
|
|
41
41
|
inUse: false,
|
|
42
|
-
config
|
|
42
|
+
config,
|
|
43
43
|
};
|
|
44
44
|
this.connections.set(id, connection);
|
|
45
45
|
this.updateStats('created', performance.now() - startTime);
|
|
@@ -63,7 +63,7 @@ class ConnectionFactory {
|
|
|
63
63
|
this.updateStats('validated', responseTime);
|
|
64
64
|
return {
|
|
65
65
|
isValid: true,
|
|
66
|
-
responseTime
|
|
66
|
+
responseTime,
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
catch (error) {
|
|
@@ -73,7 +73,7 @@ class ConnectionFactory {
|
|
|
73
73
|
return {
|
|
74
74
|
isValid: false,
|
|
75
75
|
error: errorMessage,
|
|
76
|
-
responseTime
|
|
76
|
+
responseTime,
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -93,13 +93,13 @@ class ConnectionFactory {
|
|
|
93
93
|
* Get active connections
|
|
94
94
|
*/
|
|
95
95
|
getActiveConnections() {
|
|
96
|
-
return Array.from(this.connections.values()).filter(conn => conn.isActive);
|
|
96
|
+
return Array.from(this.connections.values()).filter((conn) => conn.isActive);
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* Get idle connections
|
|
100
100
|
*/
|
|
101
101
|
getIdleConnections() {
|
|
102
|
-
return Array.from(this.connections.values()).filter(conn => conn.isActive && !conn.inUse);
|
|
102
|
+
return Array.from(this.connections.values()).filter((conn) => conn.isActive && !conn.inUse);
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
105
|
* Mark connection as in use
|
|
@@ -140,7 +140,7 @@ class ConnectionFactory {
|
|
|
140
140
|
* Destroy all connections
|
|
141
141
|
*/
|
|
142
142
|
async destroyAllConnections() {
|
|
143
|
-
const destroyPromises = Array.from(this.connections.keys()).map(id => this.destroyConnection(id));
|
|
143
|
+
const destroyPromises = Array.from(this.connections.keys()).map((id) => this.destroyConnection(id));
|
|
144
144
|
await Promise.all(destroyPromises);
|
|
145
145
|
this.logger.info('Destroyed all connections');
|
|
146
146
|
}
|
|
@@ -151,8 +151,7 @@ class ConnectionFactory {
|
|
|
151
151
|
const now = Date.now();
|
|
152
152
|
let cleaned = 0;
|
|
153
153
|
for (const [id, connection] of this.connections.entries()) {
|
|
154
|
-
if (!connection.inUse &&
|
|
155
|
-
now - connection.lastUsed.getTime() > maxAge) {
|
|
154
|
+
if (!connection.inUse && now - connection.lastUsed.getTime() > maxAge) {
|
|
156
155
|
if (await this.destroyConnection(id)) {
|
|
157
156
|
cleaned++;
|
|
158
157
|
}
|
|
@@ -173,7 +172,7 @@ class ConnectionFactory {
|
|
|
173
172
|
id: connection.id,
|
|
174
173
|
isValid: result.isValid,
|
|
175
174
|
error: result.error,
|
|
176
|
-
responseTime: result.responseTime
|
|
175
|
+
responseTime: result.responseTime,
|
|
177
176
|
};
|
|
178
177
|
});
|
|
179
178
|
return Promise.all(validationPromises);
|
|
@@ -191,7 +190,7 @@ class ConnectionFactory {
|
|
|
191
190
|
const connections = this.getAllConnections();
|
|
192
191
|
const activeConnections = this.getActiveConnections();
|
|
193
192
|
const idleConnections = this.getIdleConnections();
|
|
194
|
-
const inUseConnections = connections.filter(c => c.inUse);
|
|
193
|
+
const inUseConnections = connections.filter((c) => c.inUse);
|
|
195
194
|
const issues = [];
|
|
196
195
|
// Check for failed creations
|
|
197
196
|
if (this.stats.failedCreations > 0) {
|
|
@@ -207,7 +206,9 @@ class ConnectionFactory {
|
|
|
207
206
|
}
|
|
208
207
|
let status = 'healthy';
|
|
209
208
|
if (issues.length > 0) {
|
|
210
|
-
status = issues.some(issue => issue.includes('failures'))
|
|
209
|
+
status = issues.some((issue) => issue.includes('failures'))
|
|
210
|
+
? 'critical'
|
|
211
|
+
: 'warning';
|
|
211
212
|
}
|
|
212
213
|
return {
|
|
213
214
|
status,
|
|
@@ -216,8 +217,8 @@ class ConnectionFactory {
|
|
|
216
217
|
total: connections.length,
|
|
217
218
|
active: activeConnections.length,
|
|
218
219
|
idle: idleConnections.length,
|
|
219
|
-
inUse: inUseConnections.length
|
|
220
|
-
}
|
|
220
|
+
inUse: inUseConnections.length,
|
|
221
|
+
},
|
|
221
222
|
};
|
|
222
223
|
}
|
|
223
224
|
/**
|
|
@@ -286,7 +287,7 @@ class ConnectionPoolManager {
|
|
|
286
287
|
acquireTimeout: 30000,
|
|
287
288
|
idleTimeout: 300000,
|
|
288
289
|
validationInterval: 60000,
|
|
289
|
-
...poolConfig
|
|
290
|
+
...poolConfig,
|
|
290
291
|
};
|
|
291
292
|
this.startValidationTimer();
|
|
292
293
|
}
|
|
@@ -297,7 +298,7 @@ class ConnectionPoolManager {
|
|
|
297
298
|
this.logger.info(`Initializing connection pool with ${this.poolConfig.minConnections} minimum connections`);
|
|
298
299
|
const initPromises = Array.from({ length: this.poolConfig.minConnections }, (_, i) => this.factory.createConnection({
|
|
299
300
|
...this.config,
|
|
300
|
-
id: `pool_conn_${i}
|
|
301
|
+
id: `pool_conn_${i}`,
|
|
301
302
|
}));
|
|
302
303
|
try {
|
|
303
304
|
await Promise.all(initPromises);
|
|
@@ -329,7 +330,7 @@ class ConnectionPoolManager {
|
|
|
329
330
|
if (currentConnections.length < this.poolConfig.maxConnections) {
|
|
330
331
|
const newConnection = await this.factory.createConnection({
|
|
331
332
|
...this.config,
|
|
332
|
-
id: `pool_conn_${Date.now()}
|
|
333
|
+
id: `pool_conn_${Date.now()}`,
|
|
333
334
|
});
|
|
334
335
|
this.factory.markInUse(newConnection);
|
|
335
336
|
this.logger.debug(`Created and acquired new connection ${newConnection.id}`);
|
|
@@ -385,8 +386,8 @@ class ConnectionPoolManager {
|
|
|
385
386
|
...factoryStats,
|
|
386
387
|
poolSize: connections.length,
|
|
387
388
|
idleConnections: this.factory.getIdleConnections().length,
|
|
388
|
-
inUseConnections: connections.filter(c => c.inUse).length,
|
|
389
|
-
waitingQueue: this.waitingQueue.length
|
|
389
|
+
inUseConnections: connections.filter((c) => c.inUse).length,
|
|
390
|
+
waitingQueue: this.waitingQueue.length,
|
|
390
391
|
};
|
|
391
392
|
}
|
|
392
393
|
/**
|
|
@@ -421,7 +422,7 @@ class ConnectionPoolManager {
|
|
|
421
422
|
async waitForConnection(startTime) {
|
|
422
423
|
return new Promise((resolve, reject) => {
|
|
423
424
|
const timeout = setTimeout(() => {
|
|
424
|
-
const index = this.waitingQueue.findIndex(item => item.reject === reject);
|
|
425
|
+
const index = this.waitingQueue.findIndex((item) => item.reject === reject);
|
|
425
426
|
if (index !== -1) {
|
|
426
427
|
this.waitingQueue.splice(index, 1);
|
|
427
428
|
}
|
|
@@ -436,7 +437,7 @@ class ConnectionPoolManager {
|
|
|
436
437
|
clearTimeout(timeout);
|
|
437
438
|
reject(error);
|
|
438
439
|
},
|
|
439
|
-
timestamp: Date.now()
|
|
440
|
+
timestamp: Date.now(),
|
|
440
441
|
});
|
|
441
442
|
});
|
|
442
443
|
}
|
|
@@ -466,7 +467,9 @@ class ConnectionPoolManager {
|
|
|
466
467
|
* Validate all connections in the pool
|
|
467
468
|
*/
|
|
468
469
|
async validateConnections() {
|
|
469
|
-
const validationPromises = this.factory
|
|
470
|
+
const validationPromises = this.factory
|
|
471
|
+
.getIdleConnections()
|
|
472
|
+
.map(async (connection) => {
|
|
470
473
|
const validation = await this.factory.validateConnection(connection);
|
|
471
474
|
if (!validation.isValid) {
|
|
472
475
|
await this.factory.destroyConnection(connection.id);
|
|
@@ -480,7 +483,9 @@ class ConnectionPoolManager {
|
|
|
480
483
|
async cleanupIdleConnections() {
|
|
481
484
|
const now = Date.now();
|
|
482
485
|
const idleConnections = this.factory.getIdleConnections();
|
|
483
|
-
const excessConnections = idleConnections
|
|
486
|
+
const excessConnections = idleConnections
|
|
487
|
+
.filter((conn) => now - conn.lastUsed.getTime() > this.poolConfig.idleTimeout)
|
|
488
|
+
.slice(this.poolConfig.minConnections);
|
|
484
489
|
for (const connection of excessConnections) {
|
|
485
490
|
await this.factory.destroyConnection(connection.id);
|
|
486
491
|
}
|