UNPKG

@fastmcp-me/mcp-sqlew

Version:

MCP server for efficient context sharing between Claude Code sub-agents with 96% token reduction via action-based tools

168 lines 6.25 kB
/** * Schema initialization module * Loads and executes SQL schema from docs/schema.sql */ import { readFileSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); /** * Initialize database schema * Reads schema.sql and executes all CREATE and INSERT statements * * @param db - SQLite database connection * @throws Error if schema initialization fails */ export function initializeSchema(db) { try { // Read schema file const schemaPath = join(__dirname, '..', 'assets', 'schema.sql'); const schemaSql = readFileSync(schemaPath, 'utf-8'); // Execute schema in a transaction for atomicity db.exec('BEGIN TRANSACTION'); try { // Execute the entire schema // SQLite's exec() can handle multiple statements separated by semicolons db.exec(schemaSql); db.exec('COMMIT'); console.log('✓ Database schema initialized successfully'); } catch (error) { db.exec('ROLLBACK'); throw error; } } catch (error) { const message = error instanceof Error ? error.message : String(error); throw new Error(`Failed to initialize schema: ${message}`); } } /** * Check if schema is already initialized * Checks for existence of the m_agents table * * @param db - SQLite database connection * @returns true if schema exists, false otherwise */ export function isSchemaInitialized(db) { try { const result = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND (name='m_agents' OR name='agents')").get(); return result !== undefined; } catch (error) { return false; } } /** * Get schema version information * Returns counts of all master tables to verify schema integrity * * @param db - SQLite database connection * @returns Object with table counts */ export function getSchemaInfo(db) { const counts = { agents: 0, files: 0, context_keys: 0, layers: 0, tags: 0, scopes: 0, constraint_categories: 0, }; try { counts.agents = db.prepare('SELECT COUNT(*) as count FROM m_agents').get().count; counts.files = db.prepare('SELECT COUNT(*) as count FROM m_files').get().count; counts.context_keys = db.prepare('SELECT COUNT(*) as count FROM m_context_keys').get().count; counts.layers = db.prepare('SELECT COUNT(*) as count FROM m_layers').get().count; counts.tags = db.prepare('SELECT COUNT(*) as count FROM m_tags').get().count; counts.scopes = db.prepare('SELECT COUNT(*) as count FROM m_scopes').get().count; counts.constraint_categories = db.prepare('SELECT COUNT(*) as count FROM m_constraint_categories').get().count; } catch (error) { // If tables don't exist yet, return zeros } return counts; } /** * Verify schema integrity * Checks that all required tables, indexes, views, and triggers exist * * @param db - SQLite database connection * @returns Object with integrity check results */ export function verifySchemaIntegrity(db) { const result = { valid: true, missing: [], errors: [], }; const requiredTables = [ 'm_agents', 'm_files', 'm_context_keys', 'm_constraint_categories', 'm_layers', 'm_tags', 'm_scopes', 'm_config', 't_decisions', 't_decisions_numeric', 't_decision_history', 't_decision_tags', 't_decision_scopes', 't_agent_messages', 't_file_changes', 't_constraints', 't_constraint_tags', ]; const requiredViews = [ 'v_tagged_decisions', 'v_active_context', 'v_layer_summary', 'v_unread_messages_by_priority', 'v_recent_file_changes', 'v_tagged_constraints', ]; const requiredTriggers = [ 'trg_record_decision_history', ]; try { // Check tables for (const table of requiredTables) { const exists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(table); if (!exists) { result.valid = false; result.missing.push(`table:${table}`); } } // Check views for (const view of requiredViews) { const exists = db.prepare("SELECT name FROM sqlite_master WHERE type='view' AND name=?").get(view); if (!exists) { result.valid = false; result.missing.push(`view:${view}`); } } // Check triggers for (const trigger of requiredTriggers) { const exists = db.prepare("SELECT name FROM sqlite_master WHERE type='trigger' AND name=?").get(trigger); if (!exists) { result.valid = false; result.missing.push(`trigger:${trigger}`); } } // Verify standard data exists const layerCount = db.prepare('SELECT COUNT(*) as count FROM m_layers').get().count; if (layerCount < 5) { result.errors.push(`Expected 5 standard layers, found ${layerCount}`); result.valid = false; } const categoryCount = db.prepare('SELECT COUNT(*) as count FROM m_constraint_categories').get().count; if (categoryCount < 3) { result.errors.push(`Expected 3 standard categories, found ${categoryCount}`); result.valid = false; } const tagCount = db.prepare('SELECT COUNT(*) as count FROM m_tags').get().count; if (tagCount < 10) { result.errors.push(`Expected 10 standard tags, found ${tagCount}`); result.valid = false; } const configCount = db.prepare('SELECT COUNT(*) as count FROM m_config').get().count; if (configCount < 3) { result.errors.push(`Expected 3 m_config entries, found ${configCount}`); result.valid = false; } } catch (error) { result.valid = false; result.errors.push(error instanceof Error ? error.message : String(error)); } return result; } //# sourceMappingURL=schema.js.map