- Move all non-wrapper files (testing scripts, documentation, utilities) to misc/ directory - Keep SF CLI wrapper scripts and README.md in root directory for better organization - Maintain clean root directory with only the actual wrapper scripts and main documentation - All wrapper scripts remain easily accessible and discoverable - Supporting files are organized in misc/ subdirectory
323 lines
9.1 KiB
Bash
Executable File
323 lines
9.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Data export wrapper for Salesforce CLI
|
|
# Provides streamlined data export functionality with SOQL query support
|
|
|
|
# Color codes for output formatting
|
|
readonly RED='\033[0;31m'
|
|
readonly GREEN='\033[0;32m'
|
|
readonly YELLOW='\033[0;33m'
|
|
readonly BLUE='\033[0;34m'
|
|
readonly CYAN='\033[0;36m'
|
|
readonly GRAY='\033[0;37m'
|
|
readonly NC='\033[0m' # No Color
|
|
|
|
# Function to display usage information
|
|
show_usage() {
|
|
echo -e "${BLUE}sf-data-export - Data Export Wrapper for Salesforce CLI${NC}"
|
|
echo ""
|
|
echo "USAGE:"
|
|
echo " sf-data-export [OPTIONS]"
|
|
echo ""
|
|
echo "OPTIONS:"
|
|
echo " -qy SOQL query to export data"
|
|
echo " -fl File containing SOQL query"
|
|
echo " -so Standard object query (exports all records)"
|
|
echo " -to Target org username or alias"
|
|
echo " -ot Output file path (default: export.csv)"
|
|
echo " -fm Output format: csv, json (default: csv)"
|
|
echo " -bk Use bulk API for large datasets"
|
|
echo " -wt Wait time in minutes (default: 10)"
|
|
echo " -ve Enable verbose output"
|
|
echo " -hp Show this help message"
|
|
echo ""
|
|
echo "EXAMPLES:"
|
|
echo " sf-data-export -qy \"SELECT Id, Name FROM Account LIMIT 100\""
|
|
echo " sf-data-export -so Account -fm json -ot accounts.json"
|
|
echo " sf-data-export -fl queries/contacts.soql -bk -wt 15"
|
|
echo " sf-data-export -qy \"SELECT Id FROM User\" -to production"
|
|
echo ""
|
|
echo "This script automatically checks for Salesforce CLI installation."
|
|
}
|
|
|
|
# Function to check if Salesforce CLI is installed
|
|
check_salesforce_cli() {
|
|
if ! command -v sf &> /dev/null; then
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Function to run sf-check diagnostics
|
|
run_salesforce_check() {
|
|
if [[ -f "sf-check" ]]; then
|
|
echo -e "${YELLOW}Running Salesforce CLI diagnostics...${NC}"
|
|
./sf-check
|
|
elif [[ -f "sf-check.sh" ]]; then
|
|
echo -e "${YELLOW}Running Salesforce CLI diagnostics...${NC}"
|
|
bash sf-check.sh
|
|
elif [[ -f "sf-check.ps1" ]]; then
|
|
echo -e "${YELLOW}Running Salesforce CLI diagnostics...${NC}"
|
|
pwsh sf-check.ps1
|
|
else
|
|
echo -e "${RED}Salesforce CLI not found and no diagnostic script available.${NC}"
|
|
echo -e "${RED}Please install the Salesforce CLI: https://developer.salesforce.com/tools/salesforcecli${NC}"
|
|
fi
|
|
}
|
|
|
|
# Function to validate SOQL query
|
|
validate_query() {
|
|
local query="$1"
|
|
|
|
# Basic validation - check if it starts with SELECT
|
|
if [[ ! "$query" =~ ^[[:space:]]*[Ss][Ee][Ll][Ee][Cc][Tt] ]]; then
|
|
echo -e "${RED}Error: Query must start with SELECT${NC}"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Function to build standard object query
|
|
build_sobject_query() {
|
|
local sobject="$1"
|
|
|
|
# For common objects, use sensible field selections
|
|
case "$sobject" in
|
|
"Account")
|
|
echo "SELECT Id, Name, Type, Industry, Phone, Website, BillingCity, BillingState, BillingCountry FROM Account"
|
|
;;
|
|
"Contact")
|
|
echo "SELECT Id, FirstName, LastName, Email, Phone, AccountId, Account.Name FROM Contact"
|
|
;;
|
|
"Lead")
|
|
echo "SELECT Id, FirstName, LastName, Email, Phone, Company, Status, Source FROM Lead"
|
|
;;
|
|
"Opportunity")
|
|
echo "SELECT Id, Name, AccountId, Account.Name, Amount, CloseDate, StageName, Probability FROM Opportunity"
|
|
;;
|
|
"Case")
|
|
echo "SELECT Id, CaseNumber, Subject, Status, Priority, Origin, AccountId, Account.Name, ContactId, Contact.Name FROM Case"
|
|
;;
|
|
"User")
|
|
echo "SELECT Id, Name, Email, Username, Profile.Name, IsActive, LastLoginDate FROM User"
|
|
;;
|
|
*)
|
|
# Generic query for other objects
|
|
echo "SELECT Id, Name FROM $sobject"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Initialize variables
|
|
QUERY=""
|
|
QUERY_FILE=""
|
|
SOBJECT=""
|
|
OUTPUT_FILE="export.csv"
|
|
TARGET_ORG=""
|
|
FORMAT="csv"
|
|
USE_BULK=false
|
|
WAIT_TIME="10"
|
|
VERBOSE=false
|
|
|
|
# Show help if no arguments provided
|
|
if [[ $# -eq 0 ]]; then
|
|
show_usage
|
|
exit 0
|
|
fi
|
|
|
|
# Parse command line arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-qy)
|
|
QUERY="$2"
|
|
shift 2
|
|
;;
|
|
-fl)
|
|
QUERY_FILE="$2"
|
|
shift 2
|
|
;;
|
|
-so)
|
|
SOBJECT="$2"
|
|
shift 2
|
|
;;
|
|
-to)
|
|
TARGET_ORG="$2"
|
|
shift 2
|
|
;;
|
|
-ot)
|
|
OUTPUT_FILE="$2"
|
|
shift 2
|
|
;;
|
|
-fm)
|
|
FORMAT="$2"
|
|
shift 2
|
|
;;
|
|
-bk)
|
|
USE_BULK=true
|
|
shift
|
|
;;
|
|
-wt)
|
|
WAIT_TIME="$2"
|
|
shift 2
|
|
;;
|
|
-ve)
|
|
VERBOSE=true
|
|
shift
|
|
;;
|
|
-hp)
|
|
show_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo -e "${RED}Unknown option: $1${NC}"
|
|
echo ""
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Silently check for Salesforce CLI
|
|
if ! check_salesforce_cli; then
|
|
run_salesforce_check
|
|
exit 1
|
|
fi
|
|
|
|
# Validate that exactly one query method is specified
|
|
query_methods=0
|
|
[[ -n "$QUERY" ]] && ((query_methods++))
|
|
[[ -n "$QUERY_FILE" ]] && ((query_methods++))
|
|
[[ -n "$SOBJECT" ]] && ((query_methods++))
|
|
|
|
if [[ $query_methods -eq 0 ]]; then
|
|
echo -e "${RED}Error: Must specify one of: -qy, -fl, or -so${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Usage examples:${NC}"
|
|
echo -e "${GRAY} sf-data-export -qy \"SELECT Id, Name FROM Account\"${NC}"
|
|
echo -e "${GRAY} sf-data-export -fl queries/accounts.soql${NC}"
|
|
echo -e "${GRAY} sf-data-export -so Account${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Use -hp for detailed usage information.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ $query_methods -gt 1 ]]; then
|
|
echo -e "${RED}Error: Can only specify one of: -qy, -fl, or -so${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Validate format
|
|
if [[ "$FORMAT" != "csv" && "$FORMAT" != "json" ]]; then
|
|
echo -e "${RED}Error: Format must be 'csv' or 'json'${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Determine the final query
|
|
FINAL_QUERY=""
|
|
if [[ -n "$QUERY" ]]; then
|
|
FINAL_QUERY="$QUERY"
|
|
echo -e "${GREEN}Using inline query${NC}"
|
|
elif [[ -n "$QUERY_FILE" ]]; then
|
|
if [[ ! -f "$QUERY_FILE" ]]; then
|
|
echo -e "${RED}Error: Query file not found: $QUERY_FILE${NC}"
|
|
exit 1
|
|
fi
|
|
FINAL_QUERY=$(cat "$QUERY_FILE")
|
|
echo -e "${GREEN}Using query from file: $QUERY_FILE${NC}"
|
|
elif [[ -n "$SOBJECT" ]]; then
|
|
FINAL_QUERY=$(build_sobject_query "$SOBJECT")
|
|
echo -e "${GREEN}Using standard query for $SOBJECT${NC}"
|
|
fi
|
|
|
|
# Validate the query
|
|
if ! validate_query "$FINAL_QUERY"; then
|
|
exit 1
|
|
fi
|
|
|
|
# Build the sf command based on bulk vs regular query
|
|
if [[ "$USE_BULK" == true ]]; then
|
|
# Use Bulk API 2.0 for large datasets
|
|
SF_ARGS=("data" "export" "bulk")
|
|
SF_ARGS+=("--query" "$FINAL_QUERY")
|
|
SF_ARGS+=("--output-file" "$OUTPUT_FILE")
|
|
SF_ARGS+=("--result-format" "$FORMAT")
|
|
|
|
if [[ "$WAIT_TIME" != "10" ]]; then
|
|
SF_ARGS+=("--wait" "$WAIT_TIME")
|
|
fi
|
|
|
|
echo -e "${YELLOW}Using Bulk API 2.0${NC}"
|
|
else
|
|
# Use regular data query for smaller datasets
|
|
SF_ARGS=("data" "query")
|
|
SF_ARGS+=("--query" "$FINAL_QUERY")
|
|
SF_ARGS+=("--output-file" "$OUTPUT_FILE")
|
|
SF_ARGS+=("--result-format" "$FORMAT")
|
|
fi
|
|
|
|
# Add optional parameters
|
|
if [[ -n "$TARGET_ORG" ]]; then
|
|
SF_ARGS+=("--target-org" "$TARGET_ORG")
|
|
echo -e "${CYAN}Target org: $TARGET_ORG${NC}"
|
|
fi
|
|
|
|
echo -e "${CYAN}Output format: $FORMAT${NC}"
|
|
echo -e "${CYAN}Output file: $OUTPUT_FILE${NC}"
|
|
|
|
# Add verbose flag if requested
|
|
if [[ "$VERBOSE" == true ]]; then
|
|
SF_ARGS+=("--verbose")
|
|
fi
|
|
|
|
# Display export information
|
|
echo ""
|
|
echo -e "${BLUE}📊 Starting Data Export${NC}"
|
|
echo -e "${BLUE}=======================${NC}"
|
|
|
|
# Show query preview if verbose
|
|
if [[ "$VERBOSE" == true ]]; then
|
|
echo ""
|
|
echo -e "${YELLOW}📝 SOQL Query:${NC}"
|
|
echo -e "${GRAY}----------------------------------------${NC}"
|
|
echo -e "${GRAY}$FINAL_QUERY${NC}"
|
|
echo -e "${GRAY}----------------------------------------${NC}"
|
|
fi
|
|
|
|
# Display the command being run
|
|
echo ""
|
|
echo -e "${GRAY}Executing: sf ${SF_ARGS[*]}${NC}"
|
|
echo ""
|
|
|
|
# Execute the command
|
|
if sf "${SF_ARGS[@]}"; then
|
|
EXPORT_EXIT_CODE=0
|
|
else
|
|
EXPORT_EXIT_CODE=$?
|
|
fi
|
|
|
|
echo ""
|
|
if [[ $EXPORT_EXIT_CODE -eq 0 ]]; then
|
|
echo -e "${GREEN}✅ Data export completed successfully!${NC}"
|
|
|
|
# Show file information if it exists
|
|
if [[ -f "$OUTPUT_FILE" ]]; then
|
|
FILE_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
|
|
if [[ "$FORMAT" == "csv" ]]; then
|
|
# Count records (excluding header)
|
|
RECORD_COUNT=$(($(wc -l < "$OUTPUT_FILE") - 1))
|
|
echo -e "${CYAN}📁 Exported $RECORD_COUNT records to $OUTPUT_FILE ($FILE_SIZE)${NC}"
|
|
else
|
|
echo -e "${CYAN}📁 Data exported to $OUTPUT_FILE ($FILE_SIZE)${NC}"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$VERBOSE" == true ]]; then
|
|
echo -e "${YELLOW}💡 Use a spreadsheet application or text editor to view the exported data${NC}"
|
|
fi
|
|
else
|
|
echo -e "${RED}❌ Data export failed with exit code: $EXPORT_EXIT_CODE${NC}"
|
|
echo -e "${YELLOW}💡 Check query syntax and permissions${NC}"
|
|
exit $EXPORT_EXIT_CODE
|
|
fi
|