Skip to main content
Glama
SchemaAnalyzer.js4.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SchemaAnalyzer = void 0; class SchemaAnalyzer { /** * Analyze overall schema statistics * * Semantic: High-level schema health metrics */ analyzeSchema(tables) { return { totalTables: tables.length, totalColumns: this.countTotalColumns(tables), tablesWithPrimaryKeys: tables.filter((t) => t.hasPrimaryKey()).length, tablesWithoutPrimaryKeys: tables.filter((t) => !t.hasPrimaryKey()).length, tablesWithForeignKeys: tables.filter((t) => t.hasForeignKeys()).length, tablesWithIndexes: tables.filter((t) => t.getIndexCount() > 0).length, totalIndexes: tables.reduce((sum, t) => sum + t.getIndexCount(), 0), totalForeignKeys: tables.reduce((sum, t) => sum + t.getForeignKeyCount(), 0), totalViews: tables.filter((t) => t.isView()).length, }; } /** * Analyze individual table in detail * * Semantic: Table-level metadata and characteristics */ analyzeTable(table) { return { tableName: table.name, columnCount: table.getColumnCount(), hasPrimaryKey: table.hasPrimaryKey(), primaryKeyColumns: table.getPrimaryKeyColumns().map((col) => col.name), requiredColumns: table.getRequiredColumns().map((col) => col.name), foreignKeyCount: table.getForeignKeyCount(), indexCount: table.getIndexCount(), isView: table.isView(), }; } /** * Get column type distribution across tables * * Semantic: Type usage patterns for data modeling insights */ analyzeColumnTypes(tables) { const typeCount = new Map(); for (const table of tables) { for (const column of table.columns) { const currentCount = typeCount.get(column.type) || 0; typeCount.set(column.type, currentCount + 1); } } return typeCount; } /** * Identify tables with potential design issues * * Semantic: Tables that violate common best practices */ identifyProblematicTables(tables) { return tables.filter((table) => { // Skip views - they don't need primary keys if (table.isView()) { return false; } // Tables without primary keys are problematic if (!table.hasPrimaryKey()) { return true; } // Tables with foreign keys but no indexes on FK columns if (table.hasForeignKeys()) { const fkColumns = table.getForeignKeyColumns(); const hasUnindexedFK = fkColumns.some((col) => !table.hasIndexOnColumn(col)); if (hasUnindexedFK) { return true; } } return false; }); } /** * Get nullable column analysis * * Semantic: Data quality insights - which columns allow nulls */ analyzeNullability(table) { const nullableColumns = table.columns.filter((col) => col.isNullable); const requiredColumns = table.columns.filter((col) => !col.isNullable); return { nullableColumns, requiredColumns, nullablePercentage: (nullableColumns.length / table.columns.length) * 100, }; } /** * Count total columns across all tables */ countTotalColumns(tables) { return tables.reduce((sum, table) => sum + table.getColumnCount(), 0); } /** * Get tables sorted by complexity (column count + index count + FK count) * * Semantic: Identify most complex tables for maintenance focus */ getTablesByComplexity(tables) { return tables .map((table) => ({ table, complexity: table.getColumnCount() + table.getIndexCount() + table.getForeignKeyCount(), })) .sort((a, b) => b.complexity - a.complexity); } /** * Identify orphaned tables (no foreign keys in or out) * * Semantic: Tables with no relationships - potential data islands */ identifyOrphanedTables(tables) { // Tables that don't reference others and aren't referenced by others const referencedTableNames = new Set(); for (const table of tables) { for (const fk of table.foreignKeys) { referencedTableNames.add(fk.referencesTable); } } return tables.filter((table) => { const hasOutgoingFKs = table.hasForeignKeys(); const hasIncomingFKs = referencedTableNames.has(table.name); return !hasOutgoingFKs && !hasIncomingFKs && !table.isView(); }); } } exports.SchemaAnalyzer = SchemaAnalyzer; //# sourceMappingURL=SchemaAnalyzer.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/semanticintent/semantic-d1-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server