@magic-mustard/sqlsync
Version:
SQLSync simplifies database schema evolution by allowing a declarative approach to table management
90 lines (89 loc) • 4.13 kB
JavaScript
;
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;