File: /home/mmickelson/view-once.com/src/db.php
<?php
// Database bootstrap and migrations
function get_db(): PDO {
ini_set('display_errors', 0);
error_reporting(E_ALL);
header_remove('X-Powered-By');
// Ensure data dirs
$dataDir = dirname(DB_FILE);
if (!is_dir($dataDir)) { mkdir($dataDir, 0755, true); }
if (!is_dir(FILES_DIR)) { mkdir(FILES_DIR, 0755, true); }
$db = new PDO('sqlite:' . DB_FILE, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
// Base table
$db->exec('CREATE TABLE IF NOT EXISTS secrets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
token TEXT UNIQUE NOT NULL,
body TEXT NOT NULL,
created_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL,
is_file INTEGER DEFAULT 0,
filename TEXT,
mime_type TEXT,
file_size INTEGER
)');
// Migration: expires_at
try {
$db->exec('SELECT expires_at FROM secrets LIMIT 1');
} catch (PDOException $e) {
$db->exec('ALTER TABLE secrets ADD COLUMN expires_at INTEGER NOT NULL DEFAULT 0');
$db->exec('UPDATE secrets SET expires_at = created_at + 86400 WHERE expires_at = 0');
}
// Migration: file columns
try {
$db->exec('SELECT is_file FROM secrets LIMIT 1');
} catch (PDOException $e) {
$db->exec('ALTER TABLE secrets ADD COLUMN is_file INTEGER DEFAULT 0');
$db->exec('ALTER TABLE secrets ADD COLUMN filename TEXT');
$db->exec('ALTER TABLE secrets ADD COLUMN mime_type TEXT');
$db->exec('ALTER TABLE secrets ADD COLUMN file_size INTEGER');
}
// Indexes
$db->exec('CREATE INDEX IF NOT EXISTS idx_token ON secrets(token)');
$db->exec('CREATE INDEX IF NOT EXISTS idx_expires ON secrets(expires_at)');
return $db;
}