1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
4 |
* Copyright (C) 2010 Andrew Hutchings
|
|
5 |
*
|
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; version 2 of the License.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18 |
*/
|
|
19 |
||
20 |
#include "drizzledump_data.h" |
|
21 |
#include "drizzledump_mysql.h" |
|
22 |
#include "client_priv.h" |
|
23 |
#include <string> |
|
24 |
#include <iostream> |
|
25 |
#include <boost/regex.hpp> |
|
26 |
#include <boost/date_time/posix_time/posix_time.hpp> |
|
27 |
#include <drizzled/gettext.h> |
|
28 |
||
1799.7.4
by Andrew Hutchings
Fix up some more options and the docs |
29 |
extern bool verbose; |
30 |
extern bool ignore_errors; |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
31 |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
32 |
bool DrizzleDumpDatabaseMySQL::populateTables() |
33 |
{
|
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
34 |
drizzle_result_st *result; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
35 |
drizzle_row_t row; |
36 |
std::string query; |
|
37 |
||
1751.4.25
by Andrew Hutchings
Fix error handling |
38 |
if (not dcon->setDB(databaseName)) |
39 |
return false; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
40 |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
41 |
if (verbose) |
42 |
std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl; |
|
43 |
||
1810.1.1
by Andrew Hutchings
Add table comments |
44 |
query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, AUTO_INCREMENT, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE != 'VIEW' AND TABLE_SCHEMA='"; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
45 |
query.append(databaseName); |
46 |
query.append("' ORDER BY TABLE_NAME"); |
|
47 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
48 |
result= dcon->query(query); |
49 |
||
1751.4.25
by Andrew Hutchings
Fix error handling |
50 |
if (result == NULL) |
51 |
return false; |
|
52 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
53 |
while ((row= drizzle_row_next(result))) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
54 |
{
|
1810.1.1
by Andrew Hutchings
Add table comments |
55 |
size_t* row_sizes= drizzle_row_field_sizes(result); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
56 |
std::string tableName(row[0]); |
1751.4.25
by Andrew Hutchings
Fix error handling |
57 |
std::string displayName(tableName); |
58 |
cleanTableName(displayName); |
|
59 |
if (not ignoreTable(displayName)) |
|
1751.4.24
by Andrew Hutchings
Fix ignore tables |
60 |
continue; |
61 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
62 |
DrizzleDumpTableMySQL *table = new DrizzleDumpTableMySQL(tableName, dcon); |
1751.4.25
by Andrew Hutchings
Fix error handling |
63 |
table->displayName= displayName; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
64 |
table->setCollate(row[1]); |
65 |
table->setEngine(row[2]); |
|
66 |
if (row[3]) |
|
67 |
table->autoIncrement= boost::lexical_cast<uint64_t>(row[3]); |
|
68 |
else
|
|
69 |
table->autoIncrement= 0; |
|
70 |
||
1859.4.1
by Andrew Hutchings
Make foreign keys work for MySQL 5.0 |
71 |
if ((row[4]) and (strstr(row[4], "InnoDB free") == NULL)) |
1810.1.1
by Andrew Hutchings
Add table comments |
72 |
table->comment= DrizzleDumpData::escape(row[4], row_sizes[4]); |
73 |
else
|
|
74 |
table->comment= ""; |
|
75 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
76 |
table->database= this; |
1810.6.6
by Andrew Hutchings
Add foriegn key support for MySQL |
77 |
if ((not table->populateFields()) or (not table->populateIndexes()) or |
78 |
(not table->populateFkeys())) |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
79 |
{
|
80 |
delete table; |
|
1799.7.4
by Andrew Hutchings
Fix up some more options and the docs |
81 |
if (not ignore_errors) |
82 |
return false; |
|
83 |
else
|
|
84 |
continue; |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
85 |
}
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
86 |
tables.push_back(table); |
87 |
}
|
|
88 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
89 |
dcon->freeResult(result); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
90 |
|
91 |
return true; |
|
92 |
}
|
|
93 |
||
1751.4.23
by Andrew Hutchings
Fix various bugs |
94 |
bool DrizzleDumpDatabaseMySQL::populateTables(const std::vector<std::string> &table_names) |
95 |
{
|
|
96 |
drizzle_result_st *result; |
|
97 |
drizzle_row_t row; |
|
98 |
std::string query; |
|
99 |
||
1751.4.25
by Andrew Hutchings
Fix error handling |
100 |
if (not dcon->setDB(databaseName)) |
101 |
return false; |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
102 |
|
103 |
if (verbose) |
|
104 |
std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl; |
|
105 |
for (std::vector<std::string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it) |
|
106 |
{
|
|
107 |
std::string tableName= *it; |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
108 |
std::string displayName(tableName); |
109 |
cleanTableName(displayName); |
|
110 |
if (not ignoreTable(displayName)) |
|
1751.4.24
by Andrew Hutchings
Fix ignore tables |
111 |
continue; |
112 |
||
1751.4.23
by Andrew Hutchings
Fix various bugs |
113 |
query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='"; |
114 |
query.append(databaseName); |
|
115 |
query.append("' AND TABLE_NAME = '"); |
|
116 |
query.append(tableName); |
|
117 |
query.append("'"); |
|
118 |
||
119 |
result= dcon->query(query); |
|
120 |
||
1751.4.25
by Andrew Hutchings
Fix error handling |
121 |
if (result == NULL) |
122 |
return false; |
|
123 |
||
1751.4.23
by Andrew Hutchings
Fix various bugs |
124 |
if ((row= drizzle_row_next(result))) |
125 |
{
|
|
126 |
DrizzleDumpTableMySQL *table = new DrizzleDumpTableMySQL(tableName, dcon); |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
127 |
table->displayName= displayName; |
1751.4.23
by Andrew Hutchings
Fix various bugs |
128 |
table->setCollate(row[1]); |
129 |
table->setEngine(row[2]); |
|
130 |
if (row[3]) |
|
131 |
table->autoIncrement= boost::lexical_cast<uint64_t>(row[3]); |
|
132 |
else
|
|
133 |
table->autoIncrement= 0; |
|
134 |
||
135 |
table->database= this; |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
136 |
if ((not table->populateFields()) or (not table->populateIndexes())) |
137 |
{
|
|
138 |
delete table; |
|
1799.7.5
by Andrew Hutchings
Fix test cases |
139 |
if (not ignore_errors) |
140 |
return false; |
|
141 |
else
|
|
142 |
continue; |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
143 |
}
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
144 |
tables.push_back(table); |
145 |
dcon->freeResult(result); |
|
146 |
}
|
|
147 |
else
|
|
148 |
{
|
|
149 |
dcon->freeResult(result); |
|
1799.7.5
by Andrew Hutchings
Fix test cases |
150 |
if (not ignore_errors) |
151 |
return false; |
|
152 |
else
|
|
153 |
continue; |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
154 |
}
|
155 |
}
|
|
156 |
||
157 |
return true; |
|
158 |
||
159 |
}
|
|
160 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
161 |
bool DrizzleDumpTableMySQL::populateFields() |
162 |
{
|
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
163 |
drizzle_result_st *result; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
164 |
drizzle_row_t row; |
165 |
std::string query; |
|
166 |
||
1751.4.23
by Andrew Hutchings
Fix various bugs |
167 |
if (verbose) |
168 |
std::cerr << _("-- Retrieving fields for ") << tableName << "..." << std::endl; |
|
169 |
||
1976.4.3
by Andrew Hutchings
Add field level comments back in to drizzledump |
170 |
query="SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_DEFAULT, IS_NULLABLE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME, EXTRA, COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='"; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
171 |
query.append(database->databaseName); |
172 |
query.append("' AND TABLE_NAME='"); |
|
173 |
query.append(tableName); |
|
174 |
query.append("' ORDER BY ORDINAL_POSITION"); |
|
175 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
176 |
result= dcon->query(query); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
177 |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
178 |
if (result == NULL) |
179 |
return false; |
|
180 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
181 |
while ((row= drizzle_row_next(result))) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
182 |
{
|
183 |
std::string fieldName(row[0]); |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
184 |
DrizzleDumpFieldMySQL *field = new DrizzleDumpFieldMySQL(fieldName, dcon); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
185 |
/* Stop valgrind warning */
|
186 |
field->convertDateTime= false; |
|
1897.3.1
by Andrew Hutchings
drizzledump MySQL migration fixes: |
187 |
field->isNull= (strcmp(row[3], "YES") == 0) ? true : false; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
188 |
/* Also sets collation */
|
189 |
field->setType(row[1], row[8]); |
|
1882.2.1
by Andrew Hutchings
MySQL can contain '' as an ENUM value which is not valid in Drizzle. Convert this to NULL. |
190 |
if (field->type.compare("ENUM") == 0) |
191 |
field->isNull= true; |
|
1897.3.1
by Andrew Hutchings
drizzledump MySQL migration fixes: |
192 |
|
1971.5.5
by Andrew Hutchings
Drop the default when converting SET data type. Ugly but I can't think of a better way until we support SET properly |
193 |
if ((row[2]) and (field->type.compare("TEXT") != 0)) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
194 |
{
|
1836.1.1
by Andrew Hutchings
The MySQL date/time schema convert was not run when there was no default value |
195 |
field->defaultValue= row[2]; |
1897.3.1
by Andrew Hutchings
drizzledump MySQL migration fixes: |
196 |
if (field->convertDateTime) |
197 |
{
|
|
198 |
field->dateTimeConvert(); |
|
199 |
}
|
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
200 |
}
|
201 |
else
|
|
1971.5.5
by Andrew Hutchings
Drop the default when converting SET data type. Ugly but I can't think of a better way until we support SET properly |
202 |
{
|
203 |
field->defaultValue= ""; |
|
204 |
}
|
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
205 |
|
206 |
field->isAutoIncrement= (strcmp(row[8], "auto_increment") == 0) ? true : false; |
|
207 |
field->defaultIsNull= field->isNull; |
|
1976.4.6
by Andrew Hutchings
Merge trunk into branch |
208 |
|
1971.5.2
by Andrew Hutchings
Add BIT support when converting MySQL. We convert this to a varbinary and covert the bit length to a byte length. |
209 |
/* Seriously MySQL, why is BIT length in NUMERIC_PRECISION? */
|
210 |
if ((strncmp(row[1], "bit", 3) == 0) and (row[5] != NULL)) |
|
211 |
field->length= ((boost::lexical_cast<uint32_t>(row[5]) - 1) / 8) + 1; |
|
212 |
else
|
|
213 |
field->length= (row[4]) ? boost::lexical_cast<uint32_t>(row[4]) : 0; |
|
1971.5.4
by Andrew Hutchings
MySQL support CHAR(0), erm.. OK. Lets at least make this 1 char long. |
214 |
|
215 |
/* Also, CHAR(0) is valid?? */
|
|
216 |
if (((field->type.compare("VARBINARY") == 0) |
|
217 |
or (field->type.compare("VARCHAR") == 0)) |
|
218 |
and (field->length == 0)) |
|
219 |
{
|
|
220 |
field->length= 1; |
|
221 |
}
|
|
222 |
||
1976.4.6
by Andrew Hutchings
Merge trunk into branch |
223 |
field->decimalPrecision= (row[5]) ? boost::lexical_cast<uint32_t>(row[5]) : 0; |
224 |
field->decimalScale= (row[6]) ? boost::lexical_cast<uint32_t>(row[6]) : 0; |
|
1976.4.3
by Andrew Hutchings
Add field level comments back in to drizzledump |
225 |
field->comment= (row[9]) ? row[9] : ""; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
226 |
fields.push_back(field); |
227 |
}
|
|
228 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
229 |
dcon->freeResult(result); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
230 |
return true; |
231 |
}
|
|
232 |
||
233 |
||
1836.1.1
by Andrew Hutchings
The MySQL date/time schema convert was not run when there was no default value |
234 |
void DrizzleDumpFieldMySQL::dateTimeConvert(void) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
235 |
{
|
236 |
boost::match_flag_type flags = boost::match_default; |
|
237 |
||
1836.1.1
by Andrew Hutchings
The MySQL date/time schema convert was not run when there was no default value |
238 |
if (strcmp(defaultValue.c_str(), "CURRENT_TIMESTAMP") == 0) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
239 |
return; |
240 |
||
241 |
if (type.compare("INT") == 0) |
|
242 |
{
|
|
243 |
/* We were a TIME, now we are an INT */
|
|
1836.1.1
by Andrew Hutchings
The MySQL date/time schema convert was not run when there was no default value |
244 |
std::string ts(defaultValue); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
245 |
boost::posix_time::time_duration td(boost::posix_time::duration_from_string(ts)); |
246 |
defaultValue= boost::lexical_cast<std::string>(td.total_seconds()); |
|
247 |
return; |
|
248 |
}
|
|
249 |
||
1802.11.1
by Andrew Hutchings
1. date regex was broken |
250 |
boost::regex date_regex("(0000|-00)"); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
251 |
|
1836.1.1
by Andrew Hutchings
The MySQL date/time schema convert was not run when there was no default value |
252 |
if (regex_search(defaultValue, date_regex, flags)) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
253 |
{
|
254 |
defaultIsNull= true; |
|
255 |
defaultValue=""; |
|
256 |
}
|
|
257 |
}
|
|
258 |
||
259 |
||
260 |
bool DrizzleDumpTableMySQL::populateIndexes() |
|
261 |
{
|
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
262 |
drizzle_result_st *result; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
263 |
drizzle_row_t row; |
264 |
std::string query; |
|
265 |
std::string lastKey; |
|
266 |
bool firstIndex= true; |
|
267 |
DrizzleDumpIndex *index; |
|
268 |
||
1751.4.23
by Andrew Hutchings
Fix various bugs |
269 |
if (verbose) |
270 |
std::cerr << _("-- Retrieving indexes for ") << tableName << "..." << std::endl; |
|
271 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
272 |
query="SHOW INDEXES FROM "; |
273 |
query.append(tableName); |
|
274 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
275 |
result= dcon->query(query); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
276 |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
277 |
if (result == NULL) |
278 |
return false; |
|
279 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
280 |
while ((row= drizzle_row_next(result))) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
281 |
{
|
282 |
std::string indexName(row[2]); |
|
283 |
if (indexName.compare(lastKey) != 0) |
|
284 |
{
|
|
285 |
if (strcmp(row[10], "FULLTEXT") == 0) |
|
286 |
continue; |
|
287 |
||
288 |
if (!firstIndex) |
|
289 |
indexes.push_back(index); |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
290 |
index = new DrizzleDumpIndexMySQL(indexName, dcon); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
291 |
index->isPrimary= (strcmp(row[2], "PRIMARY") == 0); |
292 |
index->isUnique= (strcmp(row[1], "0") == 0); |
|
293 |
index->isHash= (strcmp(row[10], "HASH") == 0); |
|
294 |
lastKey= row[2]; |
|
295 |
firstIndex= false; |
|
296 |
}
|
|
2228.3.1
by Andrew Hutchings
Fix multi-part index length processing in drizzledump |
297 |
uint32_t length= (row[7]) ? boost::lexical_cast<uint32_t>(row[7]) : 0; |
298 |
index->columns.push_back(std::make_pair(row[4], length)); |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
299 |
}
|
300 |
if (!firstIndex) |
|
301 |
indexes.push_back(index); |
|
302 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
303 |
dcon->freeResult(result); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
304 |
return true; |
305 |
}
|
|
306 |
||
1810.6.6
by Andrew Hutchings
Add foriegn key support for MySQL |
307 |
bool DrizzleDumpTableMySQL::populateFkeys() |
308 |
{
|
|
309 |
drizzle_result_st *result; |
|
310 |
drizzle_row_t row; |
|
311 |
std::string query; |
|
312 |
DrizzleDumpForeignKey *fkey; |
|
313 |
||
314 |
if (verbose) |
|
315 |
std::cerr << _("-- Retrieving foreign keys for ") << tableName << "..." << std::endl; |
|
316 |
||
1966.5.1
by Andrew Hutchings
In some cases the migration of MySQL foreign keys failed. It also performed badly. Switch to using SHOW CREATE TABLE instead |
317 |
query= "SHOW CREATE TABLE `"; |
318 |
query.append(database->databaseName); |
|
319 |
query.append("`.`"); |
|
320 |
query.append(tableName); |
|
321 |
query.append("`"); |
|
1810.6.6
by Andrew Hutchings
Add foriegn key support for MySQL |
322 |
result= dcon->query(query); |
323 |
||
324 |
if (result == NULL) |
|
325 |
return false; |
|
326 |
||
1966.5.1
by Andrew Hutchings
In some cases the migration of MySQL foreign keys failed. It also performed badly. Switch to using SHOW CREATE TABLE instead |
327 |
if ((row= drizzle_row_next(result))) |
1859.4.1
by Andrew Hutchings
Make foreign keys work for MySQL 5.0 |
328 |
{
|
1966.5.1
by Andrew Hutchings
In some cases the migration of MySQL foreign keys failed. It also performed badly. Switch to using SHOW CREATE TABLE instead |
329 |
boost::match_flag_type flags = boost::match_default; |
1971.5.1
by Andrew Hutchings
Drizzledump MySQL migration fkey regex was too greedy causing output errors |
330 |
boost::regex constraint_regex("CONSTRAINT `(.*?)` FOREIGN KEY \\((.*?)\\) REFERENCES `(.*?)` \\((.*?)\\)( ON (UPDATE|DELETE) (CASCADE|RESTRICT|SET NULL))?( ON (UPDATE|DELETE) (CASCADE|RESTRICT|SET NULL))?"); |
1966.5.1
by Andrew Hutchings
In some cases the migration of MySQL foreign keys failed. It also performed badly. Switch to using SHOW CREATE TABLE instead |
331 |
|
332 |
boost::match_results<std::string::const_iterator> constraint_results; |
|
333 |
||
334 |
std::string search_body(row[1]); |
|
335 |
std::string::const_iterator start, end; |
|
336 |
start= search_body.begin(); |
|
337 |
end= search_body.end(); |
|
338 |
while (regex_search(start, end, constraint_results, constraint_regex, flags)) |
|
1859.4.1
by Andrew Hutchings
Make foreign keys work for MySQL 5.0 |
339 |
{
|
1966.5.1
by Andrew Hutchings
In some cases the migration of MySQL foreign keys failed. It also performed badly. Switch to using SHOW CREATE TABLE instead |
340 |
fkey= new DrizzleDumpForeignKey(constraint_results[1], dcon); |
341 |
fkey->parentColumns= constraint_results[2]; |
|
342 |
fkey->childTable= constraint_results[3]; |
|
343 |
fkey->childColumns= constraint_results[4]; |
|
344 |
||
345 |
if (constraint_results[5].compare("") != 0) |
|
346 |
{
|
|
347 |
if (constraint_results[6].compare("UPDATE") == 0) |
|
348 |
fkey->updateRule= constraint_results[7]; |
|
349 |
else if (constraint_results[6].compare("DELETE") == 0) |
|
350 |
fkey->deleteRule= constraint_results[7]; |
|
351 |
}
|
|
352 |
if (constraint_results[8].compare("") != 0) |
|
353 |
{
|
|
354 |
if (constraint_results[9].compare("UPDATE") == 0) |
|
355 |
fkey->updateRule= constraint_results[10]; |
|
356 |
else if (constraint_results[9].compare("DELETE") == 0) |
|
357 |
fkey->deleteRule= constraint_results[10]; |
|
358 |
}
|
|
359 |
fkey->matchOption= ""; |
|
1859.4.1
by Andrew Hutchings
Make foreign keys work for MySQL 5.0 |
360 |
|
361 |
fkeys.push_back(fkey); |
|
1966.5.1
by Andrew Hutchings
In some cases the migration of MySQL foreign keys failed. It also performed badly. Switch to using SHOW CREATE TABLE instead |
362 |
|
363 |
start= constraint_results[0].second; |
|
364 |
flags |= boost::match_prev_avail; |
|
365 |
flags |= boost::match_not_bob; |
|
1859.4.1
by Andrew Hutchings
Make foreign keys work for MySQL 5.0 |
366 |
}
|
1810.6.6
by Andrew Hutchings
Add foriegn key support for MySQL |
367 |
}
|
368 |
dcon->freeResult(result); |
|
369 |
return true; |
|
370 |
}
|
|
371 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
372 |
void DrizzleDumpFieldMySQL::setType(const char* raw_type, const char* raw_collation) |
373 |
{
|
|
374 |
std::string old_type(raw_type); |
|
375 |
std::string extra; |
|
376 |
size_t pos; |
|
377 |
||
1976.4.1
by Andrew Hutchings
MySQL migration assumed unsigned data type in the form "float(2,0) unsigned". If the braces are missing (ie. "float unsigned") a bad conversion happened. |
378 |
if (((pos= old_type.find("(")) != std::string::npos) or |
379 |
((pos= old_type.find(" ")) != std::string::npos)) |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
380 |
{
|
381 |
extra= old_type.substr(pos); |
|
382 |
old_type.erase(pos, std::string::npos); |
|
383 |
}
|
|
384 |
||
385 |
std::transform(old_type.begin(), old_type.end(), old_type.begin(), ::toupper); |
|
386 |
if ((old_type.find("CHAR") != std::string::npos) or |
|
387 |
(old_type.find("TEXT") != std::string::npos)) |
|
388 |
setCollate(raw_collation); |
|
389 |
||
1971.5.6
by Andrew Hutchings
Make BIGINT range check only happen on MySQL BIGINT UNSIGNED as it is tripping up on negative BIGINT values. |
390 |
if ((old_type.compare("BIGINT") == 0) and |
391 |
((extra.find("unsigned") != std::string::npos))) |
|
392 |
{
|
|
393 |
rangeCheck= true; |
|
394 |
}
|
|
395 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
396 |
if ((old_type.compare("INT") == 0) and |
397 |
((extra.find("unsigned") != std::string::npos))) |
|
398 |
{
|
|
399 |
type= "BIGINT"; |
|
400 |
return; |
|
401 |
}
|
|
402 |
||
403 |
if ((old_type.compare("TINYINT") == 0) or |
|
404 |
(old_type.compare("SMALLINT") == 0) or |
|
405 |
(old_type.compare("MEDIUMINT") == 0)) |
|
406 |
{
|
|
407 |
type= "INT"; |
|
408 |
return; |
|
409 |
}
|
|
410 |
||
411 |
if ((old_type.compare("TINYBLOB") == 0) or |
|
412 |
(old_type.compare("MEDIUMBLOB") == 0) or |
|
413 |
(old_type.compare("LONGBLOB") == 0)) |
|
414 |
{
|
|
415 |
type= "BLOB"; |
|
416 |
return; |
|
417 |
}
|
|
418 |
||
419 |
if ((old_type.compare("TINYTEXT") == 0) or |
|
420 |
(old_type.compare("MEDIUMTEXT") == 0) or |
|
1751.4.21
by Andrew Hutchings
Add database destination settings and connect it all up |
421 |
(old_type.compare("LONGTEXT") == 0) or |
422 |
(old_type.compare("SET") == 0)) |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
423 |
{
|
424 |
type= "TEXT"; |
|
425 |
return; |
|
426 |
}
|
|
427 |
||
428 |
if (old_type.compare("CHAR") == 0) |
|
429 |
{
|
|
430 |
type= "VARCHAR"; |
|
431 |
return; |
|
432 |
}
|
|
433 |
||
434 |
if (old_type.compare("BINARY") == 0) |
|
435 |
{
|
|
436 |
type= "VARBINARY"; |
|
1971.5.4
by Andrew Hutchings
MySQL support CHAR(0), erm.. OK. Lets at least make this 1 char long. |
437 |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
438 |
return; |
439 |
}
|
|
440 |
||
441 |
if (old_type.compare("ENUM") == 0) |
|
442 |
{
|
|
443 |
type= old_type; |
|
444 |
/* Strip out the braces, we add them again during output */
|
|
445 |
enumValues= extra.substr(1, extra.length()-2); |
|
446 |
return; |
|
447 |
}
|
|
448 |
||
449 |
if ((old_type.find("TIME") != std::string::npos) or |
|
450 |
(old_type.find("DATE") != std::string::npos)) |
|
451 |
{
|
|
452 |
/* Intended to catch TIME/DATE/TIMESTAMP/DATETIME
|
|
453 |
We may have a default TIME/DATE which needs converting */
|
|
454 |
convertDateTime= true; |
|
1897.3.1
by Andrew Hutchings
drizzledump MySQL migration fixes: |
455 |
isNull= true; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
456 |
}
|
457 |
||
1802.3.1
by Andrew Hutchings
Add YEAR conversion that was previously missing from the MySQL migration code |
458 |
if ((old_type.compare("TIME") == 0) or (old_type.compare("YEAR") == 0)) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
459 |
{
|
460 |
type= "INT"; |
|
461 |
return; |
|
462 |
}
|
|
463 |
||
464 |
if (old_type.compare("FLOAT") == 0) |
|
465 |
{
|
|
466 |
type= "DOUBLE"; |
|
467 |
return; |
|
468 |
}
|
|
469 |
||
1971.5.2
by Andrew Hutchings
Add BIT support when converting MySQL. We convert this to a varbinary and covert the bit length to a byte length. |
470 |
if (old_type.compare("BIT") == 0) |
471 |
{
|
|
472 |
type= "VARBINARY"; |
|
473 |
return; |
|
474 |
}
|
|
475 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
476 |
type= old_type; |
477 |
return; |
|
478 |
}
|
|
479 |
||
480 |
void DrizzleDumpTableMySQL::setEngine(const char* newEngine) |
|
481 |
{
|
|
1966.4.1
by Andrew Hutchings
During MySQL migration convert MEMORY engine to InnoDB since MEMORY as a non-temporary table is not yet supported |
482 |
if ((strcmp(newEngine, "MyISAM") == 0) || (strcmp(newEngine, "MEMORY") == 0)) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
483 |
engineName= "InnoDB"; |
484 |
else
|
|
485 |
engineName= newEngine; |
|
486 |
}
|
|
487 |
||
488 |
DrizzleDumpData* DrizzleDumpTableMySQL::getData(void) |
|
489 |
{
|
|
1751.4.25
by Andrew Hutchings
Fix error handling |
490 |
try
|
491 |
{
|
|
492 |
return new DrizzleDumpDataMySQL(this, dcon); |
|
493 |
}
|
|
494 |
catch(...) |
|
495 |
{
|
|
496 |
return NULL; |
|
497 |
}
|
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
498 |
}
|
499 |
||
500 |
void DrizzleDumpDatabaseMySQL::setCollate(const char* newCollate) |
|
501 |
{
|
|
502 |
if (newCollate) |
|
503 |
{
|
|
504 |
std::string tmpCollate(newCollate); |
|
505 |
if (tmpCollate.find("utf8") != std::string::npos) |
|
506 |
{
|
|
507 |
collate= tmpCollate; |
|
508 |
return; |
|
509 |
}
|
|
510 |
}
|
|
511 |
collate= "utf8_general_ci"; |
|
512 |
}
|
|
513 |
||
514 |
void DrizzleDumpTableMySQL::setCollate(const char* newCollate) |
|
515 |
{
|
|
516 |
if (newCollate) |
|
517 |
{
|
|
518 |
std::string tmpCollate(newCollate); |
|
519 |
if (tmpCollate.find("utf8") != std::string::npos) |
|
520 |
{
|
|
521 |
collate= tmpCollate; |
|
522 |
return; |
|
523 |
}
|
|
524 |
}
|
|
525 |
||
526 |
collate= "utf8_general_ci"; |
|
527 |
}
|
|
528 |
||
529 |
void DrizzleDumpFieldMySQL::setCollate(const char* newCollate) |
|
530 |
{
|
|
531 |
if (newCollate) |
|
532 |
{
|
|
533 |
std::string tmpCollate(newCollate); |
|
534 |
if (tmpCollate.find("utf8") != std::string::npos) |
|
535 |
{
|
|
536 |
collation= tmpCollate; |
|
537 |
return; |
|
538 |
}
|
|
539 |
}
|
|
540 |
collation= "utf8_general_ci"; |
|
541 |
}
|
|
542 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
543 |
DrizzleDumpDataMySQL::DrizzleDumpDataMySQL(DrizzleDumpTable *dataTable, |
544 |
DrizzleDumpConnection *connection) |
|
545 |
: DrizzleDumpData(dataTable, connection) |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
546 |
{
|
547 |
std::string query; |
|
548 |
query= "SELECT * FROM `"; |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
549 |
query.append(table->displayName); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
550 |
query.append("`"); |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
551 |
|
552 |
result= dcon->query(query); |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
553 |
if (result == NULL) |
1966.3.1
by Monty Taylor
Use std::exception instead of catch(...) |
554 |
throw std::exception(); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
555 |
}
|
556 |
||
557 |
DrizzleDumpDataMySQL::~DrizzleDumpDataMySQL() |
|
558 |
{
|
|
559 |
drizzle_result_free(result); |
|
1883.3.1
by Andrew Hutchings
Cleanup drizzledump and drizzle for cppcheck |
560 |
delete result; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
561 |
}
|
562 |
||
563 |
long DrizzleDumpDataMySQL::convertTime(const char* oldTime) const |
|
564 |
{
|
|
565 |
std::string ts(oldTime); |
|
566 |
boost::posix_time::time_duration td(boost::posix_time::duration_from_string(ts)); |
|
567 |
long seconds= td.total_seconds(); |
|
568 |
return seconds; |
|
569 |
}
|
|
570 |
||
571 |
std::string DrizzleDumpDataMySQL::convertDate(const char* oldDate) const |
|
572 |
{
|
|
573 |
boost::match_flag_type flags = boost::match_default; |
|
574 |
std::string output; |
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
575 |
boost::regex date_regex("(0000|-00)"); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
576 |
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
577 |
if (not regex_search(oldDate, date_regex, flags)) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
578 |
{
|
579 |
output.push_back('\''); |
|
580 |
output.append(oldDate); |
|
581 |
output.push_back('\''); |
|
582 |
}
|
|
583 |
else
|
|
584 |
output= "NULL"; |
|
585 |
||
586 |
return output; |
|
587 |
}
|
|
588 |
||
1802.11.1
by Andrew Hutchings
1. date regex was broken |
589 |
std::string DrizzleDumpDataMySQL::checkDateTime(const char* item, uint32_t field) const |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
590 |
{
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
591 |
std::string ret; |
592 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
593 |
if (table->fields[field]->convertDateTime) |
594 |
{
|
|
595 |
if (table->fields[field]->type.compare("INT") == 0) |
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
596 |
ret= boost::lexical_cast<std::string>(convertTime(item)); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
597 |
else
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
598 |
ret= convertDate(item); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
599 |
}
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
600 |
return ret; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
601 |
}
|
602 |