<?php

/****
This script takes all Latin1 character encoding in the database and converts it to UTF-8
****/
define("_DO_UPDATE", true);
function db_update_173_post(){
	mysql_query("SET NAMES latin1");


	// loop through every table in the database
	$data = mysql_query("SHOW TABLES");
	$fields = array();
	$keys = array();
	$allTables = array();
	while($tableInfo = mysql_fetch_array($data)){
		$tableName = $tableInfo[0];
		$allTables[] = $tableName;
		$fieldTypes[$tableName] = array();

		// loop through every field in the table
		$query = mysql_query("DESCRIBE " . $tableName);
		$keys[$tableName] = array();
		while($rowInfo = mysql_fetch_array($query)){

			// find out if this field is a varchar, char, text, or tinytext field
			if(preg_match('/.*char.*|.*text.*|.*enum.*|set.*/i', $rowInfo['Type'])){
				// it does, so this field needs to be converted
				if(!array_key_exists($tableName, $fields)){
					$fields[$tableName] = array();
				}
				$fields[$tableName][] = $rowInfo['Field'];
				$fieldTypes[$tableName][$rowInfo['Field']] = $rowInfo['Type'];
			}
			if($rowInfo['Key'] == 'PRI'){
				$keys[$tableName][] = $rowInfo['Field'];
			}
		}
	}


	/* The array "fields" now contains the names of all fields in the database that
	need to be converted (and only those that need to be converted), stored in this format:

	[table1] => Array
	    (
		[0] => fieldname1
		[1] => fieldname2
		...
	    )

	[table2] => Array
	    (
		[0] => fieldname3
		[1] => fieldname4
		[2] => fieldname5
		...
	    )
	 ...

	Keys uses the same arrangement for tracking the key fields in the tables
	Now we need to run through those tables one at a time and convert them
	*/
	$totalFailCount = 0;
	foreach($fields as $tableName => $fieldSet){

		// if this table does not have a primary key to reference by, we'll add one
		$tempKey = false;
		if(count($keys[$tableName]) == 0){
			echo "table `$tableName` has no primary key.  We'll create one for this update and drop it afterwards.\n";
			mysql_query("ALTER TABLE `$tableName` ADD `__TEMP__id__` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY");
			$keys[$tableName][] = '__TEMP__id__';
			$tempKey = true;
		}

		// build the query that gives us the field values we need to update in this table, as well as the primary keys
		$query = "SELECT `" . implode('`, `', $fieldSet) . '`';
		for($n = 0; $n < count($keys[$tableName]); $n++){
			$query .= ", `" . $keys[$tableName][$n] . "` AS __KEYFIELD_" . ($n + 1) . "__";
		}
		$query .= " FROM $tableName";

		// fetch all of those values
		mysql_query("SET NAMES latin1");
		$updates = array();
		$data = mysql_query($query);
		while($record = mysql_fetch_array($data)){
			$updates[] = $record;
		}
		mysql_query("SET NAMES utf8");

		echo "Changing default character set on table \"$tableName\": ";
		// now we have the data - let's convert the table

		if(_DO_UPDATE){
			$query = "ALTER TABLE `$tableName` DEFAULT CHARACTER SET 'utf8'";
			$success = mysql_query($query);
			if($success){
				echo " success\n";
			}else{
				echo " Failed using query: $query\n";
				$totalFailCount ++;
			}
		}else{
			echo " success\n";
		}

		echo "\n" . 'Modifying fields: "' . implode('", "', $fieldSet) . '" in table: "' . $tableName . '"';

		// now re-insert those values into the table
		$failCount = 0;
		foreach($updates as $update){
			$query = "UPDATE $tableName SET";
			$useComma = false;
			foreach($fieldSet as $fieldName){
				$fieldValue = $update[$fieldName];
				if($useComma){
					$query .= ",";
				}else{
					$useComma = true;
				}
				$newValue = iconv("windows-1252", "iso-8859-1//TRANSLIT", $fieldValue);
				$newValue = iconv("iso-8859-1", 'UTF-8//TRANSLIT', $newValue);
				$query .= " `" . $fieldName . "` = '" . mysql_real_escape_string($newValue) . "'";
			}
			$query .= " WHERE ";
			for($n = 0; $n < count($keys[$tableName]); $n++){
				if($n > 0) $query .= " AND ";
				$query .= "`" . $keys[$tableName][$n] . "` = '" . mysql_real_escape_string($update["__KEYFIELD_" . ($n + 1) . "__"]) . "'";
			}
			if(_DO_UPDATE){
				$success = mysql_query($query);
				if($success){
					echo '.';
				}else{
					echo "\nFailed to execute query: $query\n";
					$failCount++;
				}
			}else{
				echo ".";
			}

		}
		echo "\n";
		if($failCount > 0){
			echo "Updating records in table $tableName failed on $failcount records.\n";
		}
		$totalFailCount += $failCount;
		unset($updates);

		// if we've created a temporary key for this table we'll remove it now
		if($tempKey == true){
			echo "Removing the temporary key that we used for this table\n";
			$query = "ALTER TABLE `$tableName` DROP `__TEMP__id__`";
			mysql_query($query);
		}

		// we also need to change the character encoding for the individual fields
		echo "Changing character encoding for individual fields in table \"$tableName\"";
		foreach($fieldTypes[$tableName] as $fieldName => $fieldType){
			$query = "ALTER TABLE `$tableName` CHANGE `$fieldName` `$fieldName` ";
			$query .= $fieldType;
			$query .= " CHARACTER SET utf8 COLLATE utf8_general_ci";
			if(_DO_UPDATE){
				$success = mysql_query($query);
				if($success){
					echo ".";
				}else{
					echo "\nFailed using query: $query\n";
					$totalFailCount ++;
				}
			}else{
				echo ".";
			}
		}

	}

	// with all of the affected tables updated, let's go ahead and update the unaffected ones
	foreach($allTables as $tableName){
		if(!array_key_exists($tableName, $fields)){
			echo "Changing default character set on table \"$tableName\": ";
			if(_DO_UPDATE){
				$query = "ALTER TABLE `$tableName` DEFAULT CHARACTER SET 'utf8'";
				$success = mysql_query($query);
				if($success){
					echo " success\n";
				}else{
					echo " Failed using query: $query\n";
					$totalFailCount++;
				}
			}else{
				echo " success\n";
			}
		}
	}


	// finally, we'll update the character encoding on the database itself
	global $DBNAME;
	$query = "ALTER DATABASE `$DBNAME` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
	echo "$query\n";
	$success = mysql_query($query);
	if($success){
		echo "Successfully switched database character set to utf8\n";
	}else{
		echo "Unable to switch database character set to utf8\n";
		$totalFailCount++;
	}

	echo "\nFinished updating values with $totalFailCount failed queries.\n";
}

function db_update_173_pre(){
}
