Updated database migration system to use the Index methods.

This commit is contained in:
flash 2023-01-07 04:15:19 +00:00
parent 5a4094867f
commit 37eea64a27
29 changed files with 745 additions and 1365 deletions

View File

@ -1,673 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\InitialStructure;
use PDO;
// MariaDB migration!
// Gotta get rid of possible incompatible stuff like WITH RECURSIVE for new installations.
function migrate_up(PDO $conn): void {
$getMigrations = $conn->prepare("SELECT COUNT(*) FROM `msz_migrations`");
$migrations = (int)($getMigrations->execute() ? $getMigrations->fetchColumn() : 0);
if($migrations > 0) {
$conn->exec("TRUNCATE `msz_migrations`");
return;
}
$conn->exec("
CREATE TABLE `msz_ip_blacklist` (
`ip_subnet` VARBINARY(16) NOT NULL,
`ip_mask` TINYINT(3) UNSIGNED NOT NULL,
UNIQUE INDEX `ip_blacklist_unique` (`ip_subnet`, `ip_mask`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_roles` (
`role_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`role_hierarchy` INT(11) NOT NULL DEFAULT '1',
`role_name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`role_title` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`role_description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`role_hidden` TINYINT(1) NOT NULL DEFAULT '0',
`role_can_leave` TINYINT(1) NOT NULL DEFAULT '0',
`role_colour` INT(11) NULL DEFAULT NULL,
`role_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`role_id`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_users` (
`user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`password` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`email` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`register_ip` VARBINARY(16) NOT NULL,
`last_ip` VARBINARY(16) NOT NULL,
`user_super` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
`user_country` CHAR(2) NOT NULL DEFAULT 'XX' COLLATE 'utf8mb4_bin',
`user_colour` INT(11) NULL DEFAULT NULL,
`user_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_active` TIMESTAMP NULL DEFAULT NULL,
`user_deleted` TIMESTAMP NULL DEFAULT NULL,
`display_role` INT(10) UNSIGNED NULL DEFAULT NULL,
`user_totp_key` CHAR(26) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`user_about_content` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`user_about_parser` TINYINT(4) NOT NULL DEFAULT '0',
`user_signature_content` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`user_signature_parser` TINYINT(4) NOT NULL DEFAULT '0',
`user_birthdate` DATE NULL DEFAULT NULL,
`user_background_settings` TINYINT(4) NULL DEFAULT '0',
`user_website` VARCHAR(255) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_twitter` VARCHAR(20) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_github` VARCHAR(40) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_skype` VARCHAR(60) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_discord` VARCHAR(40) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_youtube` VARCHAR(255) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_steam` VARCHAR(255) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_ninswitch` VARCHAR(14) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_twitchtv` VARCHAR(30) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_osu` VARCHAR(20) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_lastfm` VARCHAR(20) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
`user_title` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`user_id`),
UNIQUE INDEX `users_username_unique` (`username`),
UNIQUE INDEX `users_email_unique` (`email`),
INDEX `users_display_role_foreign` (`display_role`),
INDEX `users_indices` (
`user_country`, `user_created`, `user_active`,
`user_deleted`, `user_birthdate`
),
CONSTRAINT `users_display_role_foreign`
FOREIGN KEY (`display_role`)
REFERENCES `msz_roles` (`role_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_user_roles` (
`user_id` INT(10) UNSIGNED NOT NULL,
`role_id` INT(10) UNSIGNED NOT NULL,
UNIQUE INDEX `user_roles_unique` (`user_id`, `role_id`),
INDEX `user_roles_role_id_foreign` (`role_id`),
CONSTRAINT `user_roles_role_id_foreign`
FOREIGN KEY (`role_id`)
REFERENCES `msz_roles` (`role_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `user_roles_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_users_password_resets` (
`user_id` INT(10) UNSIGNED NOT NULL,
`reset_ip` VARBINARY(16) NOT NULL,
`reset_requested` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`verification_code` CHAR(12) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
UNIQUE INDEX `msz_users_password_resets_unique` (`user_id`, `reset_ip`),
INDEX `msz_users_password_resets_index` (`reset_requested`),
CONSTRAINT `msz_users_password_resets_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_user_relations` (
`user_id` INT(10) UNSIGNED NOT NULL,
`subject_id` INT(10) UNSIGNED NOT NULL,
`relation_type` TINYINT(3) UNSIGNED NOT NULL,
`relation_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX `user_relations_unique` (`user_id`, `subject_id`),
INDEX `user_relations_subject_id_foreign` (`subject_id`),
CONSTRAINT `user_relations_subject_id_foreign`
FOREIGN KEY (`subject_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `user_relations_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_user_warnings` (
`warning_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NOT NULL,
`user_ip` VARBINARY(16) NOT NULL,
`issuer_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`issuer_ip` VARBINARY(16) NOT NULL,
`warning_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`warning_duration` TIMESTAMP NULL DEFAULT NULL,
`warning_type` TINYINT(3) UNSIGNED NOT NULL,
`warning_note` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`warning_note_private` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`warning_id`),
INDEX `user_warnings_user_foreign` (`user_id`),
INDEX `user_warnings_issuer_foreign` (`issuer_id`),
INDEX `user_warnings_created_index` (`warning_created`),
INDEX `user_warnings_duration_index` (`warning_duration`),
INDEX `user_warnings_type_index` (`warning_type`),
INDEX `user_warnings_user_ip_index` (`user_ip`),
CONSTRAINT `user_warnings_issuer_foreign`
FOREIGN KEY (`issuer_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL,
CONSTRAINT `user_warnings_user_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_sessions` (
`session_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NOT NULL,
`session_key` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`session_ip` VARBINARY(16) NOT NULL,
`session_ip_last` VARBINARY(16) NULL DEFAULT NULL,
`session_user_agent` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`session_country` CHAR(2) NOT NULL DEFAULT 'XX' COLLATE 'utf8mb4_bin',
`session_expires` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`session_expires_bump` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',
`session_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`session_active` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`session_id`),
UNIQUE INDEX `sessions_key_unique` (`session_key`),
INDEX `sessions_user_id_foreign` (`user_id`),
INDEX `sessions_expires_index` (`session_expires`),
CONSTRAINT `sessions_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_permissions` (
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`role_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`general_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`general_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`user_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`user_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`changelog_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`changelog_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`news_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`news_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`forum_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`forum_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`comments_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`comments_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0',
UNIQUE INDEX `permissions_user_id_unique` (`user_id`),
UNIQUE INDEX `permissions_role_id_unique` (`role_id`),
CONSTRAINT `permissions_role_id_foreign`
FOREIGN KEY (`role_id`)
REFERENCES `msz_roles` (`role_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `permissions_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_audit_log` (
`log_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`log_action` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_bin',
`log_params` TEXT NOT NULL COLLATE 'utf8mb4_bin',
`log_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`log_ip` VARBINARY(16) NULL DEFAULT NULL,
`log_country` CHAR(2) NOT NULL DEFAULT 'XX' COLLATE 'utf8mb4_bin',
PRIMARY KEY (`log_id`),
INDEX `audit_log_user_id_foreign` (`user_id`),
CONSTRAINT `audit_log_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_auth_tfa` (
`user_id` INT(10) UNSIGNED NOT NULL,
`tfa_token` CHAR(32) NOT NULL COLLATE 'utf8mb4_bin',
`tfa_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX `auth_tfa_token_unique` (`tfa_token`),
INDEX `auth_tfa_user_foreign` (`user_id`),
INDEX `auth_tfa_created_index` (`tfa_created`),
CONSTRAINT `auth_tfa_user_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_login_attempts` (
`attempt_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`attempt_success` TINYINT(1) NOT NULL,
`attempt_ip` VARBINARY(16) NOT NULL,
`attempt_country` CHAR(2) NOT NULL DEFAULT 'XX' COLLATE 'utf8mb4_bin',
`attempt_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`attempt_user_agent` VARCHAR(255) NOT NULL DEFAULT '' COLLATE 'utf8mb4_bin',
PRIMARY KEY (`attempt_id`),
INDEX `login_attempts_user_id_foreign` (`user_id`),
CONSTRAINT `login_attempts_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_comments_categories` (
`category_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`category_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`category_locked` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`category_id`),
UNIQUE INDEX `comments_categories_name_unique` (`category_name`),
INDEX `comments_categories_locked_index` (`category_locked`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_comments_posts` (
`comment_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`category_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`comment_reply_to` INT(10) UNSIGNED NULL DEFAULT NULL,
`comment_text` TEXT NOT NULL COLLATE 'utf8mb4_bin',
`comment_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`comment_pinned` TIMESTAMP NULL DEFAULT NULL,
`comment_edited` TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`comment_deleted` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`comment_id`),
INDEX `comments_posts_category_foreign` (`category_id`),
INDEX `comments_posts_user_foreign` (`user_id`),
INDEX `comments_posts_reply_id` (`comment_reply_to`),
INDEX `comments_posts_dates` (
`comment_created`, `comment_pinned`,
`comment_edited`, `comment_deleted`
),
CONSTRAINT `comments_posts_category_foreign`
FOREIGN KEY (`category_id`)
REFERENCES `msz_comments_categories` (`category_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `comments_posts_user_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_comments_votes` (
`comment_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NOT NULL,
`comment_vote` TINYINT(4) NOT NULL DEFAULT '0',
UNIQUE INDEX `comments_vote_unique` (`comment_id`, `user_id`),
INDEX `comments_vote_user_foreign` (`user_id`),
INDEX `comments_vote_index` (`comment_vote`),
CONSTRAINT `comment_vote_id`
FOREIGN KEY (`comment_id`)
REFERENCES `msz_comments_posts` (`comment_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `comment_vote_user`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_news_categories` (
`category_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`category_description` TEXT NOT NULL COLLATE 'utf8mb4_bin',
`category_is_hidden` TINYINT(1) NOT NULL DEFAULT '0',
`category_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`category_id`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_news_posts` (
`post_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`category_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`comment_section_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`post_is_featured` TINYINT(1) NOT NULL DEFAULT '0',
`post_title` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`post_text` TEXT NOT NULL COLLATE 'utf8mb4_bin',
`post_scheduled` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`post_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`post_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`post_deleted` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`post_id`),
INDEX `news_posts_category_id_foreign` (`category_id`),
INDEX `news_posts_user_id_foreign` (`user_id`),
INDEX `news_posts_comment_section` (`comment_section_id`),
INDEX `news_posts_featured_index` (`post_is_featured`),
INDEX `news_posts_scheduled_index` (`post_scheduled`),
INDEX `news_posts_created_index` (`post_created`),
INDEX `news_posts_updated_index` (`post_updated`),
INDEX `news_posts_deleted_index` (`post_deleted`),
FULLTEXT INDEX `news_posts_fulltext` (`post_title`, `post_text`),
CONSTRAINT `news_posts_category_id_foreign`
FOREIGN KEY (`category_id`)
REFERENCES `msz_news_categories` (`category_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `news_posts_comment_section`
FOREIGN KEY (`comment_section_id`)
REFERENCES `msz_comments_categories` (`category_id`)
ON UPDATE CASCADE
ON DELETE SET NULL,
CONSTRAINT `news_posts_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_changelog_tags` (
`tag_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`tag_name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`tag_description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`tag_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tag_archived` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`tag_id`),
UNIQUE INDEX `tag_name` (`tag_name`),
INDEX `tag_archived` (`tag_archived`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_changelog_changes` (
`change_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`change_action` INT(10) UNSIGNED NULL DEFAULT NULL,
`change_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`change_log` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`change_text` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`change_id`),
INDEX `changes_user_foreign` (`user_id`),
INDEX `changes_action_index` (`change_action`),
INDEX `changes_created_index` (`change_created`),
CONSTRAINT `changes_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_changelog_change_tags` (
`change_id` INT(10) UNSIGNED NOT NULL,
`tag_id` INT(10) UNSIGNED NOT NULL,
UNIQUE INDEX `change_tag_unique` (`change_id`, `tag_id`),
INDEX `tag_id_foreign_key` (`tag_id`),
CONSTRAINT `change_id_foreign_key`
FOREIGN KEY (`change_id`)
REFERENCES `msz_changelog_changes` (`change_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `tag_id_foreign_key`
FOREIGN KEY (`tag_id`)
REFERENCES `msz_changelog_tags` (`tag_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_polls` (
`poll_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`poll_max_votes` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',
`poll_expires` TIMESTAMP NULL DEFAULT NULL,
`poll_preview_results` TINYINT(3) UNSIGNED NOT NULL DEFAULT '1',
`poll_change_vote` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`poll_id`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_polls_options` (
`option_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`poll_id` INT(10) UNSIGNED NOT NULL,
`option_text` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`option_id`),
INDEX `polls_options_poll_foreign` (`poll_id`),
CONSTRAINT `polls_options_poll_foreign`
FOREIGN KEY (`poll_id`)
REFERENCES `msz_forum_polls` (`poll_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_polls_answers` (
`user_id` INT(10) UNSIGNED NOT NULL,
`poll_id` INT(10) UNSIGNED NOT NULL,
`option_id` INT(10) UNSIGNED NOT NULL,
UNIQUE INDEX `polls_answers_unique` (`user_id`, `poll_id`, `option_id`),
INDEX `polls_answers_user_foreign` (`user_id`),
INDEX `polls_answers_poll_foreign` (`poll_id`),
INDEX `polls_answers_option_foreign` (`option_id`),
CONSTRAINT `polls_answers_option_foreign`
FOREIGN KEY (`option_id`)
REFERENCES `msz_forum_polls_options` (`option_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `polls_answers_poll_foreign`
FOREIGN KEY (`poll_id`)
REFERENCES `msz_forum_polls` (`poll_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `polls_answers_user_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_categories` (
`forum_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`forum_order` INT(10) UNSIGNED NOT NULL DEFAULT '1',
`forum_parent` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`forum_name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`forum_type` TINYINT(4) NOT NULL DEFAULT '0',
`forum_description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`forum_colour` INT(10) UNSIGNED NULL DEFAULT NULL,
`forum_link` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`forum_link_clicks` INT(10) UNSIGNED NULL DEFAULT NULL,
`forum_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`forum_archived` TINYINT(1) NOT NULL DEFAULT '0',
`forum_hidden` TINYINT(1) NOT NULL DEFAULT '0',
`forum_count_topics` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`forum_count_posts` INT(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`forum_id`),
INDEX `forum_order_index` (`forum_order`),
INDEX `forum_parent_index` (`forum_parent`),
INDEX `forum_type_index` (`forum_type`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_permissions` (
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`role_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`forum_id` INT(10) UNSIGNED NOT NULL,
`forum_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`forum_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0',
UNIQUE INDEX `forum_permissions_unique` (`user_id`, `role_id`, `forum_id`),
INDEX `forum_permissions_forum_id` (`forum_id`),
INDEX `forum_permissions_role_id` (`role_id`),
CONSTRAINT `forum_permissions_forum_id_foreign`
FOREIGN KEY (`forum_id`)
REFERENCES `msz_forum_categories` (`forum_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `forum_permissions_role_id_foreign`
FOREIGN KEY (`role_id`)
REFERENCES `msz_roles` (`role_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `forum_permissions_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_topics` (
`topic_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`forum_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`poll_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`topic_type` TINYINT(4) NOT NULL DEFAULT '0',
`topic_title` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
`topic_count_views` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`topic_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`topic_bumped` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`topic_deleted` TIMESTAMP NULL DEFAULT NULL,
`topic_locked` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`topic_id`),
INDEX `topics_forum_id_foreign` (`forum_id`),
INDEX `topics_user_id_foreign` (`user_id`),
INDEX `topics_type_index` (`topic_type`),
INDEX `topics_created_index` (`topic_created`),
INDEX `topics_bumped_index` (`topic_bumped`),
INDEX `topics_deleted_index` (`topic_deleted`),
INDEX `topics_locked_index` (`topic_locked`),
INDEX `posts_poll_id_foreign` (`poll_id`),
FULLTEXT INDEX `topics_fulltext` (`topic_title`),
CONSTRAINT `posts_poll_id_foreign`
FOREIGN KEY (`poll_id`)
REFERENCES `msz_forum_polls` (`poll_id`)
ON UPDATE CASCADE
ON DELETE SET NULL,
CONSTRAINT `topics_forum_id_foreign`
FOREIGN KEY (`forum_id`)
REFERENCES `msz_forum_categories` (`forum_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `topics_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_topics_track` (
`user_id` INT(10) UNSIGNED NOT NULL,
`topic_id` INT(10) UNSIGNED NOT NULL,
`forum_id` INT(10) UNSIGNED NOT NULL,
`track_last_read` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX `topics_track_unique` (`user_id`, `topic_id`),
INDEX `topics_track_topic_id_foreign` (`topic_id`),
INDEX `topics_track_user_id_foreign` (`user_id`),
INDEX `topics_track_forum_id_foreign` (`forum_id`),
INDEX `forum_track_last_read` (`track_last_read`),
CONSTRAINT `topics_track_forum_id_foreign`
FOREIGN KEY (`forum_id`)
REFERENCES `msz_forum_categories` (`forum_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `topics_track_topic_id_foreign`
FOREIGN KEY (`topic_id`)
REFERENCES `msz_forum_topics` (`topic_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `topics_track_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_forum_posts` (
`post_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`topic_id` INT(10) UNSIGNED NOT NULL,
`forum_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
`post_ip` VARBINARY(16) NOT NULL,
`post_text` TEXT NOT NULL COLLATE 'utf8mb4_bin',
`post_parse` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0',
`post_display_signature` TINYINT(4) UNSIGNED NOT NULL DEFAULT '1',
`post_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`post_edited` TIMESTAMP NULL DEFAULT NULL,
`post_deleted` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`post_id`),
INDEX `posts_topic_id_foreign` (`topic_id`),
INDEX `posts_forum_id_foreign` (`forum_id`),
INDEX `posts_user_id_foreign` (`user_id`),
INDEX `posts_created_index` (`post_created`),
INDEX `posts_deleted_index` (`post_deleted`),
INDEX `posts_parse_index` (`post_parse`),
INDEX `posts_edited_index` (`post_edited`),
INDEX `posts_display_signature_index` (`post_display_signature`),
INDEX `posts_ip_index` (`post_ip`),
FULLTEXT INDEX `posts_fulltext` (`post_text`),
CONSTRAINT `posts_forum_id_foreign`
FOREIGN KEY (`forum_id`)
REFERENCES `msz_forum_categories` (`forum_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `posts_topic_id_foreign`
FOREIGN KEY (`topic_id`)
REFERENCES `msz_forum_topics` (`topic_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `posts_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
}

View File

@ -1,11 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\AddForumCategoryIcons;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
ALTER TABLE `msz_forum_categories`
ADD COLUMN `forum_icon` VARCHAR(50) NULL DEFAULT NULL AFTER `forum_description`;
");
}

View File

@ -1,27 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\CreateFeatureForumType;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
CREATE TABLE `msz_forum_topics_priority` (
`topic_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NOT NULL,
`topic_priority` SMALLINT(6) NOT NULL,
UNIQUE INDEX `forum_topics_priority_unique` (`topic_id`, `user_id`),
INDEX `forum_topics_priority_topic_foreign` (`topic_id`),
INDEX `forum_topics_priority_user_foreign` (`user_id`),
CONSTRAINT `forum_topics_priority_topic_foreign`
FOREIGN KEY (`topic_id`)
REFERENCES `msz_forum_topics` (`topic_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `forum_topics_priority_user_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
}

View File

@ -1,21 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\CreateEmoticonsTable;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
CREATE TABLE `msz_emoticons` (
`emote_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`emote_order` MEDIUMINT(9) NOT NULL DEFAULT 0,
`emote_hierarchy` INT(11) NOT NULL DEFAULT 0,
`emote_string` VARCHAR(50) NOT NULL COLLATE 'ascii_general_nopad_ci',
`emote_url` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`emote_id`),
UNIQUE INDEX `emotes_string` (`emote_string`),
INDEX `emotes_order` (`emote_order`),
INDEX `emotes_hierarchy` (`emote_hierarchy`),
INDEX `emotes_url` (`emote_url`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
}

View File

@ -1,14 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\CreateConfigTable;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
CREATE TABLE `msz_config` (
`config_name` VARCHAR(100) NOT NULL COLLATE 'utf8mb4_bin',
`config_value` BLOB NOT NULL DEFAULT '',
PRIMARY KEY (`config_name`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
}

View File

@ -1,161 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\ProfileFieldsInDatabase;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
CREATE TABLE `msz_profile_fields` (
`field_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`field_order` INT(11) NOT NULL DEFAULT 0,
`field_key` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
`field_title` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_bin',
`field_regex` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`field_id`),
UNIQUE INDEX `profile_fields_key_unique` (`field_key`),
INDEX `profile_fields_order_key` (`field_order`)
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_profile_fields_formats` (
`format_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`field_id` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`format_regex` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`format_link` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
`format_display` VARCHAR(255) NOT NULL DEFAULT '%s' COLLATE 'utf8mb4_bin',
PRIMARY KEY (`format_id`),
INDEX `profile_field_format_field_foreign` (`field_id`),
CONSTRAINT `profile_field_format_field_foreign`
FOREIGN KEY (`field_id`)
REFERENCES `msz_profile_fields` (`field_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$conn->exec("
CREATE TABLE `msz_profile_fields_values` (
`field_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NOT NULL,
`format_id` INT(10) UNSIGNED NOT NULL,
`field_value` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`field_id`, `user_id`),
INDEX `profile_fields_values_format_foreign` (`format_id`),
INDEX `profile_fields_values_user_foreign` (`user_id`),
INDEX `profile_fields_values_value_key` (`field_value`),
CONSTRAINT `profile_fields_values_field_foreign`
FOREIGN KEY (`field_id`)
REFERENCES `msz_profile_fields` (`field_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `profile_fields_values_format_foreign`
FOREIGN KEY (`format_id`)
REFERENCES `msz_profile_fields_formats` (`format_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `profile_fields_values_user_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
$fieldIds = [];
$fields = [
['order' => 10, 'key' => 'website', 'title' => 'Website', 'regex' => '#^((?:https?)://.{1,240})$#u'],
['order' => 20, 'key' => 'youtube', 'title' => 'Youtube', 'regex' => '#^(?:https?://(?:www.)?youtube.com/(?:(?:user|c|channel)/)?)?(UC[a-zA-Z0-9-_]{1,22}|[a-zA-Z0-9-_%]{1,100})/?$#u'],
['order' => 30, 'key' => 'twitter', 'title' => 'Twitter', 'regex' => '#^(?:https?://(?:www\.)?twitter.com/(?:\#!\/)?)?@?([A-Za-z0-9_]{1,20})/?$#u'],
['order' => 40, 'key' => 'ninswitch', 'title' => 'Nintendo Switch', 'regex' => '#^(?:SW-)?([0-9]{4}-[0-9]{4}-[0-9]{4})$#u'],
['order' => 50, 'key' => 'twitchtv', 'title' => 'Twitch.tv', 'regex' => '#^(?:https?://(?:www.)?twitch.tv/)?([0-9A-Za-z_]{3,25})/?$#u'],
['order' => 60, 'key' => 'steam', 'title' => 'Steam', 'regex' => '#^(?:https?://(?:www.)?steamcommunity.com/(?:id|profiles)/)?([a-zA-Z0-9_-]{2,100})/?$#u'],
['order' => 70, 'key' => 'osu', 'title' => 'osu!', 'regex' => '#^(?:https?://osu.ppy.sh/u(?:sers)?/)?([a-zA-Z0-9-\[\]_ ]{1,20})/?$#u'],
['order' => 80, 'key' => 'lastfm', 'title' => 'Last.fm', 'regex' => '#^(?:https?://(?:www.)?last.fm/user/)?([a-zA-Z]{1}[a-zA-Z0-9_-]{1,14})/?$#u'],
['order' => 90, 'key' => 'github', 'title' => 'Github', 'regex' => '#^(?:https?://(?:www.)?github.com/?)?([a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38})/?$#u'],
['order' => 100, 'key' => 'skype', 'title' => 'Skype', 'regex' => '#^((?:live:)?[a-zA-Z][\w\.,\-_@]{1,100})$#u'],
['order' => 110, 'key' => 'discord', 'title' => 'Discord', 'regex' => '#^(.{1,32}\#[0-9]{4})$#u'],
];
$formats = [
['field' => 'website', 'regex' => null, 'display' => '%s', 'link' => '%s'],
['field' => 'youtube', 'regex' => null, 'display' => '%s', 'link' => 'https://youtube.com/%s'],
['field' => 'youtube', 'regex' => '^UC[a-zA-Z0-9-_]{1,22}$', 'display' => 'Go to Channel', 'link' => 'https://youtube.com/channel/%s'],
['field' => 'twitter', 'regex' => null, 'display' => '@%s', 'link' => 'https://twitter.com/%s'],
['field' => 'ninswitch', 'regex' => null, 'display' => 'SW-%s', 'link' => null],
['field' => 'twitchtv', 'regex' => null, 'display' => '%s', 'link' => 'https://twitch.tv/%s'],
['field' => 'steam', 'regex' => null, 'display' => '%s', 'link' => 'https://steamcommunity.com/id/%s'],
['field' => 'osu', 'regex' => null, 'display' => '%s', 'link' => 'https://osu.ppy.sh/users/%s'],
['field' => 'lastfm', 'regex' => null, 'display' => '%s', 'link' => 'https://www.last.fm/user/%s'],
['field' => 'github', 'regex' => null, 'display' => '%s', 'link' => 'https://github.com/%s'],
['field' => 'skype', 'regex' => null, 'display' => '%s', 'link' => 'skype:%s?userinfo'],
['field' => 'discord', 'regex' => null, 'display' => '%s', 'link' => null],
];
$insertField = $conn->prepare("INSERT INTO `msz_profile_fields` (`field_order`, `field_key`, `field_title`, `field_regex`) VALUES (:order, :key, :title, :regex)");
$insertFormat = $conn->prepare("INSERT INTO `msz_profile_fields_formats` (`field_id`, `format_regex`, `format_link`, `format_display`) VALUES (:field, :regex, :link, :display)");
$insertValue = $conn->prepare("INSERT INTO `msz_profile_fields_values` (`field_id`, `user_id`, `format_id`, `field_value`) VALUES (:field, :user, :format, :value)");
for($i = 0; $i < count($fields); $i++) {
$insertField->execute($fields[$i]);
$fields[$i]['id'] = $fieldIds[$fields[$i]['key']] = (int)$conn->lastInsertId();
}
for($i = 0; $i < count($formats); $i++) {
$formats[$i]['field'] = $fieldIds[$formats[$i]['field']];
$insertFormat->execute($formats[$i]);
$formats[$i]['id'] = (int)$conn->lastInsertId();
}
$users = $conn->query("
SELECT `user_id`, `user_website`, `user_twitter`, `user_github`, `user_skype`, `user_discord`,
`user_youtube`, `user_steam`, `user_ninswitch`, `user_twitchtv`, `user_osu`, `user_lastfm`
FROM `msz_users`
")->fetchAll(PDO::FETCH_ASSOC);
foreach($users as $user) {
foreach($fields as $field) {
$source = 'user_' . $field['key'];
$formatId = 0;
if(empty($user[$source]))
continue;
foreach($formats as $format) {
if($format['field'] != $field['id'])
continue;
if(empty($format['regex']) && $formatId < 1) {
$formatId = $format['id'];
continue;
}
if(preg_match("#{$format['regex']}#", $user[$source])) {
$formatId = $format['id'];
break;
}
}
$insertValue->execute([
'field' => $field['id'],
'user' => $user['user_id'],
'format' => $formatId,
'value' => $user[$source],
]);
}
}
$conn->exec("
ALTER TABLE `msz_users`
DROP COLUMN `user_website`,
DROP COLUMN `user_twitter`,
DROP COLUMN `user_github`,
DROP COLUMN `user_skype`,
DROP COLUMN `user_discord`,
DROP COLUMN `user_youtube`,
DROP COLUMN `user_steam`,
DROP COLUMN `user_ninswitch`,
DROP COLUMN `user_twitchtv`,
DROP COLUMN `user_osu`,
DROP COLUMN `user_lastfm`;
");
}

View File

@ -1,75 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\EmoticonRestructure;
use PDO;
function migrate_up(PDO $conn): void {
$emotes = $conn->query('SELECT * FROM `msz_emoticons`')->fetchAll(PDO::FETCH_ASSOC);
$pruneDupes = $conn->prepare('DELETE FROM `msz_emoticons` WHERE `emote_id` = :id');
// int order, int hierarchy, string url, array(string string, int order) strings
$images = [];
$delete = [];
foreach($emotes as $emote) {
if(!isset($images[$emote['emote_url']])) {
$images[$emote['emote_url']] = [
'id' => $emote['emote_id'],
'order' => $emote['emote_order'],
'hierarchy' => $emote['emote_hierarchy'],
'url' => $emote['emote_url'],
'strings' => [],
];
} else {
$delete[] = $emote['emote_id'];
}
$images[$emote['emote_url']]['strings'][] = [
'string' => $emote['emote_string'],
'order' => count($images[$emote['emote_url']]['strings']) + 1,
];
}
foreach($delete as $id) {
$pruneDupes->bindValue('id', $id);
$pruneDupes->execute();
}
$conn->exec('
ALTER TABLE `msz_emoticons`
DROP COLUMN `emote_string`,
DROP INDEX `emotes_string`,
DROP INDEX `emotes_url`,
ADD UNIQUE INDEX `emotes_url` (`emote_url`);
');
$conn->exec("
CREATE TABLE `msz_emoticons_strings` (
`emote_id` INT UNSIGNED NOT NULL,
`emote_string_order` MEDIUMINT NOT NULL DEFAULT 0,
`emote_string` VARCHAR(50) NOT NULL COLLATE 'ascii_general_nopad_ci',
INDEX `string_emote_foreign` (`emote_id`),
INDEX `string_order_key` (`emote_string_order`),
UNIQUE INDEX `string_unique` (`emote_string`),
CONSTRAINT `string_emote_foreign`
FOREIGN KEY (`emote_id`)
REFERENCES `msz_emoticons` (`emote_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin';
");
$insertString = $conn->prepare('
INSERT INTO `msz_emoticons_strings` (`emote_id`, `emote_string_order`, `emote_string`)
VALUES (:id, :order, :string)
');
foreach($images as $image) {
$insertString->bindValue('id', $image['id']);
foreach($image['strings'] as $string) {
$insertString->bindValue('order', $string['order']);
$insertString->bindValue('string', $string['string']);
$insertString->execute();
}
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\AddedChatTokensTable;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
CREATE TABLE `msz_user_chat_tokens` (
`user_id` INT(10) UNSIGNED NOT NULL,
`token_string` CHAR(64) NOT NULL,
`token_created` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
UNIQUE INDEX `user_chat_token_string_unique` (`token_string`),
INDEX `user_chat_token_user_foreign` (`user_id`),
INDEX `user_chat_token_created_key` (`token_created`),
CONSTRAINT `user_chat_token_user_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
}

View File

@ -1,12 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\AuditLogTableFixes;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec('
ALTER TABLE `msz_audit_log`
DROP COLUMN `log_id`,
ADD INDEX `audit_log_created_index` (`log_created`);
');
}

View File

@ -1,12 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\LoginAttemptsTableFixes;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
ALTER TABLE `msz_login_attempts`
DROP COLUMN `attempt_id`,
ADD INDEX `login_attempts_created_index` (`attempt_created`);
");
}

View File

@ -1,13 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\SessionsTableFixes;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
ALTER TABLE `msz_sessions`
CHANGE COLUMN `session_key` `session_key` BINARY(64) NOT NULL AFTER `user_id`,
CHANGE COLUMN `session_expires` `session_expires` TIMESTAMP NOT NULL DEFAULT DATE_ADD(NOW(), INTERVAL 1 MONTH) AFTER `session_country`,
ADD INDEX `sessions_created_index` (`session_created`);
");
}

View File

@ -1,35 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\AddMissingIndexes;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
ALTER TABLE `msz_forum_categories`
ADD INDEX `forum_link_clicks_index` (`forum_link_clicks`),
ADD INDEX `forum_hidden_index` (`forum_hidden`);
");
$conn->exec("
ALTER TABLE `msz_login_attempts`
ADD INDEX `login_attempts_success_index` (`attempt_success`),
ADD INDEX `login_attempts_ip_index` (`attempt_ip`);
");
$conn->exec("
ALTER TABLE `msz_news_categories`
ADD INDEX `news_categories_is_hidden_index` (`category_is_hidden`);
");
$conn->exec("
ALTER TABLE `msz_roles`
ADD INDEX `roles_hierarchy_index` (`role_hierarchy`),
ADD INDEX `roles_hidden_index` (`role_hidden`);
");
$conn->exec("
ALTER TABLE `msz_user_relations`
ADD INDEX `user_relations_type_index` (`relation_type`),
ADD INDEX `user_relations_created_index` (`relation_created`);
");
}

View File

@ -1,16 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\RecoveryTableFixes;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
ALTER TABLE `msz_users_password_resets`
CHANGE COLUMN `verification_code` `verification_code` CHAR(12) NULL DEFAULT NULL COLLATE 'ascii_bin' AFTER `reset_requested`,
DROP INDEX `msz_users_password_resets_unique`,
ADD UNIQUE INDEX `users_password_resets_user_unique` (`user_id`, `reset_ip`),
DROP INDEX `msz_users_password_resets_index`,
ADD INDEX `users_password_resets_created_index` (`reset_requested`),
ADD UNIQUE INDEX `users_password_resets_token_unique` (`verification_code`);
");
}

View File

@ -1,16 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\CaseInsensitiveForumSearch;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
ALTER TABLE `msz_forum_topics`
CHANGE COLUMN `topic_title` `topic_title` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci' AFTER `topic_type`;
");
$conn->exec("
ALTER TABLE `msz_forum_posts`
CHANGE COLUMN `post_text` `post_text` TEXT(65535) NOT NULL COLLATE 'utf8mb4_unicode_ci' AFTER `post_ip`;
");
}

View File

@ -1,17 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\AddOwnerIdToComments;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("
ALTER TABLE `msz_comments_categories`
ADD COLUMN `owner_id` INT UNSIGNED NULL DEFAULT NULL AFTER `category_name`,
ADD INDEX `comments_categories_owner_foreign` (`owner_id`),
ADD CONSTRAINT `comments_categories_owner_foreign`
FOREIGN KEY (`owner_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE SET NULL;
");
}

View File

@ -1,8 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\NukeRelationsTable;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("DROP TABLE `msz_user_relations`");
}

View File

@ -1,8 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\NukeChatTokensTable;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("DROP TABLE `msz_user_chat_tokens`");
}

View File

@ -1,12 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\NukeOldWipForumComponents;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec('ALTER TABLE `msz_forum_topics` DROP COLUMN `poll_id`, DROP INDEX `posts_poll_id_foreign`, DROP FOREIGN KEY `posts_poll_id_foreign`;');
$conn->exec('DROP TABLE msz_forum_polls_answers;');
$conn->exec('DROP TABLE msz_forum_polls_options;');
$conn->exec('DROP TABLE msz_forum_polls;');
$conn->exec('DROP TABLE msz_forum_topics_priority;');
}

View File

@ -1,8 +0,0 @@
<?php
namespace Misuzu\DatabaseMigrations\RemoveIpBlacklist;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec('DROP TABLE msz_ip_blacklist;');
}

View File

@ -0,0 +1,685 @@
<?php
use Index\Data\IDbConnection;
use Index\Data\Migration\IDbMigration;
// Switching to the Index migration system!!!!!!
final class InitialStructureNdx_20230107_023235 implements IDbMigration {
public function migrate(IDbConnection $conn): void {
$hasMszTrack = false;
// check if the old migrations table exists
$tables = $conn->query('SHOW TABLES');
while($tables->next())
if($tables->getString(0) === 'msz_migrations') {
$hasMszTrack = true;
break;
}
// nuke it and bail
if($hasMszTrack) {
$conn->execute('DROP TABLE msz_migrations');
return;
}
$conn->execute('
CREATE TABLE msz_roles (
role_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
role_hierarchy INT(11) NOT NULL DEFAULT 1,
role_name VARCHAR(255) NOT NULL,
role_title VARCHAR(64) DEFAULT NULL,
role_description TEXT DEFAULT NULL,
role_hidden TINYINT(1) NOT NULL DEFAULT 0,
role_can_leave TINYINT(1) NOT NULL DEFAULT 0,
role_colour INT(11) DEFAULT NULL,
role_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (role_id),
KEY roles_hierarchy_index (role_hierarchy),
KEY roles_hidden_index (role_hidden)
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_users (
user_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(255) NOT NULL,
password VARCHAR(255) DEFAULT NULL,
email VARCHAR(255) NOT NULL,
register_ip VARBINARY(16) NOT NULL,
last_ip VARBINARY(16) NOT NULL,
user_super TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
user_country CHAR(2) NOT NULL DEFAULT \'XX\',
user_colour INT(11) DEFAULT NULL,
user_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
user_active TIMESTAMP NULL DEFAULT NULL,
user_deleted TIMESTAMP NULL DEFAULT NULL,
display_role INT(10) UNSIGNED DEFAULT NULL,
user_totp_key CHAR(26) DEFAULT NULL,
user_about_content TEXT DEFAULT NULL,
user_about_parser TINYINT(4) NOT NULL DEFAULT 0,
user_signature_content TEXT DEFAULT NULL,
user_signature_parser TINYINT(4) NOT NULL DEFAULT 0,
user_birthdate DATE DEFAULT NULL,
user_background_settings TINYINT(4) DEFAULT 0,
user_title VARCHAR(64) DEFAULT NULL,
PRIMARY KEY (user_id),
UNIQUE KEY users_username_unique (username),
UNIQUE KEY users_email_unique (email),
KEY users_display_role_foreign (display_role),
KEY users_indices (user_country, user_created, user_active, user_deleted, user_birthdate),
CONSTRAINT users_display_role_foreign
FOREIGN KEY (display_role)
REFERENCES msz_roles (role_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_audit_log (
user_id INT(10) UNSIGNED DEFAULT NULL,
log_action VARCHAR(50) NOT NULL,
log_params TEXT NOT NULL,
log_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
log_ip VARBINARY(16) DEFAULT NULL,
log_country CHAR(2) NOT NULL DEFAULT \'XX\',
KEY audit_log_user_id_foreign (user_id),
KEY audit_log_created_index (log_created),
CONSTRAINT audit_log_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_auth_tfa (
user_id INT(10) UNSIGNED NOT NULL,
tfa_token CHAR(32) NOT NULL,
tfa_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
UNIQUE KEY auth_tfa_token_unique (tfa_token),
KEY auth_tfa_user_foreign (user_id),
KEY auth_tfa_created_index (tfa_created),
CONSTRAINT auth_tfa_user_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_changelog_changes (
change_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT(10) UNSIGNED DEFAULT NULL,
change_action INT(10) UNSIGNED DEFAULT NULL,
change_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
change_log VARCHAR(255) NOT NULL,
change_text TEXT DEFAULT NULL,
PRIMARY KEY (change_id),
KEY changes_user_foreign (user_id),
KEY changes_action_index (change_action),
KEY changes_created_index (change_created),
CONSTRAINT changes_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_changelog_tags (
tag_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
tag_name VARCHAR(255) NOT NULL,
tag_description TEXT DEFAULT NULL,
tag_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
tag_archived TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (tag_id),
UNIQUE KEY tag_name (tag_name),
KEY tag_archived (tag_archived)
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_changelog_change_tags (
change_id INT(10) UNSIGNED NOT NULL,
tag_id INT(10) UNSIGNED NOT NULL,
UNIQUE KEY change_tag_unique (change_id, tag_id),
KEY tag_id_foreign_key (tag_id),
CONSTRAINT change_id_foreign_key
FOREIGN KEY (change_id)
REFERENCES msz_changelog_changes (change_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT tag_id_foreign_key
FOREIGN KEY (tag_id)
REFERENCES msz_changelog_tags (tag_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_comments_categories (
category_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
category_name VARCHAR(255) NOT NULL,
owner_id INT(10) UNSIGNED DEFAULT NULL,
category_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
category_locked TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (category_id),
UNIQUE KEY comments_categories_name_unique (category_name),
KEY comments_categories_locked_index (category_locked),
KEY comments_categories_owner_foreign (owner_id),
CONSTRAINT comments_categories_owner_foreign
FOREIGN KEY (owner_id)
REFERENCES msz_users (user_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_comments_posts (
comment_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
category_id INT(10) UNSIGNED NOT NULL,
user_id INT(10) UNSIGNED DEFAULT NULL,
comment_reply_to INT(10) UNSIGNED DEFAULT NULL,
comment_text TEXT NOT NULL,
comment_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
comment_pinned TIMESTAMP NULL DEFAULT NULL,
comment_edited TIMESTAMP NULL DEFAULT NULL ON UPDATE current_timestamp(),
comment_deleted TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (comment_id),
KEY comments_posts_category_foreign (category_id),
KEY comments_posts_user_foreign (user_id),
KEY comments_posts_reply_id (comment_reply_to),
KEY comments_posts_dates (comment_created, comment_pinned, comment_edited, comment_deleted),
CONSTRAINT comments_posts_category_foreign
FOREIGN KEY (category_id)
REFERENCES msz_comments_categories (category_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT comments_posts_user_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_comments_votes (
comment_id INT(10) UNSIGNED NOT NULL,
user_id INT(10) UNSIGNED NOT NULL,
comment_vote TINYINT(4) NOT NULL DEFAULT 0,
UNIQUE KEY comments_vote_unique (comment_id, user_id),
KEY comments_vote_user_foreign (user_id),
KEY comments_vote_index (comment_vote),
CONSTRAINT comment_vote_id
FOREIGN KEY (comment_id)
REFERENCES msz_comments_posts (comment_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT comment_vote_user
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_config (
config_name varchar(100) NOT NULL,
config_value blob NOT NULL DEFAULT \'\',
PRIMARY KEY (config_name)
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_emoticons (
emote_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
emote_order MEDIUMINT(9) NOT NULL DEFAULT 0,
emote_hierarchy INT(11) NOT NULL DEFAULT 0,
emote_url VARCHAR(255) NOT NULL,
PRIMARY KEY (emote_id),
UNIQUE KEY emotes_url (emote_url),
KEY emotes_order (emote_order),
KEY emotes_hierarchy (emote_hierarchy)
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_emoticons_strings (
emote_id INT(10) UNSIGNED NOT NULL,
emote_string_order MEDIUMINT(9) NOT NULL DEFAULT 0,
emote_string VARCHAR(50) CHARACTER SET ascii COLLATE ascii_general_nopad_ci NOT NULL,
UNIQUE KEY string_unique (emote_string),
KEY string_emote_foreign (emote_id),
KEY string_order_key (emote_string_order),
CONSTRAINT string_emote_foreign
FOREIGN KEY (emote_id)
REFERENCES msz_emoticons (emote_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_forum_categories (
forum_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
forum_order INT(10) UNSIGNED NOT NULL DEFAULT 1,
forum_parent INT(10) UNSIGNED NOT NULL DEFAULT 0,
forum_name VARCHAR(255) NOT NULL,
forum_type TINYINT(4) NOT NULL DEFAULT 0,
forum_description TEXT DEFAULT NULL,
forum_icon VARCHAR(50) DEFAULT NULL,
forum_colour INT(10) UNSIGNED DEFAULT NULL,
forum_link VARCHAR(255) DEFAULT NULL,
forum_link_clicks INT(10) UNSIGNED DEFAULT NULL,
forum_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
forum_archived TINYINT(1) NOT NULL DEFAULT 0,
forum_hidden TINYINT(1) NOT NULL DEFAULT 0,
forum_count_topics INT(10) UNSIGNED NOT NULL DEFAULT 0,
forum_count_posts INT(10) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (forum_id),
KEY forum_order_index (forum_order),
KEY forum_parent_index (forum_parent),
KEY forum_type_index (forum_type),
KEY forum_link_clicks_index (forum_link_clicks),
KEY forum_hidden_index (forum_hidden)
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_forum_permissions (
user_id INT(10) UNSIGNED DEFAULT NULL,
role_id INT(10) UNSIGNED DEFAULT NULL,
forum_id INT(10) UNSIGNED NOT NULL,
forum_perms_allow INT(10) UNSIGNED NOT NULL DEFAULT 0,
forum_perms_deny INT(10) UNSIGNED NOT NULL DEFAULT 0,
UNIQUE KEY forum_permissions_unique (user_id, role_id, forum_id),
KEY forum_permissions_forum_id (forum_id),
KEY forum_permissions_role_id (role_id),
CONSTRAINT forum_permissions_forum_id_foreign
FOREIGN KEY (forum_id)
REFERENCES msz_forum_categories (forum_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT forum_permissions_role_id_foreign
FOREIGN KEY (role_id)
REFERENCES msz_roles (role_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT forum_permissions_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_forum_topics (
topic_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
forum_id INT(10) UNSIGNED NOT NULL,
user_id INT(10) UNSIGNED DEFAULT NULL,
topic_type TINYINT(4) NOT NULL DEFAULT 0,
topic_title VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
topic_count_views INT(10) UNSIGNED NOT NULL DEFAULT 0,
topic_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
topic_bumped TIMESTAMP NOT NULL DEFAULT current_timestamp(),
topic_deleted TIMESTAMP NULL DEFAULT NULL,
topic_locked TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (topic_id),
KEY topics_forum_id_foreign (forum_id),
KEY topics_user_id_foreign (user_id),
KEY topics_type_index (topic_type),
KEY topics_created_index (topic_created),
KEY topics_bumped_index (topic_bumped),
KEY topics_deleted_index (topic_deleted),
KEY topics_locked_index (topic_locked),
FULLTEXT KEY topics_fulltext (topic_title),
CONSTRAINT topics_forum_id_foreign
FOREIGN KEY (forum_id)
REFERENCES msz_forum_categories (forum_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT topics_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_forum_topics_track (
user_id INT(10) UNSIGNED NOT NULL,
topic_id INT(10) UNSIGNED NOT NULL,
forum_id INT(10) UNSIGNED NOT NULL,
track_last_read TIMESTAMP NOT NULL DEFAULT current_timestamp(),
UNIQUE KEY topics_track_unique (user_id, topic_id),
KEY topics_track_topic_id_foreign (topic_id),
KEY topics_track_user_id_foreign (user_id),
KEY topics_track_forum_id_foreign (forum_id),
KEY forum_track_last_read (track_last_read),
CONSTRAINT topics_track_forum_id_foreign
FOREIGN KEY (forum_id)
REFERENCES msz_forum_categories (forum_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT topics_track_topic_id_foreign
FOREIGN KEY (topic_id)
REFERENCES msz_forum_topics (topic_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT topics_track_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_forum_posts (
post_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
topic_id INT(10) UNSIGNED NOT NULL,
forum_id INT(10) UNSIGNED NOT NULL,
user_id INT(10) UNSIGNED DEFAULT NULL,
post_ip VARBINARY(16) NOT NULL,
post_text MEDIUMTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
post_parse TINYINT(4) UNSIGNED NOT NULL DEFAULT 0,
post_display_signature TINYINT(4) UNSIGNED NOT NULL DEFAULT 1,
post_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
post_edited TIMESTAMP NULL DEFAULT NULL,
post_deleted TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (post_id),
KEY posts_topic_id_foreign (topic_id),
KEY posts_forum_id_foreign (forum_id),
KEY posts_user_id_foreign (user_id),
KEY posts_created_index (post_created),
KEY posts_deleted_index (post_deleted),
KEY posts_parse_index (post_parse),
KEY posts_edited_index (post_edited),
KEY posts_display_signature_index (post_display_signature),
KEY posts_ip_index (post_ip),
FULLTEXT KEY posts_fulltext (post_text),
CONSTRAINT posts_forum_id_foreign
FOREIGN KEY (forum_id)
REFERENCES msz_forum_categories (forum_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT posts_topic_id_foreign
FOREIGN KEY (topic_id)
REFERENCES msz_forum_topics (topic_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT posts_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_login_attempts (
user_id INT(10) UNSIGNED DEFAULT NULL,
attempt_success TINYINT(1) NOT NULL,
attempt_ip VARBINARY(16) NOT NULL,
attempt_country CHAR(2) NOT NULL DEFAULT \'XX\',
attempt_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
attempt_user_agent VARCHAR(255) NOT NULL DEFAULT \'\',
KEY login_attempts_user_id_foreign (user_id),
KEY login_attempts_created_index (attempt_created),
KEY login_attempts_success_index (attempt_success),
KEY login_attempts_ip_index (attempt_ip),
CONSTRAINT login_attempts_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_news_categories (
category_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
category_name VARCHAR(255) NOT NULL,
category_description TEXT NOT NULL,
category_is_hidden TINYINT(1) NOT NULL DEFAULT 0,
category_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (category_id),
KEY news_categories_is_hidden_index (category_is_hidden)
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_news_posts (
post_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
category_id INT(10) UNSIGNED NOT NULL,
user_id INT(10) UNSIGNED DEFAULT NULL,
comment_section_id INT(10) UNSIGNED DEFAULT NULL,
post_is_featured TINYINT(1) NOT NULL DEFAULT 0,
post_title VARCHAR(255) NOT NULL,
post_text TEXT NOT NULL,
post_scheduled TIMESTAMP NOT NULL DEFAULT current_timestamp(),
post_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
post_updated TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
post_deleted TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (post_id),
KEY news_posts_category_id_foreign (category_id),
KEY news_posts_user_id_foreign (user_id),
KEY news_posts_comment_section (comment_section_id),
KEY news_posts_featured_index (post_is_featured),
KEY news_posts_scheduled_index (post_scheduled),
KEY news_posts_created_index (post_created),
KEY news_posts_updated_index (post_updated),
KEY news_posts_deleted_index (post_deleted),
FULLTEXT KEY news_posts_fulltext (post_title, post_text),
CONSTRAINT news_posts_category_id_foreign
FOREIGN KEY (category_id)
REFERENCES msz_news_categories (category_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT news_posts_comment_section
FOREIGN KEY (comment_section_id)
REFERENCES msz_comments_categories (category_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT news_posts_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_permissions (
user_id INT(10) UNSIGNED DEFAULT NULL,
role_id INT(10) UNSIGNED DEFAULT NULL,
general_perms_allow INT(10) UNSIGNED NOT NULL DEFAULT 0,
general_perms_deny INT(10) UNSIGNED NOT NULL DEFAULT 0,
user_perms_allow INT(10) UNSIGNED NOT NULL DEFAULT 0,
user_perms_deny INT(10) UNSIGNED NOT NULL DEFAULT 0,
changelog_perms_allow INT(10) UNSIGNED NOT NULL DEFAULT 0,
changelog_perms_deny INT(10) UNSIGNED NOT NULL DEFAULT 0,
news_perms_allow INT(10) UNSIGNED NOT NULL DEFAULT 0,
news_perms_deny INT(10) UNSIGNED NOT NULL DEFAULT 0,
forum_perms_allow INT(10) UNSIGNED NOT NULL DEFAULT 0,
forum_perms_deny INT(10) UNSIGNED NOT NULL DEFAULT 0,
comments_perms_allow INT(10) UNSIGNED NOT NULL DEFAULT 0,
comments_perms_deny INT(10) UNSIGNED NOT NULL DEFAULT 0,
UNIQUE KEY permissions_user_id_unique (user_id),
UNIQUE KEY permissions_role_id_unique (role_id),
CONSTRAINT permissions_role_id_foreign
FOREIGN KEY (role_id)
REFERENCES msz_roles (role_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT permissions_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_profile_fields (
field_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
field_order INT(11) NOT NULL DEFAULT 0,
field_key VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
field_title VARCHAR(50) NOT NULL,
field_regex VARCHAR(255) NOT NULL,
PRIMARY KEY (field_id),
UNIQUE KEY profile_fields_key_unique (field_key),
KEY profile_fields_order_key (field_order)
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_profile_fields_formats (
format_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
field_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
format_regex VARCHAR(255) DEFAULT NULL,
format_link VARCHAR(255) DEFAULT NULL,
format_display VARCHAR(255) NOT NULL DEFAULT \'%s\',
PRIMARY KEY (format_id),
KEY profile_field_format_field_foreign (field_id),
CONSTRAINT profile_field_format_field_foreign
FOREIGN KEY (field_id)
REFERENCES msz_profile_fields (field_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_profile_fields_values (
field_id INT(10) UNSIGNED NOT NULL,
user_id INT(10) UNSIGNED NOT NULL,
format_id INT(10) UNSIGNED NOT NULL,
field_value VARCHAR(255) NOT NULL,
PRIMARY KEY (field_id, user_id),
KEY profile_fields_values_format_foreign (format_id),
KEY profile_fields_values_user_foreign (user_id),
KEY profile_fields_values_value_key (field_value),
CONSTRAINT profile_fields_values_field_foreign
FOREIGN KEY (field_id)
REFERENCES msz_profile_fields (field_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT profile_fields_values_format_foreign
FOREIGN KEY (format_id)
REFERENCES msz_profile_fields_formats (format_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT profile_fields_values_user_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_sessions (
session_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT(10) UNSIGNED NOT NULL,
session_key BINARY(64) NOT NULL,
session_ip VARBINARY(16) NOT NULL,
session_ip_last VARBINARY(16) DEFAULT NULL,
session_user_agent VARCHAR(255) NOT NULL,
session_country CHAR(2) NOT NULL DEFAULT \'XX\',
session_expires TIMESTAMP NOT NULL DEFAULT (current_timestamp() + INTERVAL 1 MONTH),
session_expires_bump TINYINT(3) UNSIGNED NOT NULL DEFAULT 1,
session_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
session_active TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (session_id),
UNIQUE KEY sessions_key_unique (session_key),
KEY sessions_user_id_foreign (user_id),
KEY sessions_expires_index (session_expires),
KEY sessions_created_index (session_created),
CONSTRAINT sessions_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_users_password_resets (
user_id INT(10) UNSIGNED NOT NULL,
reset_ip VARBINARY(16) NOT NULL,
reset_requested TIMESTAMP NOT NULL DEFAULT current_timestamp(),
verification_code CHAR(12) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL,
UNIQUE KEY users_password_resets_user_unique (user_id,reset_ip),
UNIQUE KEY users_password_resets_token_unique (verification_code),
KEY users_password_resets_created_index (reset_requested),
CONSTRAINT msz_users_password_resets_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_user_roles (
user_id INT(10) UNSIGNED NOT NULL,
role_id INT(10) UNSIGNED NOT NULL,
UNIQUE KEY user_roles_unique (user_id, role_id),
KEY user_roles_role_id_foreign (role_id),
CONSTRAINT user_roles_role_id_foreign
FOREIGN KEY (role_id)
REFERENCES msz_roles (role_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT user_roles_user_id_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
$conn->execute('
CREATE TABLE msz_user_warnings (
warning_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT(10) UNSIGNED NOT NULL,
user_ip VARBINARY(16) NOT NULL,
issuer_id INT(10) UNSIGNED DEFAULT NULL,
issuer_ip VARBINARY(16) NOT NULL,
warning_created TIMESTAMP NOT NULL DEFAULT current_timestamp(),
warning_duration TIMESTAMP NULL DEFAULT NULL,
warning_type TINYINT(3) UNSIGNED NOT NULL,
warning_note VARCHAR(255) NOT NULL,
warning_note_private TEXT DEFAULT NULL,
PRIMARY KEY (warning_id),
KEY user_warnings_user_foreign (user_id),
KEY user_warnings_issuer_foreign (issuer_id),
KEY user_warnings_created_index (warning_created),
KEY user_warnings_duration_index (warning_duration),
KEY user_warnings_type_index (warning_type),
KEY user_warnings_user_ip_index (user_ip),
CONSTRAINT user_warnings_issuer_foreign
FOREIGN KEY (issuer_id)
REFERENCES msz_users (user_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT user_warnings_user_foreign
FOREIGN KEY (user_id)
REFERENCES msz_users (user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB COLLATE=utf8mb4_bin;
');
}
}

@ -1 +1 @@
Subproject commit f8c6602ab953491a3e540d1ab9c77f2d885ee120
Subproject commit fbe4fe18decd502a0ca15ffe8a7c3b2d847349d5

View File

@ -22,6 +22,7 @@ define('MSZ_SOURCE', MSZ_ROOT . '/src');
define('MSZ_LIBRARIES', MSZ_ROOT . '/lib');
define('MSZ_CONFIG', MSZ_ROOT . '/config');
define('MSZ_TEMPLATES', MSZ_ROOT . '/templates');
define('MSZ_MIGRATIONS', MSZ_ROOT . '/database');
define('MSZ_NDX_PATH', MSZ_LIBRARIES . '/index');
define('MSZ_NDX_PATH_DEV', MSZ_LIBRARIES . '/index-dev');

4
msz
View File

@ -13,7 +13,7 @@ if(!MSZ_CLI)
$commands = new CommandCollection;
$commands->addCommands(
new \Misuzu\Console\Commands\CronCommand($msz),
new \Misuzu\Console\Commands\MigrateCommand,
new \Misuzu\Console\Commands\NewMigrationCommand,
new \Misuzu\Console\Commands\MigrateCommand($msz),
new \Misuzu\Console\Commands\NewMigrationCommand($msz),
);
$commands->dispatch(new CommandArgs($argv));

View File

@ -2,11 +2,17 @@
namespace Misuzu\Console\Commands;
use Misuzu\DB;
use Misuzu\MisuzuContext;
use Misuzu\Console\CommandArgs;
use Misuzu\Console\CommandInterface;
use Misuzu\Database\DatabaseMigrationManager;
class MigrateCommand implements CommandInterface {
private MisuzuContext $context;
public function __construct(MisuzuContext $ctx) {
$this->context = $ctx;
}
public function getName(): string {
return 'migrate';
}
@ -20,28 +26,31 @@ class MigrateCommand implements CommandInterface {
return;
}
touch(MSZ_ROOT . '/.migrating');
chmod(MSZ_ROOT . '/.migrating', 0777);
try {
echo "Creating migration manager.." . PHP_EOL;
$migrationManager = new DatabaseMigrationManager(DB::getPDO(), MSZ_ROOT . '/database');
$migrationManager->setLogger(function ($log) {
echo $log . PHP_EOL;
});
touch(MSZ_ROOT . '/.migrating');
chmod(MSZ_ROOT . '/.migrating', 0777);
$migrationManager->migrate();
echo 'Creating migration manager...' . PHP_EOL;
$manager = $this->context->createMigrationManager();
$errors = $migrationManager->getErrors();
$errorCount = count($errors);
echo 'Preparing to run migrations...' . PHP_EOL;
$manager->init();
if($errorCount < 1) {
echo 'Completed with no errors!' . PHP_EOL;
echo 'Creating migration repository...' . PHP_EOL;
$repo = $this->context->createMigrationRepo();
echo 'Running migrations...' . PHP_EOL;
$completed = $manager->processMigrations($repo);
if(empty($completed)) {
echo 'There were no migrations to run!' . PHP_EOL;
} else {
echo PHP_EOL . "There were {$errorCount} errors during the migrations..." . PHP_EOL;
foreach($errors as $error)
echo $error . PHP_EOL;
echo 'The following migrations have been completed:' . PHP_EOL;
foreach($completed as $migration)
echo ' - ' . $migration . PHP_EOL;
}
echo PHP_EOL;
} finally {
unlink(MSZ_ROOT . '/.migrating');
}

View File

@ -1,23 +1,18 @@
<?php
namespace Misuzu\Console\Commands;
use InvalidArgumentException;
use Index\Data\Migration\FsDbMigrationRepo;
use Misuzu\MisuzuContext;
use Misuzu\Console\CommandArgs;
use Misuzu\Console\CommandInterface;
class NewMigrationCommand implements CommandInterface {
private const TEMPLATE = <<<MIG
<?php
namespace Misuzu\DatabaseMigrations\\%s;
private MisuzuContext $context;
use PDO;
function migrate_up(PDO \$conn): void {
\$conn->exec("
CREATE TABLE ...
");
}
MIG;
public function __construct(MisuzuContext $ctx) {
$this->context = $ctx;
}
public function getName(): string {
return 'new-mig';
@ -27,24 +22,24 @@ MIG;
}
public function dispatch(CommandArgs $args): void {
$name = str_replace(' ', '_', implode(' ', $args->getArgs()));
if(empty($name)) {
echo 'Specify a migration name.' . PHP_EOL;
$repo = $this->context->createMigrationRepo();
if(!($repo instanceof FsDbMigrationRepo)) {
echo 'Migration repository type does not support creation of templates.' . PHP_EOL;
return;
}
if(!preg_match('#^([a-z_]+)$#', $name)) {
echo 'Migration name may only contain alpha and _ characters.' . PHP_EOL;
$baseName = implode(' ', $args->getArgs());
$manager = $this->context->createMigrationManager();
try {
$names = $manager->createNames($baseName);
} catch(InvalidArgumentException $ex) {
echo $ex->getMessage() . PHP_EOL;
return;
}
$fileName = date('Y_m_d_His_') . trim($name, '_') . '.php';
$filePath = MSZ_ROOT . '/database/' . $fileName;
$namespace = str_replace('_', '', ucwords($name, '_'));
$repo->saveMigrationTemplate($names->name, $manager->template($names->className));
file_put_contents($filePath, sprintf(self::TEMPLATE, $namespace));
echo "Template for '{$namespace}' has been created." . PHP_EOL;
echo "Template for '{$names->className}' has been saved to {$names->name}.php." . PHP_EOL;
}
}

View File

@ -5,7 +5,6 @@ use PDO;
use Misuzu\Database\Database;
/**
* @method static PDO getPDO()
* @method static int queries()
* @method static int exec(string $stmt)
* @method static \Misuzu\Database\DatabaseStatement prepare(string $stmt, array $options = [])

View File

@ -11,10 +11,6 @@ class Database {
$this->pdo = new PDO($dsn, $username, $password, $options);
}
public function getPDO(): PDO {
return $this->pdo;
}
public function queries(): int {
return (int)$this->query('SHOW SESSION STATUS LIKE "Questions"')->fetchColumn(1);
}

View File

@ -1,155 +0,0 @@
<?php
namespace Misuzu\Database;
use Exception;
use PDO;
use PDOException;
final class DatabaseMigrationManager {
private $targetConnection;
private $migrationStorage;
private const MIGRATION_NAMESPACE = '\\Misuzu\\DatabaseMigrations\\%s\\%s';
private $errors = [];
private $logFunction;
public function __construct(PDO $conn, string $path) {
$this->targetConnection = $conn;
$this->migrationStorage = realpath($path);
}
private function addError(Exception $exception): void {
$this->errors[] = $exception;
$this->writeLog($exception->getMessage());
}
public function setLogger(callable $logger): void {
$this->logFunction = $logger;
}
private function writeLog(string $log): void {
if(!is_callable($this->logFunction)) {
return;
}
call_user_func($this->logFunction, $log);
}
public function getErrors(): array {
return $this->errors;
}
private function getMigrationScripts(): array {
if(!file_exists($this->migrationStorage) || !is_dir($this->migrationStorage)) {
$this->addError(new Exception('Migrations script directory does not exist.'));
return [];
}
$files = glob(rtrim($this->migrationStorage, '/\\') . '/*.php');
return $files;
}
private function createMigrationRepository(): bool {
try {
$this->targetConnection->exec('
CREATE TABLE IF NOT EXISTS `msz_migrations` (
`migration_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`migration_name` VARCHAR(255) NOT NULL,
`migration_batch` INT(11) UNSIGNED NOT NULL,
PRIMARY KEY (`migration_id`),
UNIQUE INDEX (`migration_id`)
)
');
} catch(PDOException $ex) {
$this->addError($ex);
return false;
}
return true;
}
public function migrate(): bool {
$this->writeLog('Running migrations...');
if(!$this->createMigrationRepository()) {
return false;
}
$migrationScripts = $this->getMigrationScripts();
if(count($migrationScripts) < 1) {
if(count($this->errors) > 0) {
return false;
}
$this->writeLog('Nothing to migrate!');
return true;
}
try {
$this->writeLog('Fetching completed migration...');
$fetchStatus = $this->targetConnection->prepare("
SELECT *, CONCAT(:basepath, '/', `migration_name`, '.php') as `migration_path`
FROM `msz_migrations`
");
$fetchStatus->bindValue('basepath', $this->migrationStorage);
$migrationStatus = $fetchStatus->execute() ? $fetchStatus->fetchAll() : [];
} catch(PDOException $ex) {
$this->addError($ex);
return false;
}
if(count($migrationStatus) < 1 && count($this->errors) > 0) {
return false;
}
$remainingMigrations = array_diff($migrationScripts, array_column($migrationStatus, 'migration_path'));
if(count($remainingMigrations) < 1) {
$this->writeLog('Nothing to migrate!');
return true;
}
$batchNumber = $this->targetConnection->query('
SELECT COALESCE(MAX(`migration_batch`), 0) + 1
FROM `msz_migrations`
')->fetchColumn();
$recordMigration = $this->targetConnection->prepare('
INSERT INTO `msz_migrations`
(`migration_name`, `migration_batch`)
VALUES
(:name, :batch)
');
$recordMigration->bindValue('batch', $batchNumber);
foreach($remainingMigrations as $migration) {
$filename = pathinfo($migration, PATHINFO_FILENAME);
$filenameSplit = explode('_', $filename);
$recordMigration->bindValue('name', $filename);
$migrationName = '';
if(count($filenameSplit) < 5) {
$this->addError(new Exception("Invalid migration name: '{$filename}'"));
return false;
}
for($i = 4; $i < count($filenameSplit); $i++) {
$migrationName .= ucfirst(mb_strtolower($filenameSplit[$i]));
}
include_once $migration;
$this->writeLog("Running migration '{$filename}'...");
$migrationFunction = sprintf(self::MIGRATION_NAMESPACE, $migrationName, 'migrate_up');
$migrationFunction($this->targetConnection);
$recordMigration->execute();
}
$this->writeLog('Successfully completed all migrations!');
return true;
}
}

View File

@ -9,6 +9,9 @@ use Misuzu\Users\Users;
use Misuzu\Twitter\TwitterClient;
use Misuzu\Twitter\TwitterRoutes;
use Index\Data\IDbConnection;
use Index\Data\Migration\IDbMigrationRepo;
use Index\Data\Migration\DbMigrationManager;
use Index\Data\Migration\FsDbMigrationRepo;
use Index\Http\HttpFx;
use Index\Http\HttpRequest;
use Index\Routing\Router;
@ -34,6 +37,14 @@ class MisuzuContext {
return $result->next() ? $result->getInteger(0) : 0;
}
public function createMigrationManager(): DbMigrationManager {
return new DbMigrationManager($this->dbConn, 'msz_' . DbMigrationManager::DEFAULT_TABLE);
}
public function createMigrationRepo(): IDbMigrationRepo {
return new FsDbMigrationRepo(MSZ_MIGRATIONS);
}
public function getConfig(): IConfig {
return $this->config;
}