hirejared-kw-db/docs/project-docs/03-scripts/table-admin/alter-tables.md
2024-11-19 07:52:08 -05:00

6.3 KiB

Table Alteration Scripts Documentation

Overview

These scripts handle modifications to existing database tables in the keyword management system. Proper version control and change tracking are essential for table alterations.

Script Location Structure

/bin/table-admin/alter-tables/
├── versions/
│   ├── 20241119_01_add_column_keywords.sh
│   ├── 20241119_02_modify_column_type.sh
│   └── [YYYYMMDD]_[XX]_[description].sh
├── execute-version.sh
└── rollback-version.sh

Version Naming Convention

  • Format: YYYYMMDD_XX_description.sh
  • YYYYMMDD: Date of creation
  • XX: Sequential number for multiple changes on same day
  • description: Brief description using kebab-case
  • Example: 20241119_01_add_status_to_keywords.sh

Script Template Structure

Version Script Template

#!/bin/bash

# Load configuration
source ../../../../.database

# Version metadata
VERSION_ID="20241119_01"
VERSION_DESC="Add status column to Keywords table"

# Set error handling
set -e

# Setup logging
LOG_DIR="../../../../logs"
LOG_FILE="${LOG_DIR}/$(date +%Y-%m-%d)-${VERSION_ID}.log"

mkdir -p "$LOG_DIR"

# Function to log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Upgrade function
upgrade() {
    log_message "Executing upgrade for version ${VERSION_ID}"
    
    psql -h "${DB_HOST}" \
         -p "${DB_PORT}" \
         -U "${DB_USER}" \
         -d "${DB_NAME}" \
         -c "ALTER TABLE Keywords ADD COLUMN status VARCHAR(50) NOT NULL DEFAULT 'active';"
         
    # Record the change in version history
    psql -h "${DB_HOST}" \
         -p "${DB_PORT}" \
         -U "${DB_USER}" \
         -d "${DB_NAME}" \
         -c "INSERT INTO version_history (version_id, description, applied_at) 
             VALUES ('${VERSION_ID}', '${VERSION_DESC}', CURRENT_TIMESTAMP);"
}

# Rollback function
rollback() {
    log_message "Executing rollback for version ${VERSION_ID}"
    
    psql -h "${DB_HOST}" \
         -p "${DB_PORT}" \
         -U "${DB_USER}" \
         -d "${DB_NAME}" \
         -c "ALTER TABLE Keywords DROP COLUMN status;"
         
    # Remove version from history
    psql -h "${DB_HOST}" \
         -p "${DB_PORT}" \
         -U "${DB_USER}" \
         -d "${DB_NAME}" \
         -c "DELETE FROM version_history WHERE version_id = '${VERSION_ID}';"
}

# Version check function
version_exists() {
    local exists=$(psql -h "${DB_HOST}" \
                       -p "${DB_PORT}" \
                       -U "${DB_USER}" \
                       -d "${DB_NAME}" \
                       -tAc "SELECT 1 FROM version_history WHERE version_id = '${VERSION_ID}';")
    [ "$exists" = "1" ]
}

# Execute based on command argument
case "$1" in
    "upgrade")
        if version_exists; then
            log_message "Version ${VERSION_ID} already applied"
            exit 0
        fi
        upgrade
        ;;
    "rollback")
        if ! version_exists; then
            log_message "Version ${VERSION_ID} not applied"
            exit 0
        fi
        rollback
        ;;
    *)
        echo "Usage: $0 {upgrade|rollback}"
        exit 1
        ;;
esac

Version Control Table

CREATE TABLE version_history (
    version_id VARCHAR(50) PRIMARY KEY,
    description TEXT NOT NULL,
    applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    rolled_back_at TIMESTAMP
);

Execute Version Script

#!/bin/bash

# Load configuration
source ../../../.database

# Set error handling
set -e

# Check arguments
if [ $# -ne 2 ]; then
    echo "Usage: $0 <version_id> <upgrade|rollback>"
    exit 1
fi

VERSION_ID=$1
ACTION=$2

# Find version script
SCRIPT_PATH="versions/${VERSION_ID}_*.sh"
SCRIPT_FILE=$(ls $SCRIPT_PATH 2>/dev/null || true)

if [ -z "$SCRIPT_FILE" ]; then
    echo "Error: Version script not found for ${VERSION_ID}"
    exit 1
fi

# Execute version script
bash "$SCRIPT_FILE" "$ACTION"

Example Alterations

Add Column

-- Version: 20241119_01_add_status_to_keywords.sh
ALTER TABLE Keywords 
ADD COLUMN status VARCHAR(50) NOT NULL DEFAULT 'active';

Modify Column Type

-- Version: 20241119_02_modify_cpc_precision.sh
ALTER TABLE Keywords 
ALTER COLUMN gkwp_cpc_min TYPE DECIMAL(12,4),
ALTER COLUMN gkwp_cpc_max TYPE DECIMAL(12,4);

Add Index

-- Version: 20241119_03_add_keyword_search_index.sh
CREATE INDEX idx_keyword_search 
ON Keywords USING gin (keyword gin_trgm_ops);

Testing

Located in /tests/table-admin/alter-tables/

Example test:

#!/bin/bash

source ../../utils/test-framework.sh

test_version_execution() {
    # Setup
    VERSION_ID="20241119_01"
    
    # Test upgrade
    ../bin/table-admin/alter-tables/execute-version.sh "$VERSION_ID" upgrade
    
    # Verify column added
    column_check=$(psql -tAc "\d keywords" "${DB_NAME}")
    assert_contains "$column_check" "status" "Status column should exist"
    
    # Verify version recorded
    version_check=$(psql -tAc "SELECT 1 FROM version_history WHERE version_id = '${VERSION_ID}';" "${DB_NAME}")
    assert_equals "$version_check" "1" "Version should be recorded"
    
    # Test rollback
    ../bin/table-admin/alter-tables/execute-version.sh "$VERSION_ID" rollback
    
    # Verify column removed
    column_check=$(psql -tAc "\d keywords" "${DB_NAME}")
    assert_not_contains "$column_check" "status" "Status column should not exist"
}

run_test_suite

Best Practices

  1. Version Control

    • All changes tracked in version_history table
    • Unique version identifiers
    • Clear descriptions of changes
    • Timestamp tracking
  2. Reversibility

    • All changes must have rollback functionality
    • Rollbacks tested before deployment
    • Data preservation considered
  3. Safety Checks

    • Version existence verification
    • Dependency checking
    • Backup verification
    • Error handling
  4. Documentation

    • Clear change descriptions
    • Impact assessment
    • Dependencies noted
    • Testing requirements
  5. Testing

    • Upgrade testing
    • Rollback testing
    • Integration testing
    • Performance impact assessment