query("SHOW COLUMNS FROM `{$table}` LIKE " . $db->quote($column)); return (bool) $stmt->fetch(); } function scitemcustom_column_definition(PDO $db, string $table, string $column): ?array { $stmt = $db->query("SHOW COLUMNS FROM `{$table}` LIKE " . $db->quote($column)); $column_definition = $stmt->fetch(PDO::FETCH_ASSOC); return $column_definition ?: null; } function scitemcustom_index_exists(PDO $db, string $table, string $index): bool { $stmt = $db->query("SHOW INDEX FROM `{$table}` WHERE Key_name = " . $db->quote($index)); return (bool) $stmt->fetch(); } function scitemcustom_foreign_key_exists(PDO $db, string $table, string $constraint): bool { $stmt = $db->prepare( "SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :table_name AND CONSTRAINT_NAME = :constraint_name AND CONSTRAINT_TYPE = 'FOREIGN KEY'" ); $stmt->execute([ 'table_name' => $table, 'constraint_name' => $constraint, ]); return (int) $stmt->fetchColumn() > 0; } function scitemcustom_bootstrap(): void { static $scitemcustom_bootstrap_done = false; if ($scitemcustom_bootstrap_done) { return; } $db = db(); $db->exec( "CREATE TABLE IF NOT EXISTS tbl_scitemcustom ( cl_scitemcustom_id INT(11) NOT NULL AUTO_INCREMENT, cl_scitemcustom_owner_auth_id INT UNSIGNED NOT NULL, cl_scitemcustom_obj_id INT(10) UNSIGNED NOT NULL, cl_scitemcustom_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (cl_scitemcustom_id), UNIQUE KEY uq_scitemcustom_owner_obj (cl_scitemcustom_owner_auth_id, cl_scitemcustom_obj_id), KEY idx_scitemcustom_owner (cl_scitemcustom_owner_auth_id), KEY idx_scitemcustom_obj (cl_scitemcustom_obj_id), CONSTRAINT fk_scitemcustom_owner_auth FOREIGN KEY (cl_scitemcustom_owner_auth_id) REFERENCES tbl_auth (cl_auth_id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_scitemcustom_obj FOREIGN KEY (cl_scitemcustom_obj_id) REFERENCES tbl_scobjs (cl_scobjs_id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" ); if (!scitemcustom_column_exists($db, 'tbl_scitemcustom', 'cl_scitemcustom_owner_auth_id')) { $db->exec( 'ALTER TABLE tbl_scitemcustom ADD COLUMN cl_scitemcustom_owner_auth_id INT UNSIGNED NULL AFTER cl_scitemcustom_id' ); } if (scitemcustom_index_exists($db, 'tbl_scitemcustom', 'uq_scitemcustom_obj')) { $db->exec('ALTER TABLE tbl_scitemcustom DROP INDEX uq_scitemcustom_obj'); } if (!scitemcustom_index_exists($db, 'tbl_scitemcustom', 'idx_scitemcustom_owner')) { $db->exec( 'ALTER TABLE tbl_scitemcustom ADD INDEX idx_scitemcustom_owner (cl_scitemcustom_owner_auth_id)' ); } if (!scitemcustom_index_exists($db, 'tbl_scitemcustom', 'uq_scitemcustom_owner_obj')) { $db->exec( 'ALTER TABLE tbl_scitemcustom ADD UNIQUE KEY uq_scitemcustom_owner_obj (cl_scitemcustom_owner_auth_id, cl_scitemcustom_obj_id)' ); } if (!scitemcustom_foreign_key_exists($db, 'tbl_scitemcustom', 'fk_scitemcustom_owner_auth')) { $db->exec( 'ALTER TABLE tbl_scitemcustom ADD CONSTRAINT fk_scitemcustom_owner_auth FOREIGN KEY (cl_scitemcustom_owner_auth_id) REFERENCES tbl_auth (cl_auth_id) ON DELETE CASCADE ON UPDATE CASCADE' ); } $db->exec( "CREATE TABLE IF NOT EXISTS tbl_scitemcustomstat ( cl_scitemcustomstat_id INT(11) NOT NULL AUTO_INCREMENT, cl_scitemcustomstat_itemcustom_id INT(11) NOT NULL, cl_scitemcustomstat_stat_id INT(11) NOT NULL, cl_scitemcustomstat_sign ENUM('+', '', '-') NOT NULL DEFAULT '+', cl_scitemcustomstat_value DECIMAL(10,2) NOT NULL DEFAULT 0.00, cl_scitemcustomstat_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (cl_scitemcustomstat_id), UNIQUE KEY uq_scitemcustomstat_item_stat (cl_scitemcustomstat_itemcustom_id, cl_scitemcustomstat_stat_id), KEY idx_scitemcustomstat_item (cl_scitemcustomstat_itemcustom_id), KEY idx_scitemcustomstat_stat (cl_scitemcustomstat_stat_id), CONSTRAINT fk_scitemcustomstat_item FOREIGN KEY (cl_scitemcustomstat_itemcustom_id) REFERENCES tbl_scitemcustom (cl_scitemcustom_id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_scitemcustomstat_stat FOREIGN KEY (cl_scitemcustomstat_stat_id) REFERENCES tbl_scstatsitem (cl_scstatsitem_id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" ); $sign_column = scitemcustom_column_definition($db, 'tbl_scitemcustomstat', 'cl_scitemcustomstat_sign'); if ($sign_column && ($sign_column['Type'] ?? '') !== "enum('+','','-')") { $db->exec( "ALTER TABLE tbl_scitemcustomstat MODIFY COLUMN cl_scitemcustomstat_sign ENUM('+', '', '-') NOT NULL DEFAULT '+'" ); } $scitemcustom_bootstrap_done = true; }