164 lines
6.3 KiB
PHP
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);
|
|
}
|