rc-migration-tests/ef-migration/infrastructure/sql-server/extract_procedures.sh
2025-02-05 01:18:33 +00:00

167 lines
5.4 KiB
Bash
Executable File

#!/bin/bash
# Check if input file is provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <sql_file>"
exit 1
fi
SQL_FILE="$1"
BASE_DIR="sql_objects"
# Create directory structure
mkdir -p "$BASE_DIR/procedures"
# Ensure proper permissions
chmod -R 755 "$BASE_DIR"
# Function to clean filename
clean_filename() {
# Remove brackets, convert dots and spaces to underscores, remove parentheses
echo "$1" | sed 's/\[\|\]//g' | tr '.' '_' | tr ' ' '_' | sed 's/[()]//g' | sed 's/__*/_/g' | sed 's/_$//'
}
# Function to extract procedure name
extract_procedure_name() {
# More flexible procedure name extraction
local name=$(echo "$1" | sed -nE 's/.*CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+(\[[^]]+\](\.[^]]+)?|\S+).*/\2/pi' | tr -d '[]')
echo "$name"
}
# Function to extract schema name (if present)
extract_schema_name() {
# Extract schema name with more flexible matching
local schema=$(echo "$1" | sed -nE 's/.*CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+\[?([^.]+)\.([^]]+)\]?.*/\2/pi')
if [ -z "$schema" ]; then
# Try alternative extraction
schema=$(echo "$1" | sed -nE 's/.*CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+\[?([^]]+)\]?.*/\2/pi' | cut -d. -f1)
fi
if [ -z "$schema" ]; then
echo "dbo" # Default schema if not specified
else
echo "$schema" | tr -d '[]'
fi
}
# Function to process each procedure statement
process_procedure() {
local procedure_statement="$1"
local procedure_name=$(extract_procedure_name "$procedure_statement")
local schema_name=$(extract_schema_name "$procedure_statement")
# Skip if we couldn't extract procedure name
if [ -z "$procedure_name" ]; then
echo "Warning: Could not extract procedure name from:"
echo "$procedure_statement"
return
fi
# Clean filename and save
clean_name=$(clean_filename "${schema_name}_${procedure_name}")
output_file="$BASE_DIR/procedures/${clean_name}.sql"
# Trim whitespace and ensure semicolon at end if not already present
procedure_statement=$(echo "$procedure_statement" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [[ "$procedure_statement" != *\; ]]; then
procedure_statement="${procedure_statement};"
fi
# Save the procedure
echo "$procedure_statement" > "$output_file"
echo "Created: $output_file"
}
# Main processing function
extract_procedures() {
local current_statement=""
local capturing_procedure=false
local depth=0
# Disable case sensitivity
shopt -s nocasematch
# Read the file line by line
while IFS= read -r line || [ -n "$line" ]; do
# Skip empty lines and pure comment lines
if [ -z "${line// }" ] || [[ "$line" =~ ^[[:space:]]*-- ]]; then
continue
fi
# Check for procedure start (more flexible)
if [[ "$line" =~ CREATE[[:space:]]+PROC(EDURE)?[[:space:]]+ ]]; then
# Process previous statement if any
if [ -n "$current_statement" ] && $capturing_procedure; then
process_procedure "$current_statement"
fi
# Start new procedure statement
current_statement="$line"
capturing_procedure=true
depth=0
# Check if GO is on the same line
if [[ "$line" =~ GO[[:space:]]*$ ]]; then
# Remove GO and process
current_statement=$(echo "$current_statement" | sed 's/[[:space:]]*GO[[:space:]]*$//')
process_procedure "$current_statement"
current_statement=""
capturing_procedure=false
fi
continue
fi
# If we're capturing a procedure
if $capturing_procedure; then
# Track BEGIN/END blocks to ensure we capture the entire procedure
if [[ "$line" =~ BEGIN ]]; then
((depth++))
fi
if [[ "$line" =~ END ]]; then
((depth--))
fi
# Add line to current statement
current_statement+=" $line"
# Check for GO statement or end of procedure
if [[ "$line" =~ ^[[:space:]]*GO[[:space:]]*$ ]] ||
([[ "$line" =~ END ]] && [[ $depth -le 0 ]]); then
# Remove GO and process
current_statement=$(echo "$current_statement" | sed 's/[[:space:]]*GO[[:space:]]*$//; s/;[[:space:]]*$//')
process_procedure "$current_statement"
current_statement=""
capturing_procedure=false
depth=0
fi
fi
done
# Process any remaining procedure statement
if [ -n "$current_statement" ] && $capturing_procedure; then
process_procedure "$current_statement"
fi
# Re-enable case sensitivity
shopt -u nocasematch
}
# Remove comment lines and process
echo "Extracting stored procedures..."
sed 's/--.*$//' "$SQL_FILE" | extract_procedures
echo "Stored procedures have been saved in $BASE_DIR/procedures"
# Count and list files
count=$(ls -1 "$BASE_DIR/procedures"/*.sql 2>/dev/null | wc -l || echo 0)
echo -e "\nTotal stored procedures extracted: $count"
if [ "$count" -gt 0 ]; then
echo -e "\nExtracted stored procedures:"
for file in "$BASE_DIR/procedures"/*.sql; do
if [ -f "$file" ]; then
echo "- $(basename "$file")"
fi
done
fi