UNPKG

@magic-mustard/sqlsync

Version:

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

90 lines (89 loc) 4.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SplitStatementProcessor = void 0; const namespace_1 = require("../namespace"); const namespace_2 = require("./namespace"); const logger_1 = require("../../utils/logger"); const crypto_1 = require("crypto"); class SplitStatementProcessor extends namespace_1.Parser.AbstractProcessor { constructor(file, appender, handler, contentBetweenFlags) { super(file, appender, handler, contentBetweenFlags); } process() { // Extract split statement blocks from the file content const statementBlocks = this.getSplitStatementBlocks(); // Process each block of statements this.processSplitStatements(statementBlocks); } getSplitStatementBlocks() { // Use contentBetweenFlags to extract content between specific flags for split statements const startFlag = namespace_2.SplitStatements.Flags.start; const endFlag = namespace_2.SplitStatements.Flags.end; return this.contentBetweenFlags.extractContentBetweenFlags(this.file.contents, this.file.path, startFlag, endFlag, false // mustExist is set to false for now ); } hasSplitStatements() { try { const blocks = this.getSplitStatementBlocks(); return blocks.length > 0; } catch (error) { return false; } } processSplitStatements(statements) { const migrationState = this.state.getMigrationState(namespace_2.SplitStatements.StateIndex); for (const statement of statements) { // Clean the statement block by removing comments and normalizing whitespace const cleanedStatement = this.cleanStatementBlock(statement); // Skip empty statements if (!cleanedStatement.trim()) { continue; } // Generate a checksum for the statement const checksum = this.generateChecksum(cleanedStatement); // Check if the statement already exists in any migration let statementExists = false; for (const [, namespaceData] of Object.entries(migrationState)) { if (namespaceData[namespace_2.SplitStatements.StateIndex] && namespaceData[namespace_2.SplitStatements.StateIndex].includes(checksum)) { statementExists = true; 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.SplitStatements.StateIndex]: [] }; } const state = migrationState[currentMigration]; // If new, add to state state[namespace_2.SplitStatements.StateIndex].push(checksum); // Update state for the latest migration only this.state.updateMigrationState(state); // Append to migration this.migrations.append({ token: statement, filePath: this.file.path, checksum: checksum }); logger_1.logger.info(`Added split statement to migration. (file: ${this.file.path})`); } } cleanStatementBlock(statement) { // Remove SQL comments (both -- and /* */ style) let cleaned = statement.replace(/--.*$/gm, ''); cleaned = cleaned.replace(/\/\*([\s\S]*?)\*\//g, ''); // Normalize whitespace (replace multiple spaces/tabs/newlines with a single space) cleaned = cleaned.replace(/\s+/g, ' '); // Trim leading and trailing whitespace return cleaned.trim(); } generateChecksum(statement) { return (0, crypto_1.createHash)('sha256').update(statement).digest('hex'); } } exports.SplitStatementProcessor = SplitStatementProcessor;