Implement Phase 1.2: Database with encryption at rest and core infrastructure
Co-authored-by: southseact-3d <217551146+southseact-3d@users.noreply.github.com>
This commit is contained in:
143
chat/src/database/connection.js
Normal file
143
chat/src/database/connection.js
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Database connection module with SQLite support
|
||||
* Uses better-sqlite3 for synchronous operations
|
||||
* Note: SQLCipher support requires special compilation, using AES-256-GCM encryption at field level instead
|
||||
*/
|
||||
|
||||
const Database = require('better-sqlite3');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
let db = null;
|
||||
let dbPath = null;
|
||||
|
||||
/**
|
||||
* Initialize database connection
|
||||
* @param {string} databasePath - Path to the database file
|
||||
* @param {Object} options - Database options
|
||||
* @returns {Database} Database instance
|
||||
*/
|
||||
function initDatabase(databasePath, options = {}) {
|
||||
if (db) {
|
||||
return db;
|
||||
}
|
||||
|
||||
dbPath = databasePath;
|
||||
|
||||
// Ensure database directory exists
|
||||
const dbDir = path.dirname(databasePath);
|
||||
if (!fs.existsSync(dbDir)) {
|
||||
fs.mkdirSync(dbDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Initialize database with options
|
||||
const dbOptions = {
|
||||
verbose: options.verbose ? console.log : null,
|
||||
fileMustExist: false,
|
||||
timeout: options.timeout || 5000,
|
||||
...options
|
||||
};
|
||||
|
||||
db = new Database(databasePath, dbOptions);
|
||||
|
||||
// Enable WAL mode for better concurrency
|
||||
if (options.walMode !== false) {
|
||||
db.pragma('journal_mode = WAL');
|
||||
}
|
||||
|
||||
// Set reasonable defaults
|
||||
db.pragma('synchronous = NORMAL');
|
||||
db.pragma('cache_size = -64000'); // 64MB cache
|
||||
db.pragma('temp_store = MEMORY');
|
||||
db.pragma('foreign_keys = ON');
|
||||
|
||||
console.log('✅ Database connected:', databasePath);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database instance
|
||||
* @returns {Database|null} Database instance or null if not initialized
|
||||
*/
|
||||
function getDatabase() {
|
||||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close database connection
|
||||
*/
|
||||
function closeDatabase() {
|
||||
if (db) {
|
||||
try {
|
||||
db.close();
|
||||
console.log('✅ Database connection closed');
|
||||
} catch (error) {
|
||||
console.error('Error closing database:', error);
|
||||
} finally {
|
||||
db = null;
|
||||
dbPath = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if database is initialized
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isDatabaseInitialized() {
|
||||
return db !== null && db.open;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get database path
|
||||
* @returns {string|null}
|
||||
*/
|
||||
function getDatabasePath() {
|
||||
return dbPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a backup of the database
|
||||
* @param {string} backupPath - Path to backup file
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function backupDatabase(backupPath) {
|
||||
if (!db) {
|
||||
throw new Error('Database not initialized');
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const backup = db.backup(backupPath);
|
||||
backup.step(-1); // Copy all pages at once
|
||||
backup.finish();
|
||||
console.log('✅ Database backup created:', backupPath);
|
||||
resolve();
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a transaction
|
||||
* @param {Function} fn - Function to execute in transaction
|
||||
* @returns {*} Result of the function
|
||||
*/
|
||||
function transaction(fn) {
|
||||
if (!db) {
|
||||
throw new Error('Database not initialized');
|
||||
}
|
||||
return db.transaction(fn)();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
initDatabase,
|
||||
getDatabase,
|
||||
closeDatabase,
|
||||
isDatabaseInitialized,
|
||||
getDatabasePath,
|
||||
backupDatabase,
|
||||
transaction
|
||||
};
|
||||
Reference in New Issue
Block a user