UNPKG

@magic-mustard/sqlsync

Version:

SQLSync simplifies database schema evolution by allowing a declarative approach to table management

107 lines (106 loc) 5.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AlterTablesProcessor = void 0; const namespace_1 = require("../namespace"); const namespace_2 = require("./namespace"); const logger_1 = require("../../utils/logger"); const crypto_1 = require("crypto"); class AlterTablesProcessor extends namespace_1.Parser.AbstractProcessor { constructor(file, migrations, state, contentBetweenFlags) { super(file, migrations, state, contentBetweenFlags); } process() { // Extract alter table statements from the file content const alterTableBlocks = this.getAlterTableBlocks(); // Process each block of statements this.processAlterTableBlocks(alterTableBlocks); } getAlterTableBlocks() { // Extract ALTER TABLE statements directly from file content const content = this.file.contents; const alterTableRegex = /ALTER\s+TABLE\s+[\w."]+\s+[^;]*;/gi; const matches = content.match(alterTableRegex) || []; logger_1.logger.debug(`Extracted ALTER TABLE statements: ${matches.length} found`); return matches; } hasAlterTableStatements() { try { const blocks = this.getAlterTableBlocks(); return blocks.length > 0; } catch (error) { return false; } } processAlterTableBlocks(blocks) { // Get the full migration state for alter tables const migrationState = this.state.getMigrationState(namespace_2.Tables.AlterTableStateIndex); for (const block of blocks) { if (!this.validateAlterTableBlock(block)) { throw new Error(`Invalid ALTER TABLE block in file: ${this.file.path}`); } const statements = this.splitIntoAlterStatements(block); for (const statement of statements) { const checksum = this.generateChecksum(statement); // Check if this statement already exists in any migration let statementExists = false; for (const [, namespaceData] of Object.entries(migrationState)) { if (namespaceData[namespace_2.Tables.AlterTableStateIndex] && Object.values(namespaceData[namespace_2.Tables.AlterTableStateIndex]).some((statements) => statements.includes(checksum))) { statementExists = true; break; } if (statementExists) break; } if (statementExists) { // Silently ignore as it's already in the state continue; } // Get the current migration state to update using getLatestMigrationName const currentMigration = this.migrations.getLatestMigrationName(); if (!migrationState[currentMigration]) { migrationState[currentMigration] = { [namespace_2.Tables.AlterTableStateIndex]: {} }; } const currentState = migrationState[currentMigration]; // Extract schema and table name from the ALTER TABLE statement const schemaTableName = this.extractSchemaTableNameFromAlter(statement); if (!schemaTableName) { throw new Error(`Failed to extract schema and table name from ALTER TABLE statement in file: ${this.file.path}`); } // If new, add to state if (!currentState[namespace_2.Tables.AlterTableStateIndex][schemaTableName]) { currentState[namespace_2.Tables.AlterTableStateIndex][schemaTableName] = []; } currentState[namespace_2.Tables.AlterTableStateIndex][schemaTableName].push(checksum); // Update state for the latest migration only this.state.updateMigrationState(currentState); // Append to migration this.migrations.append({ token: statement, filePath: this.file.path, checksum: checksum }); } } } validateAlterTableBlock(block) { // Simple validation for now; could be improved with a proper SQL parser const hasAlterTable = block.match(/ALTER\s+TABLE/i); return block.trim().length > 0 && hasAlterTable !== null; } extractSchemaTableNameFromAlter(block) { // Simple extraction for now; could be improved with a proper SQL parser const match = block.match(/ALTER\s+TABLE\s+([\w\.]+)/i); return (match === null || match === void 0 ? void 0 : match[1]) || null; } splitIntoAlterStatements(block) { // Simple split based on semicolon for now; could be improved with a proper SQL parser return block.split(';') .filter(statement => statement.trim().length > 0 && statement.match(/ALTER\s+TABLE/i)) .map(statement => statement.trim() + ';'); } generateChecksum(statement) { return (0, crypto_1.createHash)('sha256').update(statement).digest('hex'); } } exports.AlterTablesProcessor = AlterTablesProcessor;