~drizzle-trunk/drizzle/development

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
1810.1.1 by Andrew Hutchings
Add table comments
71
    if (row[4])
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;
1751.4.25 by Andrew Hutchings
Fix error handling
77
    if ((not table->populateFields()) or (not table->populateIndexes()))
78
    {
79
      delete table;
1799.7.4 by Andrew Hutchings
Fix up some more options and the docs
80
      if (not ignore_errors)
81
        return false;
82
      else
83
        continue;
1751.4.25 by Andrew Hutchings
Fix error handling
84
    }
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
85
    tables.push_back(table);
86
  }
87
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
88
  dcon->freeResult(result);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
89
90
  return true;
91
}
92
1751.4.23 by Andrew Hutchings
Fix various bugs
93
bool DrizzleDumpDatabaseMySQL::populateTables(const std::vector<std::string> &table_names)
94
{
95
  drizzle_result_st *result;
96
  drizzle_row_t row;
97
  std::string query;
98
1751.4.25 by Andrew Hutchings
Fix error handling
99
  if (not dcon->setDB(databaseName))
100
    return false;
1751.4.23 by Andrew Hutchings
Fix various bugs
101
102
  if (verbose)
103
    std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl;
104
  for (std::vector<std::string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it)
105
  {
106
    std::string tableName= *it;
1751.4.25 by Andrew Hutchings
Fix error handling
107
    std::string displayName(tableName);
108
    cleanTableName(displayName);
109
    if (not ignoreTable(displayName))
1751.4.24 by Andrew Hutchings
Fix ignore tables
110
      continue;
111
1751.4.23 by Andrew Hutchings
Fix various bugs
112
    query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='";
113
    query.append(databaseName);
114
    query.append("' AND TABLE_NAME = '");
115
    query.append(tableName);
116
    query.append("'");
117
118
    result= dcon->query(query);
119
1751.4.25 by Andrew Hutchings
Fix error handling
120
    if (result == NULL)
121
      return false;
122
1751.4.23 by Andrew Hutchings
Fix various bugs
123
    if ((row= drizzle_row_next(result)))
124
    {
125
      DrizzleDumpTableMySQL *table = new DrizzleDumpTableMySQL(tableName, dcon);
1751.4.25 by Andrew Hutchings
Fix error handling
126
      table->displayName= displayName;
1751.4.23 by Andrew Hutchings
Fix various bugs
127
      table->setCollate(row[1]);
128
      table->setEngine(row[2]);
129
      if (row[3])
130
        table->autoIncrement= boost::lexical_cast<uint64_t>(row[3]);
131
      else
132
        table->autoIncrement= 0;
133
134
      table->database= this;
1751.4.25 by Andrew Hutchings
Fix error handling
135
      if ((not table->populateFields()) or (not table->populateIndexes()))
136
      {
137
        delete table;
1799.7.5 by Andrew Hutchings
Fix test cases
138
        if (not ignore_errors)
139
          return false;
140
        else
141
          continue;
1751.4.25 by Andrew Hutchings
Fix error handling
142
      }
1751.4.23 by Andrew Hutchings
Fix various bugs
143
      tables.push_back(table);
144
      dcon->freeResult(result);
145
    }
146
    else
147
    {
148
      dcon->freeResult(result);
1799.7.5 by Andrew Hutchings
Fix test cases
149
      if (not ignore_errors)
150
        return false;
151
      else
152
        continue;
1751.4.23 by Andrew Hutchings
Fix various bugs
153
    }
154
  }
155
156
  return true;
157
158
}
159
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
160
bool DrizzleDumpTableMySQL::populateFields()
161
{
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
162
  drizzle_result_st *result;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
163
  drizzle_row_t row;
164
  std::string query;
165
1751.4.23 by Andrew Hutchings
Fix various bugs
166
  if (verbose)
167
    std::cerr << _("-- Retrieving fields for ") << tableName << "..." << std::endl;
168
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
169
  query="SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_DEFAULT, IS_NULLABLE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='";
170
  query.append(database->databaseName);
171
  query.append("' AND TABLE_NAME='");
172
  query.append(tableName);
173
  query.append("' ORDER BY ORDINAL_POSITION");
174
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
175
  result= dcon->query(query);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
176
1751.4.25 by Andrew Hutchings
Fix error handling
177
  if (result == NULL)
178
    return false;
179
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
180
  while ((row= drizzle_row_next(result)))
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
181
  {
182
    std::string fieldName(row[0]);
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
183
    DrizzleDumpFieldMySQL *field = new DrizzleDumpFieldMySQL(fieldName, dcon);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
184
    /* Stop valgrind warning */
185
    field->convertDateTime= false;
186
    /* Also sets collation */
187
    field->setType(row[1], row[8]);
1802.11.2 by Andrew Hutchings
Allow null dates for conversion
188
    field->isNull= (strcmp(row[3], "YES") == 0) ? true : false;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
189
    if (row[2])
190
    {
191
      if (field->convertDateTime)
192
      {
193
        field->dateTimeConvert(row[2]);
194
      }
195
      else
196
        field->defaultValue= row[2];
197
    }
198
    else
199
     field->defaultValue= "";
200
201
    field->isAutoIncrement= (strcmp(row[8], "auto_increment") == 0) ? true : false;
202
    field->defaultIsNull= field->isNull;
203
    field->length= (row[4]) ? boost::lexical_cast<uint32_t>(row[4]) : 0;
204
    field->decimalPrecision= (row[5]) ? boost::lexical_cast<uint32_t>(row[5]) : 0;
205
    field->decimalScale= (row[6]) ? boost::lexical_cast<uint32_t>(row[6]) : 0;
206
207
208
    fields.push_back(field);
209
  }
210
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
211
  dcon->freeResult(result);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
212
  return true;
213
}
214
215
216
void DrizzleDumpFieldMySQL::dateTimeConvert(const char* oldDefault)
217
{
218
  boost::match_flag_type flags = boost::match_default;
219
220
  if (strcmp(oldDefault, "CURRENT_TIMESTAMP") == 0)
221
  {
222
    defaultValue= oldDefault;
223
    return;
224
  }
225
226
  if (type.compare("INT") == 0)
227
  {
228
    /* We were a TIME, now we are an INT */
229
    std::string ts(oldDefault);
230
    boost::posix_time::time_duration td(boost::posix_time::duration_from_string(ts));
231
    defaultValue= boost::lexical_cast<std::string>(td.total_seconds());
232
    return;
233
  }
234
1802.11.1 by Andrew Hutchings
1. date regex was broken
235
  boost::regex date_regex("(0000|-00)");
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
236
1802.11.1 by Andrew Hutchings
1. date regex was broken
237
  if (not regex_search(oldDefault, date_regex, flags))
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
238
  {
239
    defaultValue= oldDefault;
240
  }
241
  else
242
  {
243
    defaultIsNull= true;
244
    defaultValue="";
245
  }
1802.11.2 by Andrew Hutchings
Allow null dates for conversion
246
  isNull= true;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
247
}
248
249
250
bool DrizzleDumpTableMySQL::populateIndexes()
251
{
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
252
  drizzle_result_st *result;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
253
  drizzle_row_t row;
254
  std::string query;
255
  std::string lastKey;
256
  bool firstIndex= true;
257
  DrizzleDumpIndex *index;
258
1751.4.23 by Andrew Hutchings
Fix various bugs
259
  if (verbose)
260
    std::cerr << _("-- Retrieving indexes for ") << tableName << "..." << std::endl;
261
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
262
  query="SHOW INDEXES FROM ";
263
  query.append(tableName);
264
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
265
  result= dcon->query(query);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
266
1751.4.25 by Andrew Hutchings
Fix error handling
267
  if (result == NULL)
268
    return false;
269
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
270
  while ((row= drizzle_row_next(result)))
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
271
  {
272
    std::string indexName(row[2]);
273
    if (indexName.compare(lastKey) != 0)
274
    {
275
      if (strcmp(row[10], "FULLTEXT") == 0)
276
        continue;
277
278
      if (!firstIndex)
279
        indexes.push_back(index);
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
280
      index = new DrizzleDumpIndexMySQL(indexName, dcon);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
281
      index->isPrimary= (strcmp(row[2], "PRIMARY") == 0);
282
      index->isUnique= (strcmp(row[1], "0") == 0);
283
      index->isHash= (strcmp(row[10], "HASH") == 0);
1802.2.1 by Andrew Hutchings
Fix index lengths not shown for part-indexed columns.
284
      index->length= (row[7]) ? boost::lexical_cast<uint32_t>(row[7]) : 0;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
285
      lastKey= row[2];
286
      firstIndex= false;
287
    }
288
    index->columns.push_back(row[4]);
289
  }
290
  if (!firstIndex)
291
    indexes.push_back(index);
292
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
293
  dcon->freeResult(result);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
294
  return true;
295
}
296
297
void DrizzleDumpFieldMySQL::setType(const char* raw_type, const char* raw_collation)
298
{
299
  std::string old_type(raw_type);
300
  std::string extra;
301
  size_t pos;
302
  
303
  if ((pos= old_type.find("(")) != std::string::npos)
304
  {
305
    extra= old_type.substr(pos);
306
    old_type.erase(pos, std::string::npos);
307
  }
308
309
  std::transform(old_type.begin(), old_type.end(), old_type.begin(), ::toupper);
310
  if ((old_type.find("CHAR") != std::string::npos) or 
311
    (old_type.find("TEXT") != std::string::npos))
312
    setCollate(raw_collation);
313
314
  if ((old_type.compare("INT") == 0) and 
315
    ((extra.find("unsigned") != std::string::npos)))
316
  {
317
    type= "BIGINT";
318
    return;
319
  }
320
    
321
  if ((old_type.compare("TINYINT") == 0) or
322
    (old_type.compare("SMALLINT") == 0) or
323
    (old_type.compare("MEDIUMINT") == 0))
324
  {
325
    type= "INT";
326
    return;
327
  }
328
329
  if ((old_type.compare("TINYBLOB") == 0) or
330
    (old_type.compare("MEDIUMBLOB") == 0) or
331
    (old_type.compare("LONGBLOB") == 0))
332
  {
333
    type= "BLOB";
334
    return;
335
  }
336
337
  if ((old_type.compare("TINYTEXT") == 0) or
338
    (old_type.compare("MEDIUMTEXT") == 0) or
1751.4.21 by Andrew Hutchings
Add database destination settings and connect it all up
339
    (old_type.compare("LONGTEXT") == 0) or
340
    (old_type.compare("SET") == 0))
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
341
  {
342
    type= "TEXT";
343
    return;
344
  }
345
346
  if (old_type.compare("CHAR") == 0)
347
  {
348
    type= "VARCHAR";
349
    return;
350
  }
351
352
  if (old_type.compare("BINARY") == 0)
353
  {
354
    type= "VARBINARY";
355
    return;
356
  }
357
358
  if (old_type.compare("ENUM") == 0)
359
  {
360
    type= old_type;
361
    /* Strip out the braces, we add them again during output */
362
    enumValues= extra.substr(1, extra.length()-2);
363
    return;
364
  }
365
366
  if ((old_type.find("TIME") != std::string::npos) or
367
    (old_type.find("DATE") != std::string::npos))
368
  {
369
    /* Intended to catch TIME/DATE/TIMESTAMP/DATETIME 
370
       We may have a default TIME/DATE which needs converting */
371
    convertDateTime= true;
372
  }
373
1802.3.1 by Andrew Hutchings
Add YEAR conversion that was previously missing from the MySQL migration code
374
  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
375
  {
376
    type= "INT";
377
    return;
378
  }
379
380
  if (old_type.compare("FLOAT") == 0)
381
  {
382
    type= "DOUBLE";
383
    return;
384
  }
385
386
  type= old_type;
387
  return;
388
}
389
390
void DrizzleDumpTableMySQL::setEngine(const char* newEngine)
391
{
392
  if (strcmp(newEngine, "MyISAM") == 0)
393
    engineName= "InnoDB";
394
  else
395
    engineName= newEngine; 
396
}
397
398
DrizzleDumpData* DrizzleDumpTableMySQL::getData(void)
399
{
1751.4.25 by Andrew Hutchings
Fix error handling
400
  try
401
  {
402
    return new DrizzleDumpDataMySQL(this, dcon);
403
  }
404
  catch(...)
405
  {
406
    return NULL;
407
  }
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
408
}
409
410
void DrizzleDumpDatabaseMySQL::setCollate(const char* newCollate)
411
{
412
  if (newCollate)
413
  {
414
    std::string tmpCollate(newCollate);
415
    if (tmpCollate.find("utf8") != std::string::npos)
416
    {
417
      collate= tmpCollate;
418
      return;
419
    }
420
  }
421
  collate= "utf8_general_ci";
422
}
423
424
void DrizzleDumpTableMySQL::setCollate(const char* newCollate)
425
{
426
  if (newCollate)
427
  {
428
    std::string tmpCollate(newCollate);
429
    if (tmpCollate.find("utf8") != std::string::npos)
430
    {
431
      collate= tmpCollate;
432
      return;
433
    }
434
  }
435
436
  collate= "utf8_general_ci";
437
}
438
439
void DrizzleDumpFieldMySQL::setCollate(const char* newCollate)
440
{
441
  if (newCollate)
442
  {
443
    std::string tmpCollate(newCollate);
444
    if (tmpCollate.find("utf8") != std::string::npos)
445
    {
446
      collation= tmpCollate;
447
      return;
448
    }
449
  }
450
  collation= "utf8_general_ci";
451
}
452
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
453
DrizzleDumpDataMySQL::DrizzleDumpDataMySQL(DrizzleDumpTable *dataTable,
454
  DrizzleDumpConnection *connection)
