From 95f89e213bbff9da7820d10da7a3b18be58a486e Mon Sep 17 00:00:00 2001 From: flashwave Date: Fri, 13 Oct 2023 22:25:40 +0000 Subject: [PATCH] Added migration for existing layout. --- composer.json | 3 + .../2023_10_13_215920_existing_tables.php | 109 ++++++++++++++++++ makai.php | 1 + src/MakaiContext.php | 18 ++- tools/migrate | 34 ++++++ tools/new-migration | 25 ++++ 6 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 database/2023_10_13_215920_existing_tables.php create mode 100755 tools/migrate create mode 100755 tools/new-migration diff --git a/composer.json b/composer.json index 0cbae17..5a5e05d 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,9 @@ "erusev/parsedown": "~1.6" }, "autoload": { + "classmap": [ + "database" + ], "psr-4": { "Makai\\": "src" } diff --git a/database/2023_10_13_215920_existing_tables.php b/database/2023_10_13_215920_existing_tables.php new file mode 100644 index 0000000..c642744 --- /dev/null +++ b/database/2023_10_13_215920_existing_tables.php @@ -0,0 +1,109 @@ +query('SHOW TABLES'); + while($result->next()) + $existingTables[] = $result->getString(0); + + if(!in_array('fm_contacts', $existingTables)) + $conn->execute(' + CREATE TABLE fm_contacts ( + cont_name VARBINARY(16) NOT NULL, + cont_homepage TINYINT(4) NOT NULL DEFAULT "0", + cont_order INT(11) NOT NULL DEFAULT "0", + cont_title VARCHAR(255) NOT NULL COLLATE "utf8mb4_bin", + cont_icon VARCHAR(255) NOT NULL COLLATE "utf8mb4_bin", + cont_colour INT(10) UNSIGNED NOT NULL, + cont_display VARCHAR(255) NOT NULL COLLATE "utf8mb4_bin", + cont_link VARCHAR(255) NULL DEFAULT NULL COLLATE "utf8mb4_bin", + PRIMARY KEY (cont_name), + KEY cont_homepage (cont_homepage), + KEY cont_order (cont_order) + ) ENGINE=InnoDB COLLATE="utf8mb4_bin"; + '); + + if(!in_array('fm_public_keys', $existingTables)) + $conn->execute(' + CREATE TABLE fm_public_keys ( + key_id INT(11) NOT NULL AUTO_INCREMENT, + key_level INT(11) NOT NULL DEFAULT "0", + key_algo VARCHAR(20) NOT NULL COLLATE "utf8mb4_bin", + key_body TEXT NOT NULL COLLATE "utf8mb4_bin", + key_comment VARCHAR(255) NOT NULL COLLATE "utf8mb4_bin", + key_created TIMESTAMP NOT NULL DEFAULT current_timestamp(), + key_deprecated TIMESTAMP NULL DEFAULT NULL, + PRIMARY KEY (key_id), + UNIQUE KEY key_body (key_body), + KEY key_deprecated (key_deprecated), + KEY key_level (key_level) + ) ENGINE=InnoDB COLLATE="utf8mb4_bin"; + '); + + if(!in_array('fm_proglangs', $existingTables)) + $conn->execute(' + CREATE TABLE fm_proglangs ( + language_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + language_name VARCHAR(50) NOT NULL COLLATE "utf8mb4_unicode_ci", + language_colour MEDIUMINT(8) UNSIGNED NULL DEFAULT NULL, + PRIMARY KEY (language_id), + UNIQUE KEY language_name (language_name) + ) ENGINE=InnoDB COLLATE="utf8mb4_bin"; + '); + + if(!in_array('fm_projects', $existingTables)) + $conn->execute(' + CREATE TABLE fm_projects ( + project_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + project_name VARCHAR(255) NOT NULL COLLATE "utf8mb4_unicode_ci", + project_name_clean VARCHAR(255) NULL DEFAULT NULL COLLATE "ascii_general_ci", + project_summary VARCHAR(255) NULL DEFAULT NULL COLLATE "utf8mb4_unicode_ci", + project_description MEDIUMTEXT NULL DEFAULT NULL COLLATE "utf8mb4_unicode_ci", + project_order INT(11) NOT NULL DEFAULT "0", + project_type ENUM("Project", "Tool") NOT NULL DEFAULT "Project" COLLATE "ascii_general_ci", + project_featured TINYINT(3) UNSIGNED NOT NULL DEFAULT "0", + project_colour MEDIUMINT(8) UNSIGNED NULL DEFAULT NULL, + project_homepage VARCHAR(255) NULL DEFAULT NULL COLLATE "ascii_general_ci", + project_repository VARCHAR(255) NULL DEFAULT NULL COLLATE "ascii_general_ci", + project_forum VARCHAR(255) NULL DEFAULT NULL COLLATE "ascii_general_ci", + project_created TIMESTAMP NOT NULL DEFAULT current_timestamp(), + project_deleted TIMESTAMP NULL DEFAULT NULL, + project_archived TIMESTAMP NULL DEFAULT NULL, + PRIMARY KEY (project_id), + UNIQUE KEY project_name (project_name), + UNIQUE KEY project_name_clean (project_name_clean), + KEY project_order (project_order), + KEY project_type (project_type), + KEY project_archived (project_archived), + KEY project_deleted (project_deleted), + KEY project_created (project_created), + KEY project_featured (project_featured) + ) ENGINE=InnoDB COLLATE="utf8mb4_bin"; + '); + + if(!in_array('fm_projects_proglangs', $existingTables)) + $conn->execute(' + CREATE TABLE fm_projects_proglangs ( + project_id INT(10) UNSIGNED NOT NULL, + language_id INT(10) UNSIGNED NOT NULL, + priority INT(10) NOT NULL DEFAULT "0", + UNIQUE KEY projects_proglangs_unique (project_id, language_id), + KEY projects_proglangs_language_foreign (language_id), + KEY projects_proglangs_priority_index (priority), + CONSTRAINT projects_proglangs_language_foreign + FOREIGN KEY (language_id) + REFERENCES fm_proglangs (language_id) + ON UPDATE CASCADE + ON DELETE CASCADE, + CONSTRAINT projects_proglangs_project_foreign + FOREIGN KEY (project_id) + REFERENCES fm_projects (project_id) + ON UPDATE CASCADE + ON DELETE CASCADE + ) ENGINE=InnoDB COLLATE="utf8mb4_bin"; + '); + } +} diff --git a/makai.php b/makai.php index 97247e8..3c759cf 100644 --- a/makai.php +++ b/makai.php @@ -12,6 +12,7 @@ define('MKI_DIR_PUBLIC', MKI_ROOT . '/public'); define('MKI_DIR_CONFIG', MKI_ROOT . '/config'); define('MKI_DIR_TEMPLATES', MKI_ROOT . '/templates'); define('MKI_DIR_ASSETS', MKI_ROOT . '/assets'); +define('MKI_DIR_MIGRATIONS', MKI_ROOT . '/database'); require_once MKI_ROOT . '/vendor/autoload.php'; diff --git a/src/MakaiContext.php b/src/MakaiContext.php index 5426f11..66ef060 100644 --- a/src/MakaiContext.php +++ b/src/MakaiContext.php @@ -3,6 +3,9 @@ namespace Makai; use Index\Environment; use Index\Data\IDbConnection; +use Index\Data\Migration\IDbMigrationRepo; +use Index\Data\Migration\DbMigrationManager; +use Index\Data\Migration\FsDbMigrationRepo; use Index\Security\CSRFP; use Sasae\SasaeEnvironment; @@ -44,10 +47,23 @@ final class MakaiContext { return $this->sshKeys; } - public function getDatabase(): IDbConnection { + public function getDbConn(): IDbConnection { return $this->dbConn; } + public function getDbQueryCount(): int { + $result = $this->dbConn->query('SHOW SESSION STATUS LIKE "Questions"'); + return $result->next() ? $result->getInteger(1) : 0; + } + + public function createMigrationManager(): DbMigrationManager { + return new DbMigrationManager($this->dbConn, 'fm_' . DbMigrationManager::DEFAULT_TABLE); + } + + public function createMigrationRepo(): IDbMigrationRepo { + return new FsDbMigrationRepo(MKI_DIR_MIGRATIONS); + } + public function getTemplating(): SasaeEnvironment { return $this->templating; } diff --git a/tools/migrate b/tools/migrate new file mode 100755 index 0000000..ec2670e --- /dev/null +++ b/tools/migrate @@ -0,0 +1,34 @@ +#!/usr/bin/env php +createMigrationManager(); + + echo 'Preparing to run migrations...' . PHP_EOL; + $manager->init(); + + echo 'Creating migration repository...' . PHP_EOL; + $repo = $makai->createMigrationRepo(); + + echo 'Running migrations...' . PHP_EOL; + $completed = $manager->processMigrations($repo); + + if(empty($completed)) { + echo 'There were no migrations to run!' . PHP_EOL; + } else { + echo 'The following migrations have been completed:' . PHP_EOL; + foreach($completed as $migration) + echo ' - ' . $migration . PHP_EOL; + } + + echo PHP_EOL; +} finally { + unlink(MKI_ROOT . '/.migrating'); +} diff --git a/tools/new-migration b/tools/new-migration new file mode 100755 index 0000000..811f51c --- /dev/null +++ b/tools/new-migration @@ -0,0 +1,25 @@ +#!/usr/bin/env php +createMigrationRepo(); +if(!($repo instanceof FsDbMigrationRepo)) { + echo 'Migration repository type does not support creation of templates.' . PHP_EOL; + return; +} + +$baseName = implode(' ', array_slice($argv, 1)); +$manager = $makai->createMigrationManager(); + +try { + $names = $manager->createNames($baseName); +} catch(InvalidArgumentException $ex) { + echo $ex->getMessage() . PHP_EOL; + return; +} + +$repo->saveMigrationTemplate($names->name, $manager->template($names->className)); + +echo "Template for '{$names->className}' has been saved to {$names->name}.php." . PHP_EOL;