"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareDropIndexesJson = exports.prepareCreateReferencesJson = exports.prepareCreateIndexesJson = exports.prepareAlterTableColumnsJson = exports.prepareRenameColumns = exports.prepareAddValuesToEnumJson = exports.prepareCreateEnumJson = exports.prepareRenameTableJson = exports.prepareDropTableJson = exports.prepareCreateTableJson = void 0;
const prepareCreateTableJson = (table) => {
    const { name, columns } = table;
    return {
        type: 'create_table',
        tableName: name,
        columns: Object.values(columns)
    };
};
exports.prepareCreateTableJson = prepareCreateTableJson;
const prepareDropTableJson = (table) => {
    return {
        type: 'drop_table',
        tableName: table.name
    };
};
exports.prepareDropTableJson = prepareDropTableJson;
const prepareRenameTableJson = (tableFrom, tableTo) => {
    return {
        type: 'rename_table',
        tableNameFrom: tableFrom.name,
        tableNameTo: tableTo.name
    };
};
exports.prepareRenameTableJson = prepareRenameTableJson;
const prepareCreateEnumJson = (name, values) => {
    return {
        type: 'create_type_enum',
        name: name,
        values
    };
};
exports.prepareCreateEnumJson = prepareCreateEnumJson;
// https://blog.yo1.dog/updating-enum-values-in-postgresql-the-safe-and-easy-way/
const prepareAddValuesToEnumJson = (name, values) => {
    return values.map(it => {
        return {
            type: 'alter_type_add_value',
            name: name,
            value: it
        };
    });
};
exports.prepareAddValuesToEnumJson = prepareAddValuesToEnumJson;
const prepareRenameColumns = (tableName, pairs) => {
    return pairs.map(it => {
        return {
            type: 'alter_table_rename_column',
            tableName: tableName,
            oldColumnName: it.from.name,
            newColumnName: it.to.name,
        };
    });
};
exports.prepareRenameColumns = prepareRenameColumns;
const prepareAlterTableColumnsJson = (tableName, deleted, added, altered) => {
    const statements = [];
    const dropColumns = _prepareDropColumns(tableName, deleted);
    const addColumns = _prepareAddColumns(tableName, added);
    const alterColumns = _prepareAlterColumns(tableName, altered);
    statements.push(...dropColumns);
    statements.push(...addColumns);
    statements.push(...alterColumns);
    return statements;
};
exports.prepareAlterTableColumnsJson = prepareAlterTableColumnsJson;
const _prepareDropColumns = (taleName, columns) => {
    return columns.map(it => {
        return {
            type: 'alter_table_drop_column',
            tableName: taleName,
            columnName: it.name
        };
    });
};
const _prepareAddColumns = (tableName, columns) => {
    return columns.map(it => {
        return {
            type: 'alter_table_add_column',
            tableName: tableName,
            column: it
        };
    });
};
const _prepareAlterColumns = (tableName, columns) => {
    let statements = [];
    for (const column of columns) {
        // TODO: rename column
        const columnName = typeof column.name !== 'string' ? column.name.new : column.name;
        if (typeof column.name !== 'string') {
            statements.push({
                type: 'alter_table_rename_column',
                tableName,
                oldColumnName: column.name.old,
                newColumnName: column.name.new
            });
        }
        if (column.type?.type === 'changed') {
            statements.push({
                type: 'alter_table_alter_column_set_type',
                tableName,
                columnName,
                newDataType: column.type.new
            });
        }
        if (column.defaultValue?.type === 'added') {
            statements.push({
                type: 'alter_table_alter_column_set_default',
                tableName,
                columnName,
                newDefaultValue: column.defaultValue.value
            });
        }
        if (column.defaultValue?.type === 'changed') {
            statements.push({
                type: 'alter_table_alter_column_set_default',
                tableName,
                columnName,
                newDefaultValue: column.defaultValue.new
            });
        }
        if (column.defaultValue?.type === 'deleted') {
            statements.push({
                type: 'alter_table_alter_column_drop_default',
                tableName,
                columnName,
            });
        }
        if (column.notNull?.type === 'added') {
            statements.push({
                type: 'alter_table_alter_column_set_notnull',
                tableName,
                columnName
            });
        }
        if (column.notNull?.type === 'changed') {
            const type = column.notNull.new ? 'alter_table_alter_column_set_notnull' : 'alter_table_alter_column_drop_notnull';
            statements.push({
                type: type,
                tableName,
                columnName
            });
        }
        if (column.notNull?.type === 'deleted') {
            statements.push({
                type: 'alter_table_alter_column_drop_notnull',
                tableName,
                columnName
            });
        }
    }
    return statements;
};
const prepareCreateIndexesJson = (tableName, indexes) => {
    return indexes.map(index => {
        return {
            type: 'create_index',
            tableName,
            indexName: index.name,
            value: index.columns.join(', '),
            isUnique: index.isUnique,
        };
    });
};
exports.prepareCreateIndexesJson = prepareCreateIndexesJson;
const prepareCreateReferencesJson = (tableName, columns) => {
    return columns.filter(it => {
        return it.references !== undefined;
    }).map(entry => {
        const column = entry;
        const references = column.references;
        return {
            type: 'create_reference',
            fromTable: tableName,
            toTable: references.table,
            fromColumn: column.name,
            toColumn: references.column,
            foreignKeyName: references.foreignKeyName,
            onDelete: references.onDelete,
            onUpdate: references.onUpdate,
        };
    });
};
exports.prepareCreateReferencesJson = prepareCreateReferencesJson;
const prepareDropIndexesJson = (tableName, indexes) => {
    return indexes.map(index => {
        return {
            type: 'drop_index',
            tableName,
            indexName: index.name,
        };
    });
};
exports.prepareDropIndexesJson = prepareDropIndexesJson;
//# sourceMappingURL=jsonStatements.js.map