455
  : DrizzleDumpData(dataTable, connection)
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
456
{
457
  std::string query;
458
  query= "SELECT * FROM `";
1751.4.25 by Andrew Hutchings
Fix error handling
459
  query.append(table->displayName);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
460
  query.append("`");
1751.4.20 by Andrew Hutchings
Add database connection class and the start of a database output ostream
461
462
  result= dcon->query(query);
1751.4.25 by Andrew Hutchings
Fix error handling
463
  if (result == NULL)
464
    throw 1;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
465
}
466
467
DrizzleDumpDataMySQL::~DrizzleDumpDataMySQL()
468
{
469
  drizzle_result_free(result);
470
  if (result) delete result;
471
}
472
473
long DrizzleDumpDataMySQL::convertTime(const char* oldTime) const
474
{
475
  std::string ts(oldTime);
476
  boost::posix_time::time_duration td(boost::posix_time::duration_from_string(ts));
477
  long seconds= td.total_seconds();
478
  return seconds;
479
}
480
481
std::string DrizzleDumpDataMySQL::convertDate(const char* oldDate) const
482
{
483
  boost::match_flag_type flags = boost::match_default;
484
  std::string output;
1802.11.1 by Andrew Hutchings
1. date regex was broken
485
  boost::regex date_regex("(0000|-00)");
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
486
1802.11.1 by Andrew Hutchings
1. date regex was broken
487
  if (not regex_search(oldDate, date_regex, flags))
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
488
  {
489
    output.push_back('\'');
490
    output.append(oldDate);
491
    output.push_back('\'');
492
  }
493
  else
494
    output= "NULL";
495
496
  return output;
497
}
498
1802.11.1 by Andrew Hutchings
1. date regex was broken
499
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
500
{
1802.11.1 by Andrew Hutchings
1. date regex was broken
501
  std::string ret;
502
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
503
  if (table->fields[field]->convertDateTime)
504
  {
505
    if (table->fields[field]->type.compare("INT") == 0)
1802.11.1 by Andrew Hutchings
1. date regex was broken
506
      ret= boost::lexical_cast<std::string>(convertTime(item));
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
507
    else
1802.11.1 by Andrew Hutchings
1. date regex was broken
508
      ret= convertDate(item);
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
509
  }
1802.11.1 by Andrew Hutchings
1. date regex was broken
510
  return ret;
1751.4.19 by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files
511
}
512