#!/bin/bash # C Nostr Relay Database Initialization Script # Creates and initializes the SQLite database with proper schema set -e # Exit on any error # Configuration DB_DIR="$(dirname "$0")" DB_NAME="c_nostr_relay.db" DB_PATH="${DB_DIR}/${DB_NAME}" SCHEMA_FILE="${DB_DIR}/schema.sql" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Logging functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Check if SQLite3 is installed check_sqlite() { if ! command -v sqlite3 &> /dev/null; then log_error "sqlite3 is not installed. Please install it first:" echo " Ubuntu/Debian: sudo apt-get install sqlite3" echo " CentOS/RHEL: sudo yum install sqlite" echo " macOS: brew install sqlite3" exit 1 fi local version=$(sqlite3 --version | cut -d' ' -f1) log_info "Using SQLite version: $version" } # Create database directory if it doesn't exist create_db_directory() { if [ ! -d "$DB_DIR" ]; then log_info "Creating database directory: $DB_DIR" mkdir -p "$DB_DIR" fi } # Backup existing database if it exists backup_existing_db() { if [ -f "$DB_PATH" ]; then local backup_path="${DB_PATH}.backup.$(date +%Y%m%d_%H%M%S)" log_warning "Existing database found. Creating backup: $backup_path" cp "$DB_PATH" "$backup_path" fi } # Initialize the database with schema init_database() { log_info "Initializing database: $DB_PATH" if [ ! -f "$SCHEMA_FILE" ]; then log_error "Schema file not found: $SCHEMA_FILE" exit 1 fi # Remove existing database if --force flag is used if [ "$1" = "--force" ] && [ -f "$DB_PATH" ]; then log_warning "Force flag detected. Removing existing database." rm -f "$DB_PATH" fi # Create the database and apply schema log_info "Applying schema from: $SCHEMA_FILE" if sqlite3 "$DB_PATH" < "$SCHEMA_FILE"; then log_success "Database schema applied successfully" else log_error "Failed to apply database schema" exit 1 fi } # Verify database integrity verify_database() { log_info "Verifying database integrity..." # Check if database file exists and is not empty if [ ! -s "$DB_PATH" ]; then log_error "Database file is empty or doesn't exist" exit 1 fi # Run SQLite integrity check local integrity_result=$(sqlite3 "$DB_PATH" "PRAGMA integrity_check;") if [ "$integrity_result" = "ok" ]; then log_success "Database integrity check passed" else log_error "Database integrity check failed: $integrity_result" exit 1 fi # Verify schema version local schema_version=$(sqlite3 "$DB_PATH" "PRAGMA user_version;") log_info "Database schema version: $schema_version" # Check that main tables exist local table_count=$(sqlite3 "$DB_PATH" "SELECT count(*) FROM sqlite_master WHERE type='table' AND name IN ('events', 'schema_info');") if [ "$table_count" -eq 2 ]; then log_success "Core tables created successfully" else log_error "Missing core tables (expected 2, found $table_count)" exit 1 fi } # Display database information show_db_info() { log_info "Database Information:" echo " Location: $DB_PATH" echo " Size: $(du -h "$DB_PATH" | cut -f1)" log_info "Database Tables:" sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;" | sed 's/^/ - /' log_info "Database Indexes:" sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='index' AND name NOT LIKE 'sqlite_%' ORDER BY name;" | sed 's/^/ - /' log_info "Database Views:" sqlite3 "$DB_PATH" "SELECT name FROM sqlite_master WHERE type='view' ORDER BY name;" | sed 's/^/ - /' } # Run database optimization optimize_database() { log_info "Running database optimization..." sqlite3 "$DB_PATH" "PRAGMA optimize; VACUUM; ANALYZE;" log_success "Database optimization completed" } # Print usage information print_usage() { echo "Usage: $0 [OPTIONS]" echo "" echo "Initialize SQLite database for C Nostr Relay" echo "" echo "Options:" echo " --force Remove existing database before initialization" echo " --info Show database information after initialization" echo " --optimize Run database optimization after initialization" echo " --help Show this help message" echo "" echo "Examples:" echo " $0 # Initialize database (with backup if exists)" echo " $0 --force # Force reinitialize database" echo " $0 --info --optimize # Initialize with info and optimization" } # Main execution main() { local force_flag=false local show_info=false local optimize=false # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in --force) force_flag=true shift ;; --info) show_info=true shift ;; --optimize) optimize=true shift ;; --help) print_usage exit 0 ;; *) log_error "Unknown option: $1" print_usage exit 1 ;; esac done log_info "Starting C Nostr Relay database initialization..." # Execute initialization steps check_sqlite create_db_directory if [ "$force_flag" = false ]; then backup_existing_db fi if [ "$force_flag" = true ]; then init_database --force else init_database fi verify_database if [ "$optimize" = true ]; then optimize_database fi if [ "$show_info" = true ]; then show_db_info fi log_success "Database initialization completed successfully!" echo "" echo "Database ready at: $DB_PATH" echo "You can now start your C Nostr Relay application." } # Execute main function with all arguments main "$@"