fss-link 1.0.51 → 1.0.53
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 +42 -2
- package/dist/package.json +1 -1
- package/dist/src/config/auth.js +5 -8
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.d.ts +1 -0
- package/dist/src/config/config.js +5 -0
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/database-utils.d.ts +185 -0
- package/dist/src/config/database-utils.js +295 -0
- package/dist/src/config/database-utils.js.map +1 -0
- package/dist/src/config/database.d.ts +197 -1
- package/dist/src/config/database.js +499 -160
- package/dist/src/config/database.js.map +1 -1
- package/dist/src/config/databaseHealthMonitor.d.ts +86 -0
- package/dist/src/config/databaseHealthMonitor.js +180 -0
- package/dist/src/config/databaseHealthMonitor.js.map +1 -0
- package/dist/src/config/databaseMetrics.d.ts +147 -0
- package/dist/src/config/databaseMetrics.js +369 -0
- package/dist/src/config/databaseMetrics.js.map +1 -0
- package/dist/src/config/databaseMigrations.js +40 -2
- package/dist/src/config/databaseMigrations.js.map +1 -1
- package/dist/src/config/databaseSchemaValidator.d.ts +114 -0
- package/dist/src/config/databaseSchemaValidator.js +499 -0
- package/dist/src/config/databaseSchemaValidator.js.map +1 -0
- package/dist/src/config/providerPersistence.d.ts +7 -0
- package/dist/src/config/providerPersistence.js +14 -7
- package/dist/src/config/providerPersistence.js.map +1 -1
- package/dist/src/gemini.js +35 -2
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/ui/utils/updateCheck.js +1 -1
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/utils/installationInfo.js +16 -0
- package/dist/src/utils/installationInfo.js.map +1 -1
- package/dist/src/utils/installationInfo.test.js +6 -6
- package/dist/src/utils/installationInfo.test.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +18 -4
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* TEMPORARY DATABASE UTILITIES
|
|
8
|
+
*
|
|
9
|
+
* These wrapper functions provide immediate relief from manual memory management
|
|
10
|
+
* while we transition to a proper ORM/repository pattern.
|
|
11
|
+
*
|
|
12
|
+
* @todo PHASE 2: Replace with Repository pattern (BaseRepository, ModelRepository, etc.)
|
|
13
|
+
* @todo PHASE 3: Consider migrating to Drizzle ORM or similar for full type safety
|
|
14
|
+
*
|
|
15
|
+
* Current problems these wrappers solve:
|
|
16
|
+
* - Manual .free() calls causing memory leaks
|
|
17
|
+
* - Inconsistent error handling patterns
|
|
18
|
+
* - No automatic cleanup on exceptions
|
|
19
|
+
* - Raw SQL scattered throughout business logic
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Safe query execution with automatic statement cleanup.
|
|
23
|
+
* Returns all matching rows as an array.
|
|
24
|
+
*
|
|
25
|
+
* @todo UPGRADE: Replace with repository.findMany() method
|
|
26
|
+
*
|
|
27
|
+
* @param db - SQLite database instance
|
|
28
|
+
* @param sql - SQL query string
|
|
29
|
+
* @param params - Query parameters (optional)
|
|
30
|
+
* @returns Array of query results
|
|
31
|
+
* @throws DatabaseError for SQL execution errors
|
|
32
|
+
*/
|
|
33
|
+
export function safeQuery(db, sql, params = []) {
|
|
34
|
+
let stmt = null;
|
|
35
|
+
try {
|
|
36
|
+
stmt = db.prepare(sql);
|
|
37
|
+
if (params.length > 0) {
|
|
38
|
+
stmt.bind(params);
|
|
39
|
+
}
|
|
40
|
+
const results = [];
|
|
41
|
+
while (stmt.step()) {
|
|
42
|
+
results.push(stmt.getAsObject());
|
|
43
|
+
}
|
|
44
|
+
return results;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw new DatabaseError(`Query failed: ${sql}`, error);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
if (stmt) {
|
|
51
|
+
stmt.free();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Safe query execution returning first result or null.
|
|
57
|
+
* Automatically handles statement cleanup.
|
|
58
|
+
*
|
|
59
|
+
* @todo UPGRADE: Replace with repository.findFirst() method
|
|
60
|
+
*
|
|
61
|
+
* @param db - SQLite database instance
|
|
62
|
+
* @param sql - SQL query string
|
|
63
|
+
* @param params - Query parameters (optional)
|
|
64
|
+
* @returns First matching row or null
|
|
65
|
+
* @throws DatabaseError for SQL execution errors
|
|
66
|
+
*/
|
|
67
|
+
export function safeQueryFirst(db, sql, params = []) {
|
|
68
|
+
let stmt = null;
|
|
69
|
+
try {
|
|
70
|
+
stmt = db.prepare(sql);
|
|
71
|
+
if (params.length > 0) {
|
|
72
|
+
stmt.bind(params);
|
|
73
|
+
}
|
|
74
|
+
return stmt.step() ? stmt.getAsObject() : null;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
throw new DatabaseError(`Query failed: ${sql}`, error);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
if (stmt) {
|
|
81
|
+
stmt.free();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Safe execution of INSERT/UPDATE/DELETE statements.
|
|
87
|
+
* Automatically handles statement cleanup.
|
|
88
|
+
*
|
|
89
|
+
* @todo UPGRADE: Replace with repository.create()/update()/delete() methods
|
|
90
|
+
*
|
|
91
|
+
* @param db - SQLite database instance
|
|
92
|
+
* @param sql - SQL statement string
|
|
93
|
+
* @param params - Statement parameters (optional)
|
|
94
|
+
* @returns Number of affected rows
|
|
95
|
+
* @throws DatabaseError for SQL execution errors
|
|
96
|
+
*/
|
|
97
|
+
export function safeExec(db, sql, params = []) {
|
|
98
|
+
let stmt = null;
|
|
99
|
+
try {
|
|
100
|
+
stmt = db.prepare(sql);
|
|
101
|
+
if (params.length > 0) {
|
|
102
|
+
stmt.bind(params);
|
|
103
|
+
}
|
|
104
|
+
stmt.step();
|
|
105
|
+
// Get affected rows count for INSERT/UPDATE/DELETE
|
|
106
|
+
const changes = db.exec('SELECT changes() as count')[0];
|
|
107
|
+
return changes?.values?.[0]?.[0] || 0;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw new DatabaseError(`Execution failed: ${sql}`, error);
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
if (stmt) {
|
|
114
|
+
stmt.free();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Safe transaction execution with automatic rollback on error.
|
|
120
|
+
* Ensures consistent database state even if operations fail.
|
|
121
|
+
*
|
|
122
|
+
* @todo UPGRADE: Replace with repository.withTransaction() method
|
|
123
|
+
*
|
|
124
|
+
* @param db - SQLite database instance
|
|
125
|
+
* @param operations - Function containing database operations
|
|
126
|
+
* @returns Result of operations function
|
|
127
|
+
* @throws DatabaseError for transaction failures
|
|
128
|
+
*/
|
|
129
|
+
export function safeTransaction(db, operations) {
|
|
130
|
+
try {
|
|
131
|
+
db.exec('BEGIN TRANSACTION');
|
|
132
|
+
const result = operations();
|
|
133
|
+
db.exec('COMMIT');
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
try {
|
|
138
|
+
db.exec('ROLLBACK');
|
|
139
|
+
}
|
|
140
|
+
catch (rollbackError) {
|
|
141
|
+
// Log rollback failure but throw original error
|
|
142
|
+
console.error('Failed to rollback transaction:', rollbackError);
|
|
143
|
+
}
|
|
144
|
+
throw new DatabaseError('Transaction failed', error);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get the last inserted row ID from an INSERT operation.
|
|
149
|
+
* Helper for operations that need the new record ID.
|
|
150
|
+
*
|
|
151
|
+
* @todo UPGRADE: Repository pattern will handle this automatically
|
|
152
|
+
*
|
|
153
|
+
* @param db - SQLite database instance
|
|
154
|
+
* @returns Last inserted row ID
|
|
155
|
+
*/
|
|
156
|
+
export function getLastInsertId(db) {
|
|
157
|
+
const result = safeQueryFirst(db, 'SELECT last_insert_rowid() as id');
|
|
158
|
+
return result?.id || 0;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Custom error class for database operations.
|
|
162
|
+
* Provides consistent error handling across all database functions.
|
|
163
|
+
*
|
|
164
|
+
* @todo UPGRADE: Repository pattern will have more specific error types
|
|
165
|
+
*/
|
|
166
|
+
export class DatabaseError extends Error {
|
|
167
|
+
cause;
|
|
168
|
+
constructor(message, cause) {
|
|
169
|
+
super(message);
|
|
170
|
+
this.cause = cause;
|
|
171
|
+
this.name = 'DatabaseError';
|
|
172
|
+
// Include original error details if available
|
|
173
|
+
if (cause instanceof Error) {
|
|
174
|
+
this.message += ` (${cause.message})`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* MIGRATION HELPERS
|
|
180
|
+
*
|
|
181
|
+
* These functions help gradually replace manual prepare/free patterns
|
|
182
|
+
* throughout the existing codebase.
|
|
183
|
+
*/
|
|
184
|
+
/**
|
|
185
|
+
* Check if a table exists in the database.
|
|
186
|
+
* Common pattern used in migration logic.
|
|
187
|
+
*
|
|
188
|
+
* @param db - SQLite database instance
|
|
189
|
+
* @param tableName - Name of table to check
|
|
190
|
+
* @returns True if table exists
|
|
191
|
+
*/
|
|
192
|
+
export function tableExists(db, tableName) {
|
|
193
|
+
const result = safeQueryFirst(db, 'SELECT COUNT(*) as count FROM sqlite_master WHERE type="table" AND name=?', [tableName]);
|
|
194
|
+
return (result?.count || 0) > 0;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check if a column exists in a table.
|
|
198
|
+
* Useful for schema validation and migrations.
|
|
199
|
+
*
|
|
200
|
+
* @param db - SQLite database instance
|
|
201
|
+
* @param tableName - Name of table
|
|
202
|
+
* @param columnName - Name of column to check
|
|
203
|
+
* @returns True if column exists
|
|
204
|
+
*/
|
|
205
|
+
export function columnExists(db, tableName, columnName) {
|
|
206
|
+
try {
|
|
207
|
+
const result = safeQuery(db, `PRAGMA table_info(${tableName})`);
|
|
208
|
+
return result.some((col) => col.name === columnName);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* COMMON UTILITY PATTERNS
|
|
216
|
+
*
|
|
217
|
+
* These higher-level helpers encapsulate frequent database patterns
|
|
218
|
+
*/
|
|
219
|
+
/**
|
|
220
|
+
* Check if any records exist matching the criteria
|
|
221
|
+
* @param db - SQLite database instance
|
|
222
|
+
* @param table - Table name
|
|
223
|
+
* @param whereClause - WHERE clause (without WHERE keyword)
|
|
224
|
+
* @param params - Parameters for WHERE clause
|
|
225
|
+
* @returns True if any records exist
|
|
226
|
+
*/
|
|
227
|
+
export function recordExists(db, table, whereClause, params = []) {
|
|
228
|
+
const result = safeQueryFirst(db, `SELECT COUNT(*) as count FROM ${table} WHERE ${whereClause}`, params);
|
|
229
|
+
return (result?.count || 0) > 0;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Count records matching criteria
|
|
233
|
+
* @param db - SQLite database instance
|
|
234
|
+
* @param table - Table name
|
|
235
|
+
* @param whereClause - WHERE clause (without WHERE keyword, optional)
|
|
236
|
+
* @param params - Parameters for WHERE clause
|
|
237
|
+
* @returns Number of matching records
|
|
238
|
+
*/
|
|
239
|
+
export function countRecords(db, table, whereClause, params = []) {
|
|
240
|
+
const sql = whereClause
|
|
241
|
+
? `SELECT COUNT(*) as count FROM ${table} WHERE ${whereClause}`
|
|
242
|
+
: `SELECT COUNT(*) as count FROM ${table}`;
|
|
243
|
+
const result = safeQueryFirst(db, sql, params);
|
|
244
|
+
return result?.count || 0;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Delete records with safe execution
|
|
248
|
+
* @param db - SQLite database instance
|
|
249
|
+
* @param table - Table name
|
|
250
|
+
* @param whereClause - WHERE clause (without WHERE keyword)
|
|
251
|
+
* @param params - Parameters for WHERE clause
|
|
252
|
+
* @returns Number of deleted records
|
|
253
|
+
*/
|
|
254
|
+
export function deleteRecords(db, table, whereClause, params = []) {
|
|
255
|
+
return safeExec(db, `DELETE FROM ${table} WHERE ${whereClause}`, params);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Update records with safe execution
|
|
259
|
+
* @param db - SQLite database instance
|
|
260
|
+
* @param table - Table name
|
|
261
|
+
* @param setClause - SET clause (without SET keyword)
|
|
262
|
+
* @param whereClause - WHERE clause (without WHERE keyword)
|
|
263
|
+
* @param params - Parameters for SET and WHERE clauses
|
|
264
|
+
* @returns Number of updated records
|
|
265
|
+
*/
|
|
266
|
+
export function updateRecords(db, table, setClause, whereClause, params = []) {
|
|
267
|
+
return safeExec(db, `UPDATE ${table} SET ${setClause} WHERE ${whereClause}`, params);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* EXAMPLE MIGRATION FROM OLD PATTERN TO NEW PATTERN:
|
|
271
|
+
*
|
|
272
|
+
* // OLD (manual memory management):
|
|
273
|
+
* const stmt = db.prepare('SELECT * FROM model_configs WHERE auth_type = ?');
|
|
274
|
+
* stmt.bind([authType]);
|
|
275
|
+
* const results = [];
|
|
276
|
+
* while (stmt.step()) {
|
|
277
|
+
* results.push(stmt.getAsObject());
|
|
278
|
+
* }
|
|
279
|
+
* stmt.free(); // Easy to forget!
|
|
280
|
+
*
|
|
281
|
+
* // NEW (automatic cleanup):
|
|
282
|
+
* const results = safeQuery(db, 'SELECT * FROM model_configs WHERE auth_type = ?', [authType]);
|
|
283
|
+
*
|
|
284
|
+
* // UTILITY HELPERS:
|
|
285
|
+
* const hasActiveModels = recordExists(db, 'model_configs', 'is_active = 1');
|
|
286
|
+
* const modelCount = countRecords(db, 'model_configs', 'auth_type = ?', ['ollama']);
|
|
287
|
+
* const deletedCount = deleteRecords(db, 'model_configs', 'is_active = 0 AND last_used < ?', [cutoffDate]);
|
|
288
|
+
*
|
|
289
|
+
* // FUTURE (repository pattern):
|
|
290
|
+
* const results = await modelRepo.findByAuthType(authType);
|
|
291
|
+
* const hasActive = await modelRepo.hasActive();
|
|
292
|
+
* const count = await modelRepo.countByAuthType('ollama');
|
|
293
|
+
* const deleted = await modelRepo.deleteInactive(cutoffDate);
|
|
294
|
+
*/
|
|
295
|
+
//# sourceMappingURL=database-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-utils.js","sourceRoot":"","sources":["../../../src/config/database-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { ModelConfig } from 'fss-link-core';
|
|
7
7
|
import { type BackupMetadata } from './databaseBackup.js';
|
|
8
|
+
import { type DatabaseMetrics, type HistoricalMetrics } from './databaseMetrics.js';
|
|
9
|
+
import { type HealthCheckResult } from './databaseHealthMonitor.js';
|
|
10
|
+
import { type SchemaValidationResult } from './databaseSchemaValidator.js';
|
|
8
11
|
interface ExtendedModelConfig extends ModelConfig {
|
|
9
12
|
source?: string;
|
|
10
13
|
}
|
|
@@ -36,6 +39,9 @@ export declare class FSSLinkDatabase {
|
|
|
36
39
|
private migrationManager;
|
|
37
40
|
private backupManager;
|
|
38
41
|
private queryOptimizer;
|
|
42
|
+
private metricsCollector;
|
|
43
|
+
private healthMonitor;
|
|
44
|
+
private schemaValidator;
|
|
39
45
|
constructor();
|
|
40
46
|
/**
|
|
41
47
|
* Derive encryption key from machine-specific data
|
|
@@ -87,10 +93,12 @@ export declare class FSSLinkDatabase {
|
|
|
87
93
|
private ensureDefaultConfigurations;
|
|
88
94
|
/**
|
|
89
95
|
* Get provider settings for a specific provider
|
|
96
|
+
* @todo UPGRADE: Move to ProviderSettingsRepository.findByProviderId()
|
|
90
97
|
*/
|
|
91
98
|
getProviderSettings(providerId: number): Promise<Record<string, string>>;
|
|
92
99
|
/**
|
|
93
100
|
* Save a provider setting
|
|
101
|
+
* @todo UPGRADE: Move to ProviderSettingsRepository.upsert()
|
|
94
102
|
*/
|
|
95
103
|
saveProviderSetting(providerId: number, key: string, value: string | number): Promise<void>;
|
|
96
104
|
/**
|
|
@@ -103,6 +111,7 @@ export declare class FSSLinkDatabase {
|
|
|
103
111
|
setActiveModel(id: number): Promise<void>;
|
|
104
112
|
/**
|
|
105
113
|
* Add or update a model configuration
|
|
114
|
+
* @todo UPGRADE: Move to ModelRepository.upsert()
|
|
106
115
|
*/
|
|
107
116
|
upsertModelConfig(config: ExtendedModelConfig): Promise<number>;
|
|
108
117
|
/**
|
|
@@ -115,6 +124,7 @@ export declare class FSSLinkDatabase {
|
|
|
115
124
|
getFavoriteModels(): Promise<ExtendedModelConfig[]>;
|
|
116
125
|
/**
|
|
117
126
|
* Get recently used models
|
|
127
|
+
* @todo UPGRADE: Move to ModelRepository.findRecentlyUsed()
|
|
118
128
|
*/
|
|
119
129
|
getRecentModels(limit?: number): Promise<ExtendedModelConfig[]>;
|
|
120
130
|
/**
|
|
@@ -130,11 +140,13 @@ export declare class FSSLinkDatabase {
|
|
|
130
140
|
*/
|
|
131
141
|
setUserPreference(key: string, value: string): Promise<void>;
|
|
132
142
|
/**
|
|
133
|
-
* Get user preference
|
|
143
|
+
* Get user preference by key
|
|
144
|
+
* @todo UPGRADE: Move to PreferencesRepository.findByKey()
|
|
134
145
|
*/
|
|
135
146
|
getUserPreference(key: string): Promise<string | null>;
|
|
136
147
|
/**
|
|
137
148
|
* Get all user preferences
|
|
149
|
+
* @todo UPGRADE: Move to PreferencesRepository.findAll()
|
|
138
150
|
*/
|
|
139
151
|
getAllUserPreferences(): Promise<Record<string, string>>;
|
|
140
152
|
/**
|
|
@@ -213,6 +225,7 @@ export declare class FSSLinkDatabase {
|
|
|
213
225
|
saveCustomEndpoint(providerId: number, name: string, url: string, description?: string, isDefault?: boolean): Promise<number>;
|
|
214
226
|
/**
|
|
215
227
|
* Get custom endpoints for a provider
|
|
228
|
+
* @todo UPGRADE: Move to CustomEndpointsRepository.findByProviderId()
|
|
216
229
|
*/
|
|
217
230
|
getCustomEndpoints(providerId: number): Promise<DatabaseCustomEndpointRecord[]>;
|
|
218
231
|
/**
|
|
@@ -224,12 +237,195 @@ export declare class FSSLinkDatabase {
|
|
|
224
237
|
} | null>;
|
|
225
238
|
/**
|
|
226
239
|
* Get smart default provider based on usage and preferences
|
|
240
|
+
* @todo UPGRADE: Move to ModelRepository.findSmartDefault()
|
|
227
241
|
*/
|
|
228
242
|
getSmartDefaultProvider(): Promise<ModelConfig | null>;
|
|
229
243
|
/**
|
|
230
244
|
* Get a specific model configuration by ID
|
|
245
|
+
* @todo UPGRADE: Move to ModelRepository.findById()
|
|
231
246
|
*/
|
|
232
247
|
getModelById(modelId: number): Promise<ModelConfig | null>;
|
|
248
|
+
/**
|
|
249
|
+
* Get query performance metrics from the optimizer
|
|
250
|
+
*/
|
|
251
|
+
getQueryMetrics(): Promise<Array<{
|
|
252
|
+
query: string;
|
|
253
|
+
executionCount: number;
|
|
254
|
+
totalTime: number;
|
|
255
|
+
averageTime: number;
|
|
256
|
+
minTime: number;
|
|
257
|
+
maxTime: number;
|
|
258
|
+
lastExecuted: Date;
|
|
259
|
+
}>>;
|
|
260
|
+
/**
|
|
261
|
+
* Get slow queries (above threshold)
|
|
262
|
+
*/
|
|
263
|
+
getSlowQueries(thresholdMs?: number): Promise<Array<{
|
|
264
|
+
query: string;
|
|
265
|
+
executionCount: number;
|
|
266
|
+
totalTime: number;
|
|
267
|
+
averageTime: number;
|
|
268
|
+
minTime: number;
|
|
269
|
+
maxTime: number;
|
|
270
|
+
lastExecuted: Date;
|
|
271
|
+
}>>;
|
|
272
|
+
/**
|
|
273
|
+
* Get most frequently executed queries
|
|
274
|
+
*/
|
|
275
|
+
getFrequentQueries(limit?: number): Promise<Array<{
|
|
276
|
+
query: string;
|
|
277
|
+
executionCount: number;
|
|
278
|
+
totalTime: number;
|
|
279
|
+
averageTime: number;
|
|
280
|
+
minTime: number;
|
|
281
|
+
maxTime: number;
|
|
282
|
+
lastExecuted: Date;
|
|
283
|
+
}>>;
|
|
284
|
+
/**
|
|
285
|
+
* Get prepared statement cache statistics
|
|
286
|
+
*/
|
|
287
|
+
getCacheStats(): Promise<{
|
|
288
|
+
size: number;
|
|
289
|
+
maxSize: number;
|
|
290
|
+
hitRate: number;
|
|
291
|
+
entries: Array<{
|
|
292
|
+
query: string;
|
|
293
|
+
usageCount: number;
|
|
294
|
+
lastUsed: Date;
|
|
295
|
+
}>;
|
|
296
|
+
}>;
|
|
297
|
+
/**
|
|
298
|
+
* Clear query performance metrics
|
|
299
|
+
*/
|
|
300
|
+
clearQueryMetrics(): Promise<void>;
|
|
301
|
+
/**
|
|
302
|
+
* Optimize database by running ANALYZE
|
|
303
|
+
*/
|
|
304
|
+
optimizeDatabase(): Promise<void>;
|
|
305
|
+
/**
|
|
306
|
+
* Get comprehensive database statistics
|
|
307
|
+
*/
|
|
308
|
+
getDatabaseStats(): Promise<{
|
|
309
|
+
pageCount: number;
|
|
310
|
+
pageSize: number;
|
|
311
|
+
freelistCount: number;
|
|
312
|
+
schemaVersion: number;
|
|
313
|
+
userVersion: number;
|
|
314
|
+
tables: Array<{
|
|
315
|
+
name: string;
|
|
316
|
+
rowCount: number;
|
|
317
|
+
}>;
|
|
318
|
+
}>;
|
|
319
|
+
/**
|
|
320
|
+
* Run VACUUM to reclaim space and defragment
|
|
321
|
+
*/
|
|
322
|
+
vacuumDatabase(): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Collect comprehensive database metrics
|
|
325
|
+
*/
|
|
326
|
+
collectMetrics(): Promise<DatabaseMetrics>;
|
|
327
|
+
/**
|
|
328
|
+
* Get historical metrics for trend analysis
|
|
329
|
+
*/
|
|
330
|
+
getHistoricalMetrics(hours?: number): Promise<HistoricalMetrics[]>;
|
|
331
|
+
/**
|
|
332
|
+
* Get performance trends
|
|
333
|
+
*/
|
|
334
|
+
getPerformanceTrends(hours?: number): Promise<{
|
|
335
|
+
queryTimeTraend: number;
|
|
336
|
+
cacheHitTrend: number;
|
|
337
|
+
overallHealthTrend: number;
|
|
338
|
+
}>;
|
|
339
|
+
/**
|
|
340
|
+
* Generate a comprehensive database health report
|
|
341
|
+
*/
|
|
342
|
+
generateHealthReport(): Promise<{
|
|
343
|
+
metrics: DatabaseMetrics;
|
|
344
|
+
trends: {
|
|
345
|
+
queryTimeTraend: number;
|
|
346
|
+
cacheHitTrend: number;
|
|
347
|
+
overallHealthTrend: number;
|
|
348
|
+
};
|
|
349
|
+
recommendations: string[];
|
|
350
|
+
}>;
|
|
351
|
+
/**
|
|
352
|
+
* Set custom metrics thresholds
|
|
353
|
+
*/
|
|
354
|
+
setMetricsThresholds(thresholds: {
|
|
355
|
+
slowQueryThreshold?: number;
|
|
356
|
+
cacheHitRateThreshold?: number;
|
|
357
|
+
connectionUtilizationThreshold?: number;
|
|
358
|
+
diskUsageWarning?: number;
|
|
359
|
+
backupAgeWarning?: number;
|
|
360
|
+
}): Promise<void>;
|
|
361
|
+
/**
|
|
362
|
+
* Clear metrics history (for testing or cleanup)
|
|
363
|
+
*/
|
|
364
|
+
clearMetricsHistory(): Promise<void>;
|
|
365
|
+
/**
|
|
366
|
+
* Perform comprehensive health check
|
|
367
|
+
*/
|
|
368
|
+
performHealthCheck(): Promise<HealthCheckResult[]>;
|
|
369
|
+
/**
|
|
370
|
+
* Get maintenance recommendations
|
|
371
|
+
*/
|
|
372
|
+
getMaintenanceRecommendations(): Promise<string[]>;
|
|
373
|
+
/**
|
|
374
|
+
* Get recent health check history
|
|
375
|
+
*/
|
|
376
|
+
getHealthHistory(hours?: number): Promise<HealthCheckResult[]>;
|
|
377
|
+
/**
|
|
378
|
+
* Update health monitoring thresholds
|
|
379
|
+
*/
|
|
380
|
+
updateHealthThresholds(thresholds: {
|
|
381
|
+
queryTimeMs?: number;
|
|
382
|
+
cacheHitRate?: number;
|
|
383
|
+
connectionUtilization?: number;
|
|
384
|
+
healthScore?: number;
|
|
385
|
+
diskUsageMB?: number;
|
|
386
|
+
backupAgeHours?: number;
|
|
387
|
+
}): Promise<void>;
|
|
388
|
+
/**
|
|
389
|
+
* Clear health monitoring history
|
|
390
|
+
*/
|
|
391
|
+
clearHealthHistory(): Promise<void>;
|
|
392
|
+
/**
|
|
393
|
+
* Validate database schema against expected structure
|
|
394
|
+
*/
|
|
395
|
+
validateSchema(): Promise<SchemaValidationResult>;
|
|
396
|
+
/**
|
|
397
|
+
* Validate specific table schema
|
|
398
|
+
*/
|
|
399
|
+
validateTableSchema(tableName: string): Promise<{
|
|
400
|
+
isValid: boolean;
|
|
401
|
+
errors: any[];
|
|
402
|
+
warnings: any[];
|
|
403
|
+
}>;
|
|
404
|
+
/**
|
|
405
|
+
* Check if database needs migration based on schema validation
|
|
406
|
+
*/
|
|
407
|
+
needsSchemaMigration(): Promise<boolean>;
|
|
408
|
+
/**
|
|
409
|
+
* Get missing tables from schema
|
|
410
|
+
*/
|
|
411
|
+
getMissingTables(): Promise<string[]>;
|
|
412
|
+
/**
|
|
413
|
+
* Get missing indexes from schema
|
|
414
|
+
*/
|
|
415
|
+
getMissingIndexes(): Promise<string[]>;
|
|
416
|
+
/**
|
|
417
|
+
* Get formatted schema validation report
|
|
418
|
+
*/
|
|
419
|
+
getSchemaValidationReport(): Promise<string>;
|
|
420
|
+
/**
|
|
421
|
+
* Perform comprehensive database integrity check
|
|
422
|
+
*/
|
|
423
|
+
performIntegrityCheck(): Promise<{
|
|
424
|
+
schemaValidation: SchemaValidationResult;
|
|
425
|
+
healthCheck: HealthCheckResult[];
|
|
426
|
+
recommendations: string[];
|
|
427
|
+
overallStatus: 'healthy' | 'warning' | 'critical';
|
|
428
|
+
}>;
|
|
233
429
|
}
|
|
234
430
|
/**
|
|
235
431
|
* Get the global FSS Link database instance
|