PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); echo "Connecting to Supabase PostgreSQL...\n"; $dsn = "pgsql:host=$supabaseHost;port=$supabasePort;dbname=$supabaseDb"; $supabasePdo = new PDO($dsn, $supabaseUser, $dbPassword, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]); echo "Converting and creating tables in Supabase...\n"; // Define tables and their PostgreSQL schemas $schemas = [ "users" => "CREATE TABLE IF NOT EXISTS users ( id VARCHAR(255) PRIMARY KEY, supabase_uid VARCHAR(255), student_id VARCHAR(10) UNIQUE NOT NULL, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255), grade_level INTEGER, track VARCHAR(100), section VARCHAR(100), role VARCHAR(50) DEFAULT 'Voter', access_level INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP )", "elections" => "CREATE TABLE IF NOT EXISTS elections ( id VARCHAR(255) PRIMARY KEY, title VARCHAR(255) NOT NULL, description TEXT, status VARCHAR(50) DEFAULT 'Preparing', start_date_and_time TIMESTAMP NOT NULL, end_date_and_time TIMESTAMP NOT NULL, created_by VARCHAR(255) REFERENCES users(id), archived BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )", "positions" => "CREATE TABLE IF NOT EXISTS positions ( id VARCHAR(255) PRIMARY KEY, election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, type VARCHAR(50) DEFAULT 'Uniform', max_votes INTEGER DEFAULT 1, sort_order INTEGER DEFAULT 0 )", "candidates" => "CREATE TABLE IF NOT EXISTS candidates ( id VARCHAR(255) PRIMARY KEY, election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE, position_id VARCHAR(255) REFERENCES positions(id) ON DELETE CASCADE, user_id VARCHAR(255) REFERENCES users(id) ON DELETE CASCADE, party_name VARCHAR(255), manifesto TEXT, approved BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )", "votes" => "CREATE TABLE IF NOT EXISTS votes ( id VARCHAR(255) PRIMARY KEY, election_id VARCHAR(255) REFERENCES elections(id), position_id VARCHAR(255) REFERENCES positions(id), candidate_id VARCHAR(255) REFERENCES candidates(id), voter_id VARCHAR(255) REFERENCES users(id), casted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ip_address VARCHAR(45), user_agent TEXT, UNIQUE (election_id, position_id, voter_id) )", "election_assignments" => "CREATE TABLE IF NOT EXISTS election_assignments ( id VARCHAR(255) PRIMARY KEY, election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE, user_id VARCHAR(255) REFERENCES users(id) ON DELETE CASCADE, role_in_election VARCHAR(50) DEFAULT 'Voter', assigned_by VARCHAR(255) REFERENCES users(id), assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )", "parties" => "CREATE TABLE IF NOT EXISTS parties ( id VARCHAR(255) PRIMARY KEY, election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, description TEXT, logo_url TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )", "audit_logs" => "CREATE TABLE IF NOT EXISTS audit_logs ( id VARCHAR(255) PRIMARY KEY, user_id VARCHAR(255) REFERENCES users(id), action VARCHAR(255) NOT NULL, details TEXT, table_name VARCHAR(100), record_id VARCHAR(255), old_values TEXT, new_values TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, election_id VARCHAR(255) REFERENCES elections(id) ON DELETE CASCADE )" ]; foreach ($schemas as $tableName => $sql) { echo "Creating table: $tableName...\n"; $supabasePdo->exec($sql); } echo "Migrating data...\n"; $tables = array_keys($schemas); // Order matters for foreign keys: users, elections, positions, candidates, assignments, votes, audit_logs $orderedTables = ["users", "elections", "positions", "election_assignments", "parties", "candidates", "votes", "audit_logs"]; foreach ($orderedTables as $table) { echo "Migrating data for $table...\n"; $stmt = $localPdo->query("SELECT * FROM $table"); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($rows)) { echo "No data for $table.\n"; continue; } $columns = array_keys($rows[0]); $placeholders = implode(',', array_fill(0, count($columns), '?')); $insertSql = "INSERT INTO $table (" . implode(',', $columns) . ") VALUES ($placeholders) ON CONFLICT (id) DO NOTHING"; $insertStmt = $supabasePdo->prepare($insertSql); $count = 0; foreach ($rows as $row) { $insertStmt->execute(array_values($row)); $count++; } echo "Migrated $count rows for $table.\n"; } echo "Migration completed successfully!\n"; } catch (Exception $e) { echo "Error: " . $e->getMessage() . "\n"; exit(1); }