diff --git a/public/index.php b/public/index.php index 7cc587a..1929802 100644 --- a/public/index.php +++ b/public/index.php @@ -22,32 +22,15 @@ include_once(dirname(dirname(__FILE__)) . "/config/bootstrap.php"); * Validate application state before processing request */ -// Check prerequisites +// Check prerequisites (includes database connection and migrations) $prerequisites = new Prerequisites(); -$results = $prerequisites->validate(); -if (count($prerequisites->getErrors()) > 0) { - $prerequisites->generateWebSummary($results); +if (!$prerequisites->validate()) { + $prerequisites->generateWebSummary(); exit; } -// Connect to the database -try { - // SQLite will just create this if it doesn't exist. - $db = new PDO("sqlite:" . DB_FILE); - $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); -} catch (PDOException $e) { - throw new SetupException( - "Database connection failed: " . $e->getMessage(), - 'database_connection', - 0, - $e - ); -} - -// Do any necessary database migrations -$migrator = new Migrator($db); -$migrator->migrate(); +// Get the working database connection from prerequisites +$db = $prerequisites->getDatabase(); // Make sure the initial setup is complete unless we're already heading to setup if (!(preg_match('/setup$/', $path))) { diff --git a/src/Framework/Exception/SetupException.php b/src/Framework/Exception/SetupException.php deleted file mode 100644 index befbfd7..0000000 --- a/src/Framework/Exception/SetupException.php +++ /dev/null @@ -1,38 +0,0 @@ -setupIssue = $setupIssue; - } - - // Exception handler - // Exceptions don't generally define their own handlers, - // but this is a very specific case. - public function handle(){ - // try to log the error, but keep going if it fails - try { - Log::error($this->setupIssue . ", " . $this->getMessage()); - } catch (Exception $e) { - // Do nothing and move on to the normal error handling - // We don't want to short-circuit this if there's a problem logging - } - - // TODO: This doesn't need to be a switch anymore - // May not need to exist at all - switch ($this->setupIssue){ - case 'database_connection': - case 'db_migration': - // Unrecoverable errors. - // Show error message and exit - http_response_code(500); - echo "
" . Util::escape_html($this->setupIssue) . '-' . Util::escape_html($this->getMessage()) . "
"; - exit; - } - } - - -} \ No newline at end of file diff --git a/src/Framework/Migrator/Migrator.php b/src/Framework/Migrator/Migrator.php index 32d2d6c..02ada1e 100644 --- a/src/Framework/Migrator/Migrator.php +++ b/src/Framework/Migrator/Migrator.php @@ -18,9 +18,8 @@ class Migrator{ $currentVersion = $this->getVersion(); if ($newVersion <= $currentVersion){ - throw new SetupException( - "New version ($newVersion) must be greater than current version ($currentVersion)", - 'db_migration' + throw new Exception( + "New version ($newVersion) must be greater than current version ($currentVersion)" ); } @@ -89,9 +88,8 @@ class Migrator{ Log::info("Updated database version to " . $this->getVersion()); } catch (Exception $e) { $this->db->rollBack(); - throw new SetupException( - "Migration failed: $filename", - 'db_migration', + throw new Exception( + "Migration failed: $filename - " . $e->getMessage(), 0, $e ); diff --git a/src/Framework/Prerequisites/Prerequisites.php b/src/Framework/Prerequisites/Prerequisites.php index 6ff902e..7b064c3 100644 --- a/src/Framework/Prerequisites/Prerequisites.php +++ b/src/Framework/Prerequisites/Prerequisites.php @@ -16,6 +16,7 @@ class Prerequisites { private $logFile; private $isCli; private $isWeb; + private $database = null; public function __construct() { $this->isCli = php_sapi_name() === 'cli'; @@ -377,12 +378,68 @@ class Prerequisites { ); } - return $canCreateDb; + if (!$canCreateDb) { + return false; + } + + // Test database connection + try { + $db = new PDO("sqlite:" . $dbFile); + $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + + // Test basic query to ensure database is functional + $db->query("SELECT 1")->fetchColumn(); + + $this->addCheck( + 'Database Connection', + true, + 'Successfully connected to database' + ); + + // Store working database connection + $this->database = $db; + + // Test migrations + return $this->checkMigrations($db); + + } catch (PDOException $e) { + $this->addCheck( + 'Database Connection', + false, + 'Failed to connect: ' . $e->getMessage(), + 'error' + ); + return false; + } + } + + private function checkMigrations($db) { + try { + $migrator = new Migrator($db); + $migrator->migrate(); + + $this->addCheck( + 'Database Migrations', + true, + 'All database migrations applied successfully' + ); + return true; + + } catch (Exception $e) { + $this->addCheck( + 'Database Migrations', + false, + 'Migration failed: ' . $e->getMessage(), + 'error' + ); + return false; + } } // validate prereqs // runs on each request and can be run from CLI - public function validate() { + public function validate(): bool { $this->log("=== tkr prerequisites check started at " . date('Y-m-d H:i:s') . " ===", true); if ($this->isCli) { @@ -406,7 +463,8 @@ class Prerequisites { $this->generateCliSummary($results); } - return $results; + // Return true only if no errors occurred + return count($this->errors) === 0; } /** @@ -567,4 +625,14 @@ class Prerequisites { public function getWarnings() { return $this->warnings; } + + /** + * Get working database connection (only call after validate() returns true) + */ + public function getDatabase(): PDO { + if ($this->database === null) { + throw new RuntimeException('Database not available - call validate() first'); + } + return $this->database; + } } \ No newline at end of file