setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $pdo->exec('PRAGMA foreign_keys = ON'); initSchema($pdo); seedAdmin($pdo); return $pdo; } function initSchema(PDO $pdo): void { $pdo->exec(" CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, role TEXT NOT NULL CHECK(role IN ('admin','user')), created_at TEXT NOT NULL ); "); $pdo->exec(" CREATE TABLE IF NOT EXISTS directories ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, parent_id INTEGER NULL, level INTEGER NOT NULL CHECK(level BETWEEN 1 AND 3), created_at TEXT NOT NULL, FOREIGN KEY(parent_id) REFERENCES directories(id) ON DELETE CASCADE ); "); $pdo->exec(" CREATE TABLE IF NOT EXISTS archives ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, directory_id INTEGER NOT NULL, loan_institution TEXT, borrower TEXT, credit_limit REAL, remaining_limit REAL, start_date TEXT, end_date TEXT, annual_rate REAL, guarantee_type TEXT, guarantor TEXT, archive_kind TEXT NOT NULL DEFAULT 'bank_loan', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, FOREIGN KEY(directory_id) REFERENCES directories(id) ON DELETE CASCADE ); "); $hasArchiveKind = false; foreach ($pdo->query('PRAGMA table_info(archives)')->fetchAll(PDO::FETCH_ASSOC) as $col) { if (($col['name'] ?? '') === 'archive_kind') { $hasArchiveKind = true; break; } } if (!$hasArchiveKind) { $pdo->exec("ALTER TABLE archives ADD COLUMN archive_kind TEXT NOT NULL DEFAULT 'bank_loan'"); } $pdo->exec(" CREATE TABLE IF NOT EXISTS files ( id INTEGER PRIMARY KEY AUTOINCREMENT, archive_id INTEGER NOT NULL, original_name TEXT NOT NULL, stored_name TEXT NOT NULL, file_ext TEXT NOT NULL, file_size INTEGER NOT NULL, created_at TEXT NOT NULL, FOREIGN KEY(archive_id) REFERENCES archives(id) ON DELETE CASCADE ); "); $pdo->exec("CREATE INDEX IF NOT EXISTS idx_archives_end_date ON archives(end_date)"); $pdo->exec("CREATE INDEX IF NOT EXISTS idx_archives_loan_inst ON archives(loan_institution)"); $pdo->exec("CREATE INDEX IF NOT EXISTS idx_archives_borrower ON archives(borrower)"); } function seedAdmin(PDO $pdo): void { $stmt = $pdo->prepare('SELECT COUNT(*) FROM users WHERE username = :username'); $stmt->execute([':username' => 'admin']); if ((int)$stmt->fetchColumn() > 0) { return; } $stmt = $pdo->prepare('INSERT INTO users(username,password_hash,role,created_at) VALUES(:u,:p,:r,:c)'); $stmt->execute([ ':u' => 'admin', ':p' => password_hash('jinniu123', PASSWORD_DEFAULT), ':r' => 'admin', ':c' => date('Y-m-d H:i:s'), ]); }