38458-vm/supabase_migration.php
2026-02-15 21:32:26 +00:00

164 lines
6.3 KiB
PHP

<?php
require_once __DIR__ . '/db/config.php';
// This script migrates the local MariaDB database to Supabase PostgreSQL.
// It requires the Supabase Database Password.
if (php_sapi_name() !== 'cli') {
die("This script must be run from the command line.");
}
$dbPassword = $argv[1] ?? '';
if (!$dbPassword) {
echo "Usage: php supabase_migration.php [SUPABASE_DB_PASSWORD]\n";
exit(1);
}
$supabaseHost = "aws-1-ap-southeast-1.pooler.supabase.com";
$supabaseUser = "postgres.siqeqnizegizxemrfgkf";
$supabaseDb = "postgres";
$supabasePort = "6543";
try {
echo "Connecting to local MariaDB...\n";
$localPdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => 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);
}