Add database migration tool (flatfile -> mysql)

This commit is contained in:
Trevor Slocum 2014-07-20 12:12:00 -07:00
parent 4041a57559
commit 784a8dfdd4
8 changed files with 139 additions and 74 deletions

View file

@ -72,6 +72,28 @@ Updating
- Visit [GitHub](https://github.com/tslocum/TinyIB) and review the changes made in the update.
- Ensure the update does not interfere with your changes.
Migrating
------------
TinyIB includes a database migration tool, which currently only supports migrating from flat file to MySQL. While the migration is in progress, visitors will not be able to create or delete posts.
1. Edit **settings.php**
- Ensure ``TINYIB_DBMODE`` is still set to ``flatfile``.
- Set ``TINYIB_DBMIGRATE`` to ``true``.
- Configure all MySQL-related settings.
2. Open the management panel.
3. Click **Migrate Database**
4. Click **Start the migration**
5. If the migration was successful:
- Edit **settings.php**
- Set ``TINYIB_DBMODE`` to ``mysqli``.
- Set ``TINYIB_DBMIGRATE`` to ``false``.
- Click **Rebuild All** and ensure the board still looks the way it should.
If there was a warning about AUTO_INCREMENT not being updated, you'll need to update it manually via a more privileged MySQL user. Run the following query for one or both of the tables, dependant of the warnings you were issued:
``ALTER TABLE (table name) AUTO_INCREMENT = (value to be set)``
Support
------------

View file

@ -59,6 +59,10 @@ if (TINYIB_TRIPSEED == '' || TINYIB_ADMINPASS == '') {
$redirect = true;
// Check if the request is to make a post
if (isset($_POST['message']) || isset($_POST['file'])) {
if (TINYIB_DBMIGRATE) {
fancyDie('Posting is currently disabled.<br>Please try again in a few moments.');
}
list($loggedin, $isadmin) = manageCheckLogIn();
$rawpost = isRawPost();
if (!$loggedin) {
@ -262,6 +266,10 @@ if (isset($_POST['message']) || isset($_POST['file'])) {
fancyDie('Tick the box next to a post and click "Delete" to delete it.');
}
if (TINYIB_DBMIGRATE) {
fancyDie('Post deletion is currently disabled.<br>Please try again in a few moments.');
}
$post = postByID($_POST['delete']);
if ($post) {
list($loggedin, $isadmin) = manageCheckLogIn();
@ -348,6 +356,67 @@ if (isset($_POST['message']) || isset($_POST['file'])) {
$text .= '<p><b>TinyIB was not installed via Git.</b></p>
<p>If you installed TinyIB without Git, you must <a href="https://github.com/tslocum/TinyIB">update manually</a>. If you did install with Git, ensure the script has read and write access to the <b>.git</b> folder.</p>';
}
} elseif (isset($_GET['dbmigrate'])) {
if (TINYIB_DBMIGRATE) {
if (isset($_GET['go'])) {
if (TINYIB_DBMODE == 'flatfile') {
if (function_exists('mysqli_connect')) {
$link = @mysqli_connect(TINYIB_DBHOST, TINYIB_DBUSERNAME, TINYIB_DBPASSWORD);
if (!$link) {
fancyDie("Could not connect to database: " . ((is_object($link)) ? mysqli_error($link) : (($link_error = mysqli_connect_error()) ? $link_error : '(unknown error)')));
}
$db_selected = @mysqli_query($link, "USE " . constant('TINYIB_DBNAME'));
if (!$db_selected) {
fancyDie("Could not select database: " . ((is_object($link)) ? mysqli_error($link) : (($link_error = mysqli_connect_error()) ? $link_error : '(unknown error')));
}
if (mysqli_num_rows(mysqli_query($link, "SHOW TABLES LIKE '" . TINYIB_DBPOSTS . "'")) == 0) {
if (mysqli_num_rows(mysqli_query($link, "SHOW TABLES LIKE '" . TINYIB_DBBANS . "'")) == 0) {
mysqli_query($link, $posts_sql);
mysqli_query($link, $bans_sql);
$max_id = 0;
$threads = allThreads();
foreach ($threads as $thread) {
$posts = postsInThreadByID($thread['id']);
foreach ($posts as $post) {
mysqli_query($link, "INSERT INTO `" . TINYIB_DBPOSTS . "` (`id`, `parent`, `timestamp`, `bumped`, `ip`, `name`, `tripcode`, `email`, `nameblock`, `subject`, `message`, `password`, `file`, `file_hex`, `file_original`, `file_size`, `file_size_formatted`, `image_width`, `image_height`, `thumb`, `thumb_width`, `thumb_height`) VALUES (" . $post['id'] . ", " . $post['parent'] . ", " . time() . ", " . time() . ", '" . $_SERVER['REMOTE_ADDR'] . "', '" . mysqli_real_escape_string($link, $post['name']) . "', '" . mysqli_real_escape_string($link, $post['tripcode']) . "', '" . mysqli_real_escape_string($link, $post['email']) . "', '" . mysqli_real_escape_string($link, $post['nameblock']) . "', '" . mysqli_real_escape_string($link, $post['subject']) . "', '" . mysqli_real_escape_string($link, $post['message']) . "', '" . mysqli_real_escape_string($link, $post['password']) . "', '" . $post['file'] . "', '" . $post['file_hex'] . "', '" . mysqli_real_escape_string($link, $post['file_original']) . "', " . $post['file_size'] . ", '" . $post['file_size_formatted'] . "', " . $post['image_width'] . ", " . $post['image_height'] . ", '" . $post['thumb'] . "', " . $post['thumb_width'] . ", " . $post['thumb_height'] . ")");
$max_id = max($max_id, $post['id']);
}
}
if ($max_id > 0 && !mysqli_query($link, "ALTER TABLE `" . TINYIB_DBPOSTS . "` AUTO_INCREMENT = " . ($max_id + 1))) {
$text .= '<p><b>Warning:</b> Unable to update the AUTO_INCREMENT value for table ' . TINYIB_DBPOSTS . ', please set it to ' . ($max_id + 1) . '.</p>';
}
$max_id = 0;
$bans = allBans();
foreach ($bans as $ban) {
$max_id = max($max_id, $ban['id']);
mysqli_query($link, "INSERT INTO `" . TINYIB_DBBANS . "` (`id`, `ip`, `timestamp`, `expire`, `reason`) VALUES ('" . mysqli_real_escape_string($link, $ban['id']) . "', '" . mysqli_real_escape_string($link, $ban['ip']) . "', '" . mysqli_real_escape_string($link, $ban['timestamp']) . "', '" . mysqli_real_escape_string($link, $ban['expire']) . "', '" . mysqli_real_escape_string($link, $ban['reason']) . "')");
}
if ($max_id > 0 && !mysqli_query($link, "ALTER TABLE `" . TINYIB_DBBANS . "` AUTO_INCREMENT = " . ($max_id + 1))) {
$text .= '<p><b>Warning:</b> Unable to update the AUTO_INCREMENT value for table ' . TINYIB_DBBANS . ', please set it to ' . ($max_id + 1) . '.</p>';
}
$text .= '<p><b>Database migration complete</b>. Set TINYIB_DBMODE to mysqli and TINYIB_DBMIGRATE to false, then click <b>Rebuild All</b> above and ensure everything looks the way it should.</p>';
} else {
fancyDie('Bans table (' . TINYIB_DBBANS . ') already exists! Please DROP this table and try again.');
}
} else {
fancyDie('Posts table (' . TINYIB_DBPOSTS . ') already exists! Please DROP this table and try again.');
}
} else {
fancyDie('Please install the <a href="http://php.net/manual/en/book.mysqli.php">MySQLi extension</a> and try again.');
}
} else {
fancyDie('Set TINYIB_DBMODE to flatfile and enter in your MySQL settings in settings.php before migrating.');
}
} else {
$text .= '<p>This tool currently only supports migration from a flat file database to MySQL. Your original database will not be deleted. If the migration fails, disable the tool and your board will be unaffected. See the <a href="https://github.com/tslocum/TinyIB#migrating" target="_blank">README</a> <small>(<a href="README.md" target="_blank">alternate link</a>)</small> for instructions.</a><br><br><a href="?manage&dbmigrate&go"><b>Start the migration</b></a></p>';
}
} else {
fancyDie('Set TINYIB_DBMIGRATE to true in settings.php to use this feature.');
}
}
}

View file

@ -18,46 +18,12 @@ if (!$db_selected) {
// Create the posts table if it does not exist
if (mysql_num_rows(mysql_query("SHOW TABLES LIKE '" . TINYIB_DBPOSTS . "'")) == 0) {
mysql_query("CREATE TABLE `" . TINYIB_DBPOSTS . "` (
`id` mediumint(7) unsigned NOT NULL auto_increment,
`parent` mediumint(7) unsigned NOT NULL,
`timestamp` int(20) NOT NULL,
`bumped` int(20) NOT NULL,
`ip` varchar(15) NOT NULL,
`name` varchar(75) NOT NULL,
`tripcode` varchar(10) NOT NULL,
`email` varchar(75) NOT NULL,
`nameblock` varchar(255) NOT NULL,
`subject` varchar(75) NOT NULL,
`message` text NOT NULL,
`password` varchar(255) NOT NULL,
`file` varchar(75) NOT NULL,
`file_hex` varchar(75) NOT NULL,
`file_original` varchar(255) NOT NULL,
`file_size` int(20) unsigned NOT NULL default '0',
`file_size_formatted` varchar(75) NOT NULL,
`image_width` smallint(5) unsigned NOT NULL default '0',
`image_height` smallint(5) unsigned NOT NULL default '0',
`thumb` varchar(255) NOT NULL,
`thumb_width` smallint(5) unsigned NOT NULL default '0',
`thumb_height` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `bumped` (`bumped`)
) ENGINE=MyISAM");
mysql_query($posts_sql);
}
// Create the bans table if it does not exist
if (mysql_num_rows(mysql_query("SHOW TABLES LIKE '" . TINYIB_DBBANS . "'")) == 0) {
mysql_query("CREATE TABLE `" . TINYIB_DBBANS . "` (
`id` mediumint(7) unsigned NOT NULL auto_increment,
`ip` varchar(15) NOT NULL,
`timestamp` int(20) NOT NULL,
`expire` int(20) NOT NULL,
`reason` text NOT NULL,
PRIMARY KEY (`id`),
KEY `ip` (`ip`)
) ENGINE=MyISAM");
mysql_query($bans_sql);
}
# Post Functions

View file

@ -18,46 +18,12 @@ if (!$db_selected) {
// Create the posts table if it does not exist
if (mysqli_num_rows(mysqli_query($link, "SHOW TABLES LIKE '" . TINYIB_DBPOSTS . "'")) == 0) {
mysqli_query($link, "CREATE TABLE `" . TINYIB_DBPOSTS . "` (
`id` mediumint(7) unsigned NOT NULL auto_increment,
`parent` mediumint(7) unsigned NOT NULL,
`timestamp` int(20) NOT NULL,
`bumped` int(20) NOT NULL,
`ip` varchar(15) NOT NULL,
`name` varchar(75) NOT NULL,
`tripcode` varchar(10) NOT NULL,
`email` varchar(75) NOT NULL,
`nameblock` varchar(255) NOT NULL,
`subject` varchar(75) NOT NULL,
`message` text NOT NULL,
`password` varchar(255) NOT NULL,
`file` varchar(75) NOT NULL,
`file_hex` varchar(75) NOT NULL,
`file_original` varchar(255) NOT NULL,
`file_size` int(20) unsigned NOT NULL default '0',
`file_size_formatted` varchar(75) NOT NULL,
`image_width` smallint(5) unsigned NOT NULL default '0',
`image_height` smallint(5) unsigned NOT NULL default '0',
`thumb` varchar(255) NOT NULL,
`thumb_width` smallint(5) unsigned NOT NULL default '0',
`thumb_height` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `bumped` (`bumped`)
) ENGINE=MyISAM");
mysqli_query($link, $posts_sql);
}
// Create the bans table if it does not exist
if (mysqli_num_rows(mysqli_query($link, "SHOW TABLES LIKE '" . TINYIB_DBBANS . "'")) == 0) {
mysqli_query($link, "CREATE TABLE `" . TINYIB_DBBANS . "` (
`id` mediumint(7) unsigned NOT NULL auto_increment,
`ip` varchar(15) NOT NULL,
`timestamp` int(20) NOT NULL,
`expire` int(20) NOT NULL,
`reason` text NOT NULL,
PRIMARY KEY (`id`),
KEY `ip` (`ip`)
) ENGINE=MyISAM");
mysqli_query($link, $bans_sql);
}
# Post Functions
@ -228,7 +194,7 @@ function allBans() {
function insertBan($ban) {
global $link;
mysqli_query($link, "INSERT INTO `" . TINYIB_DBBANS . "` (`ip`, `timestamp`, `expire`, `reason`) VALUES ('" . mysqli_real_escape_string($link, $ban['ip']) . "')");
mysqli_query($link, "INSERT INTO `" . TINYIB_DBBANS . "` (`ip`, `timestamp`, `expire`, `reason`) VALUES ('" . mysqli_real_escape_string($link, $ban['ip']) . "', '" . time() . "', '" . mysqli_real_escape_string($link, $ban['expire']) . "', '" . mysqli_real_escape_string($link, $ban['reason']) . "')");
return mysqli_insert_id($link);
}

View file

@ -27,3 +27,6 @@ if (!defined('TINYIB_SWF')) {
if (!defined('TINYIB_WEBM')) {
define('TINYIB_WEBM', false);
}
if (!defined('TINYIB_DBMIGRATE')) {
define('TINYIB_DBMIGRATE', false);
}

View file

@ -3,6 +3,44 @@ if (!defined('TINYIB_BOARD')) {
die('');
}
$posts_sql = "CREATE TABLE `" . TINYIB_DBPOSTS . "` (
`id` mediumint(7) unsigned NOT NULL auto_increment,
`parent` mediumint(7) unsigned NOT NULL,
`timestamp` int(20) NOT NULL,
`bumped` int(20) NOT NULL,
`ip` varchar(15) NOT NULL,
`name` varchar(75) NOT NULL,
`tripcode` varchar(10) NOT NULL,
`email` varchar(75) NOT NULL,
`nameblock` varchar(255) NOT NULL,
`subject` varchar(75) NOT NULL,
`message` text NOT NULL,
`password` varchar(255) NOT NULL,
`file` varchar(75) NOT NULL,
`file_hex` varchar(75) NOT NULL,
`file_original` varchar(255) NOT NULL,
`file_size` int(20) unsigned NOT NULL default '0',
`file_size_formatted` varchar(75) NOT NULL,
`image_width` smallint(5) unsigned NOT NULL default '0',
`image_height` smallint(5) unsigned NOT NULL default '0',
`thumb` varchar(255) NOT NULL,
`thumb_width` smallint(5) unsigned NOT NULL default '0',
`thumb_height` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `bumped` (`bumped`)
) ENGINE=MyISAM";
$bans_sql = "CREATE TABLE `" . TINYIB_DBBANS . "` (
`id` mediumint(7) unsigned NOT NULL auto_increment,
`ip` varchar(15) NOT NULL,
`timestamp` int(20) NOT NULL,
`expire` int(20) NOT NULL,
`reason` text NOT NULL,
PRIMARY KEY (`id`),
KEY `ip` (`ip`)
) ENGINE=MyISAM";
function cleanString($string) {
$search = array("<", ">");
$replace = array("&lt;", "&gt;");

View file

@ -379,7 +379,7 @@ function adminBar() {
if (!$loggedin) {
return $return;
}
return '[<a href="?manage">Status</a>] [' . (($isadmin) ? '<a href="?manage&bans">Bans</a>] [' : '') . '<a href="?manage&moderate">Moderate Post</a>] [<a href="?manage&rawpost">Raw Post</a>] [' . (($isadmin) ? '<a href="?manage&rebuildall">Rebuild All</a>] [' : '') . '<a href="?manage&logout">Log Out</a>] &middot; ' . $return;
return '[<a href="?manage">Status</a>] [' . (($isadmin) ? '<a href="?manage&bans">Bans</a>] [' : '') . '<a href="?manage&moderate">Moderate Post</a>] [<a href="?manage&rawpost">Raw Post</a>] [' . (($isadmin) ? '<a href="?manage&rebuildall">Rebuild All</a>] [' : '') . (($isadmin && TINYIB_DBMIGRATE) ? '<a href="?manage&dbmigrate"><b>Migrate Database</b></a>] [' : '') . '<a href="?manage&logout">Log Out</a>] &middot; ' . $return;
}
function managePage($text, $onload = '') {

View file

@ -21,6 +21,7 @@ define('TINYIB_TRIPSEED', ""); // Enter some random text - Used when generating
define('TINYIB_ADMINPASS', ""); // Text entered at the manage prompt to gain administrator access
define('TINYIB_MODPASS', ""); // Moderators only have access to delete posts ["" to disable]
define('TINYIB_DBMODE', "flatfile"); // Choose: flatfile / mysql / mysqli / sqlite (flatfile is not recommended for popular sites)
define('TINYIB_DBMIGRATE', false); // Enable database migration tool (see README for instructions)
// Note: The following only apply when TINYIB_DBMODE is set to mysql or mysqli (recommended)
define('TINYIB_DBHOST', "localhost");