@magic-mustard/sqlsync
Version:
SQLSync simplifies database schema evolution by allowing a declarative approach to table management
86 lines (85 loc) • 4.68 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateEnumsProcessor = void 0;
const namespace_1 = require("../namespace");
const namespace_2 = require("./namespace");
const logger_1 = require("../../utils/logger");
class CreateEnumsProcessor extends namespace_1.Parser.AbstractProcessor {
constructor(file, appender, handler, contentBetweenFlags) {
super(file, appender, handler, contentBetweenFlags);
}
process() {
// Extract create enum statements from the file content
const createEnumStatements = this.getCreateEnumStatements();
// Process each statement with validations
this.processCreateEnumStatements(createEnumStatements);
}
getCreateEnumStatements() {
// Extract CREATE TYPE or CREATE ENUM statements directly from file content
const content = this.file.contents;
const createEnumRegex = /CREATE\s+(?:TYPE|ENUM)\s+\w+\s*\.\s*\w+\s+AS\s+ENUM\s*\([^;]*\);/gi;
const matches = content.match(createEnumRegex) || [];
logger_1.logger.debug(`Extracted CREATE TYPE/ENUM statements: ${matches.length} found`);
return matches;
}
hasCreateEnumStatements() {
try {
const statements = this.getCreateEnumStatements();
return statements.length > 0;
}
catch (error) {
return false;
}
}
processCreateEnumStatements(statements) {
// Get the current state for enums
const state = this.state.getNamespaceState(namespace_2.Enums.CreateEnumStateIndex);
for (const statement of statements) {
// Extract schema and enum name from CREATE TYPE/ENUM statement
const schemaMatch = statement.match(/CREATE\s+(?:TYPE|ENUM)\s+(?:(\w+)\.)?(\w+)/i);
if (!schemaMatch) {
logger_1.logger.error(`Failed to extract schema and enum name from CREATE TYPE/ENUM statement in file: ${this.file.path}`);
continue;
}
const schema = schemaMatch[1];
if (!schema) {
throw new Error(`Invalid CREATE TYPE/ENUM statement in file ${this.file.path}: Schema must be specified (e.g., public.user_role).`);
}
const enumName = schemaMatch[2];
const schemaQualifiedEnumName = `${schema}.${enumName}`;
// Check if the enum already exists in the state
if (state[namespace_2.Enums.CreateEnumStateIndex] && state[namespace_2.Enums.CreateEnumStateIndex][schema] && state[namespace_2.Enums.CreateEnumStateIndex][schema].includes(schemaQualifiedEnumName)) {
logger_1.logger.info(`CREATE TYPE/ENUM statement for ${schemaQualifiedEnumName} already exists in state. It will not be added to the migration. (file: ${this.file.path})`);
continue;
}
// If new, add to state
if (!state[namespace_2.Enums.CreateEnumStateIndex]) {
state[namespace_2.Enums.CreateEnumStateIndex] = {};
}
if (!state[namespace_2.Enums.CreateEnumStateIndex][schema]) {
state[namespace_2.Enums.CreateEnumStateIndex][schema] = [];
}
state[namespace_2.Enums.CreateEnumStateIndex][schema].push(schemaQualifiedEnumName);
// Log the exact state structure before updating
console.log("CreateEnumsProcessor | State before update:", JSON.stringify(state, null, 2));
this.state.updateNamespaceState(namespace_2.Enums.CreateEnumStateIndex, state);
// Append to migration
this.migrations.append({
token: statement,
filePath: this.file.path
});
logger_1.logger.success(`Added CREATE TYPE/ENUM statement for ${schemaQualifiedEnumName} to migration. (file: ${this.file.path})`);
}
}
validateCreateEnumStatement(statement) {
// Check if the statement contains exactly one CREATE ENUM or CREATE TYPE statement and no other SQL statements
const createEnumCount = (statement.match(/CREATE\s+ENUM/i) || []).length;
const createTypeCount = (statement.match(/CREATE\s+TYPE/i) || []).length;
const totalCreateStatements = createEnumCount + createTypeCount;
// Split the statement by semicolon to check for multiple statements
const statements = statement.split(';').filter(s => s.trim().length > 0);
// Return true only if there is exactly one statement and exactly one CREATE ENUM or TYPE
return statements.length === 1 && totalCreateStatements === 1;
}
}
exports.CreateEnumsProcessor = CreateEnumsProcessor;