|
3 | 3 | class CreateTableSQLRewriter extends AbstractSQLRewriter
|
4 | 4 | {
|
5 | 5 | private $stringReplacements = [
|
6 |
| - 'bigint(20)' => 'bigint', |
7 |
| - 'bigint(10)' => 'int', |
8 |
| - 'int(11)' => 'int', |
9 |
| - 'tinytext' => 'text', |
10 |
| - 'mediumtext' => 'text', |
11 |
| - 'longtext' => 'text', |
12 |
| - 'unsigned' => '', |
| 6 | + ' bigint(40)' => ' bigint', |
| 7 | + ' bigint(20)' => ' bigint', |
| 8 | + ' bigint(10)' => ' int', |
| 9 | + ' int(11)' => ' int', |
| 10 | + ' int(10)' => ' int', |
| 11 | + ' int(1)' => ' smallint', |
| 12 | + ' tinytext' => ' text', |
| 13 | + ' mediumtext' => ' text', |
| 14 | + ' longtext' => ' text', |
| 15 | + ' unsigned' => ' ', |
13 | 16 | 'gmt datetime NOT NULL default \'0000-00-00 00:00:00\'' => 'gmt timestamp NOT NULL DEFAULT timezone(\'gmt\'::text, now())',
|
14 | 17 | 'default \'0000-00-00 00:00:00\'' => 'DEFAULT now()',
|
15 | 18 | '\'0000-00-00 00:00:00\'' => 'now()',
|
16 | 19 | 'datetime' => 'timestamp',
|
17 |
| - 'DEFAULT CHARACTER SET utf8mb4' => '', |
18 |
| - 'DEFAULT CHARACTER SET utf8' => '', |
| 20 | + ' DEFAULT CHARACTER SET utf8mb4' => '', |
| 21 | + ' DEFAULT CHARACTER SET utf8' => '', |
19 | 22 |
|
20 | 23 | // WP 2.7.1 compatibility
|
21 |
| - 'int(4)' => 'smallint', |
| 24 | + ' int(4)' => ' smallint', |
22 | 25 |
|
23 | 26 | // For WPMU (starting with WP 3.2)
|
24 |
| - 'tinyint(2)' => 'smallint', |
25 |
| - 'tinyint(1)' => 'smallint', |
26 |
| - "enum('0','1')" => 'smallint', |
27 |
| - 'COLLATE utf8mb4_unicode_520_ci' => '', |
28 |
| - 'COLLATE utf8_general_ci' => '', |
| 27 | + ' tinyint(2)' => ' smallint', |
| 28 | + ' tinyint(1)' => ' smallint', |
| 29 | + " enum('0','1')" => ' smallint', |
| 30 | + ' COLLATE utf8mb4_unicode_520_ci' => '', |
| 31 | + ' COLLATE utf8_general_ci' => '', |
| 32 | + ' CHARACTER SET utf8' => '', |
| 33 | + ' DEFAULT CHARSET=utf8' => '', |
29 | 34 |
|
30 | 35 | // For flash-album-gallery plugin
|
31 |
| - 'tinyint' => 'smallint' |
| 36 | + ' tinyint' => ' smallint' |
32 | 37 | ];
|
33 | 38 |
|
34 | 39 | public function rewrite(): string
|
35 | 40 | {
|
36 | 41 | $sql = $this->original();
|
37 | 42 |
|
38 | 43 |
|
39 |
| - $sql = str_replace('CREATE TABLE IF NOT EXISTS ', 'CREATE TABLE ', $sql); |
| 44 | + $tableSQL = str_replace('CREATE TABLE IF NOT EXISTS ', 'CREATE TABLE ', $sql); |
40 | 45 | $pattern = '/CREATE TABLE [`]?(\w+)[`]?/';
|
41 |
| - preg_match($pattern, $sql, $matches); |
| 46 | + preg_match($pattern, $tableSQL, $matches); |
42 | 47 | $table = $matches[1];
|
43 | 48 |
|
| 49 | + // change all creates into create if not exists |
| 50 | + $pattern = "/CREATE TABLE (IF NOT EXISTS )?(\w+)\s*\(/i"; |
| 51 | + $replacement = 'CREATE TABLE IF NOT EXISTS $2 ('; |
| 52 | + $sql = preg_replace($pattern, $replacement, $sql); |
| 53 | + |
44 | 54 | // Remove trailing spaces
|
45 |
| - $sql = trim($sql) . ';'; |
| 55 | + $sql = trim($sql); |
| 56 | + |
| 57 | + // Add a slash if needed |
| 58 | + if (substr($sql, strlen($sql) - 1, 1) != ";") { |
| 59 | + $sql = $sql . ";"; |
| 60 | + } |
46 | 61 |
|
47 | 62 | // Translate types and some other replacements
|
48 |
| - $sql = str_replace( |
| 63 | + $sql = str_ireplace( |
49 | 64 | array_keys($this->stringReplacements),
|
50 | 65 | array_values($this->stringReplacements),
|
51 | 66 | $sql
|
52 | 67 | );
|
53 | 68 |
|
54 |
| - // Fix auto_increment by adding a sequence |
55 |
| - $pattern = '/int[ ]+NOT NULL auto_increment/'; |
| 69 | + // bigint |
| 70 | + $pattern = '/bigint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i'; |
56 | 71 | preg_match($pattern, $sql, $matches);
|
57 | 72 | if($matches) {
|
58 |
| - $seq = $table . '_seq'; |
59 |
| - $sql = str_replace('NOT NULL auto_increment', "NOT NULL DEFAULT nextval('$seq'::text)", $sql); |
60 |
| - $sql .= "\nCREATE SEQUENCE $seq;"; |
| 73 | + $sql = preg_replace($pattern, 'bigserial', $sql); |
61 | 74 | }
|
62 | 75 |
|
63 |
| - // Support for INDEX creation |
64 |
| - $pattern = '/,\s+(UNIQUE |)KEY\s+([^\s]+)\s+\(((?:[\w]+(?:\([\d]+\))?[,]?)*)\)/'; |
| 76 | + // int |
| 77 | + $pattern = '/int(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i'; |
| 78 | + preg_match($pattern, $sql, $matches); |
| 79 | + if($matches) { |
| 80 | + $sql = preg_replace($pattern, 'serial', $sql); |
| 81 | + } |
| 82 | + |
| 83 | + // smallint |
| 84 | + $pattern = '/smallint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i'; |
| 85 | + preg_match($pattern, $sql, $matches); |
| 86 | + if($matches) { |
| 87 | + $sql = preg_replace($pattern, 'smallserial', $sql); |
| 88 | + } |
| 89 | + |
| 90 | + // Handle for numeric and decimal -- being replaced with serial |
| 91 | + $numeric_patterns = ['/numeric(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i', '/decimal(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i']; |
| 92 | + foreach($numeric_patterns as $pattern) { |
| 93 | + preg_match($pattern, $sql, $matches); |
| 94 | + if($matches) { |
| 95 | + $sql = preg_replace($pattern, 'serial', $sql); |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + // Support for UNIQUE INDEX creation |
| 100 | + $pattern = '/,\s*(UNIQUE |)KEY\s+(`[^`]+`|\w+)\s+\(((?:[^()]|\([^)]*\))*)\)/'; |
65 | 101 | if(preg_match_all($pattern, $sql, $matches, PREG_SET_ORDER)) {
|
66 | 102 | foreach($matches as $match) {
|
67 | 103 | $unique = $match[1];
|
68 | 104 | $index = $match[2];
|
69 | 105 | $columns = $match[3];
|
70 |
| - $columns = preg_replace('/\(\d+\)/', '', $columns); |
71 |
| - // Workaround for index name duplicate |
72 |
| - $index = $table . '_' . $index; |
73 |
| - $sql .= "\nCREATE {$unique}INDEX $index ON $table ($columns);"; |
| 106 | + |
| 107 | + // Removing backticks from the index names |
| 108 | + $index = str_replace('`', '', $index); |
| 109 | + |
| 110 | + // Removing backticks and key length constraints from the columns |
| 111 | + $columns = preg_replace(["/`/", "/\(\d+\)/"], '', $columns); |
| 112 | + |
| 113 | + // Creating a unique index name |
| 114 | + $indexName = $table . '_' . $index; |
| 115 | + |
| 116 | + // Appending the CREATE INDEX statement to SQL |
| 117 | + $sql .= "\nCREATE {$unique}INDEX IF NOT EXISTS $indexName ON $table ($columns);"; |
74 | 118 | }
|
75 | 119 | }
|
76 | 120 | // Now remove handled indexes
|
77 | 121 | $sql = preg_replace($pattern, '', $sql);
|
78 | 122 |
|
| 123 | + |
| 124 | + $pattern = "/(,\s*)?UNIQUE KEY\s+[a-zA-Z0-9_]+\s+(\([a-zA-Z0-9_,\s]+\))/"; |
| 125 | + $replacement = "$1UNIQUE $2"; |
| 126 | + $sql = preg_replace($pattern, $replacement, $sql); |
| 127 | + |
79 | 128 | return $sql;
|
80 | 129 | }
|
81 | 130 | }
|
0 commit comments