diff --git a/README.md b/README.md index ec9f97b..12500f9 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Run `./launch.sh` in the main directory of the repository to run the server with Once launched the application is available at `http://localhost:8082` +To update the database schema run `docker-compose exec -T app php /var/www/html/database/update-db.php`. + ### Without containers You will need: diff --git a/database/database.sql b/database/database.sql index 77cea76..c53adc6 100644 --- a/database/database.sql +++ b/database/database.sql @@ -59,3 +59,6 @@ create table notes ( foreign key (candidate_id) references users (id) on delete cascade on update cascade, primary key (uid, candidate_id) ); + +-- Be careful not to change this line other than the number of the version, this is parsed with regex by the updater +insert into config (id, value) values ('SchemaVersion', '0'); \ No newline at end of file diff --git a/database/update-db.php b/database/update-db.php new file mode 100644 index 0000000..c0c2a7a --- /dev/null +++ b/database/update-db.php @@ -0,0 +1,95 @@ +getConfigValue('SchemaVersion'); + } catch (\Exception $e) { + if ($e->getCode() === 404) { + $currentVersion = 0; + } else { + throw $e; + } + } + + if ($currentVersion === $schema) { + echo 'Database is up to date'; + return; + } + + if ($currentVersion > $schema) { + throw new \Exception('Database version is newer than the one in the sql file', 1); + } + + $rawDb = $db->getDb(); + + while ($currentVersion < $schema) { + $currentVersion++; + $filename = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'update' . DIRECTORY_SEPARATOR . $currentVersion . '.sql'; + if (!file_exists($filename)) { + throw new \Exception('Update file not found: ' . $filename, 2); + } + + $sql = file_get_contents($filename); + $rawDb->exec('BEGIN'); + $rawDb->exec($sql); + $db->setConfigValue('SchemaVersion', $currentVersion); + $rawDb->exec('COMMIT'); + echo 'Updated to version ' . $currentVersion; + echo PHP_EOL; + } +} catch(\Exception $e) { + echo get_class($e); + echo PHP_EOL; + echo $e->getMessage(); + echo PHP_EOL; + echo $e->getTraceAsString(); + exit(1); +} + +echo 'Update completed'; +echo PHP_EOL; +exit(0); \ No newline at end of file diff --git a/database/update/1.sql b/database/update/1.sql new file mode 100644 index 0000000..9409d08 --- /dev/null +++ b/database/update/1.sql @@ -0,0 +1,3 @@ + + +-- TODO: actually use this \ No newline at end of file diff --git a/src/Database.php b/src/Database.php index 4f97eed..9fbfb11 100644 --- a/src/Database.php +++ b/src/Database.php @@ -19,6 +19,17 @@ public function __construct() $this->db = new SQLite3(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'weeehire.db', SQLITE3_OPEN_READWRITE); } + /** + * ⚠️ THIS METHOD IS UNSAFE, NEVER EXPOSE IT, ONLY FOR DB UPGRADE ⚠️ + * Get the SQLite3 object + * @return SQLite3 + */ + + public function getDb(): SQLite3 + { + return $this->db; + } + /** * Insert a new User into the database * @@ -205,7 +216,7 @@ public function getConfigValue(string $option) $result->finalize(); if ($row === false) { - throw new DatabaseException("Config value $option not found"); + throw new DatabaseException("Config value $option not found", 404); } return $row['value'];