Guest User

Untitled

a guest
Jun 8th, 2018
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.36 KB | None | 0 0
  1. <?php
  2. /**
  3. * Migrates MySQL database table columns that have been stored in a mixed
  4. * environment - e.g. database running on `latin1` but using `SET NAMES utf8`
  5. * during the connection when writing data to the DMBS.
  6. *
  7. * Expected source character set: latin1
  8. * Defined target character set: utf8
  9. * Defined target collation: utf8_general_ci
  10. *
  11. * @author Oliver Hader <oliver.hader@typo3.org>
  12. * @license GPLv2 (or any later version)
  13. * @modified 2018-06-05
  14. */
  15.  
  16. if ($argc < 4) {
  17. echo implode(PHP_EOL, [
  18. '+ Usage',
  19. '++++++++',
  20. sprintf('%s database username password [hostname]' . PHP_EOL, $argv[0])
  21. ]);
  22. exit(1);
  23. }
  24.  
  25. $arguments = $argv;
  26. array_shift($arguments);
  27.  
  28. $database = array_shift($arguments);
  29. $username = array_shift($arguments);
  30. $password = array_shift($arguments);
  31. $hostname = array_shift($arguments);
  32.  
  33. if (empty($hostname)) {
  34. $hostname = '127.0.0.1';
  35. }
  36.  
  37. $dsn = sprintf('mysql:dbname=%s;host=%s', $database, $hostname);
  38. $pdo = new \PDO($dsn, $username, $password);
  39.  
  40.  
  41. $statement = $pdo->query(
  42. 'SELECT TABLES.TABLE_NAME, TABLES.TABLE_COLLATION, CCSA.CHARACTER_SET_NAME '
  43. . 'FROM information_schema.TABLES TABLES, '
  44. . 'information_schema.COLLATION_CHARACTER_SET_APPLICABILITY CCSA '
  45. . 'WHERE CCSA.COLLATION_NAME = TABLES.TABLE_COLLATION AND TABLES.TABLE_SCHEMA=' . $pdo->quote($database)
  46. );
  47.  
  48. $changed = 0;
  49. $tables = $statement->fetchAll(\PDO::FETCH_ASSOC);
  50. foreach ($tables as $table) {
  51. $tableName = $table['TABLE_NAME'];
  52. $statement = $pdo->query(
  53. 'SELECT COLUMN_NAME, COLUMN_DEFAULT, COLUMN_TYPE, IS_NULLABLE, '
  54. . 'DATA_TYPE, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS '
  55. . 'WHERE TABLE_NAME=' . $pdo->quote($tableName) . ' AND TABLE_SCHEMA=' . $pdo->quote($database)
  56. );
  57. $columns = array_filter(
  58. $statement->fetchAll(\PDO::FETCH_ASSOC),
  59. function (array $column) {
  60. return $column['CHARACTER_SET_NAME'] === 'latin1'
  61. || strpos($column['COLLATION_NAME'], 'latin1_') === 0;
  62. }
  63. );
  64.  
  65. foreach ($columns as $column) {
  66. $columnName = $column['COLUMN_NAME'];
  67. echo sprintf('+ %s.%s... ', $tableName, $columnName);
  68.  
  69. $parts = [
  70. 'ALTER TABLE',
  71. $tableName,
  72. 'CHANGE',
  73. $columnName,
  74. $columnName,
  75. 'BLOB',
  76. ];
  77. $pdo->query(implode(' ', $parts));
  78.  
  79. $parts = [
  80. 'ALTER TABLE',
  81. $tableName,
  82. 'CHANGE',
  83. $columnName,
  84. $columnName,
  85. $column['COLUMN_TYPE'],
  86. 'CHARACTER SET utf8',
  87. 'COLLATE utf8_general_ci',
  88. ($column['IS_NULLABLE'] ? '' : 'NOT ') . 'NULL',
  89. ];
  90. if ($column['COLUMN_DEFAULT'] !== null) {
  91. $parts[] = 'DEFAULT ' . $pdo->quote($column['COLUMN_DEFAULT']);
  92. }
  93. $pdo->query(implode(' ', $parts));
  94. $changed++;
  95.  
  96. echo 'done' . PHP_EOL;
  97. }
  98.  
  99. if ($table['CHARACTER_SET_NAME'] === 'latin1'
  100. || strpos($table['TABLE_COLLATION'], 'latin1_') === 0
  101. ) {
  102. echo sprintf('* %s... ', $tableName);
  103. $pdo->query(implode(' ', [
  104. 'ALTER TABLE',
  105. $tableName,
  106. 'CHARACTER SET utf8',
  107. 'COLLATE utf8_general_ci',
  108. ]));
  109. echo 'done' . PHP_EOL;
  110. }
  111. }
  112.  
  113. if ($changed === 0) {
  114. echo 'All fine. Not changes required...' . PHP_EOL;
  115. }
Add Comment
Please, Sign In to add comment