~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzledump_mysql.cc

  • Committer: Patrick Galbraith
  • Date: 2010-10-03 13:40:30 UTC
  • mto: (1812.1.3 build)
  • mto: This revision was merged to the branch mainline in revision 1813.
  • Revision ID: patg@patg-desktop-20101003134030-j13wf1e79za77jtf
Added license to start_mc.sh.in to clear up ambiguity

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <boost/date_time/posix_time/posix_time.hpp>
27
27
#include <drizzled/gettext.h>
28
28
 
29
 
extern bool verbose;
30
 
extern bool ignore_errors;
 
29
extern bool  verbose;
31
30
 
32
31
bool DrizzleDumpDatabaseMySQL::populateTables()
33
32
{
41
40
  if (verbose)
42
41
    std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl;
43
42
 
44
 
  query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, AUTO_INCREMENT, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE != 'VIEW' AND TABLE_SCHEMA='";
 
43
  query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='";
45
44
  query.append(databaseName);
46
45
  query.append("' ORDER BY TABLE_NAME");
47
46
 
52
51
 
53
52
  while ((row= drizzle_row_next(result)))
54
53
  {
55
 
    size_t* row_sizes= drizzle_row_field_sizes(result);
56
54
    std::string tableName(row[0]);
57
55
    std::string displayName(tableName);
58
56
    cleanTableName(displayName);
68
66
    else
69
67
      table->autoIncrement= 0;
70
68
 
71
 
    if ((row[4]) and (strstr(row[4], "InnoDB free") == NULL))
72
 
      table->comment= DrizzleDumpData::escape(row[4], row_sizes[4]);
73
 
    else
74
 
      table->comment= "";
75
 
 
76
69
    table->database= this;
77
 
    if ((not table->populateFields()) or (not table->populateIndexes()) or
78
 
     (not table->populateFkeys()))
 
70
    if ((not table->populateFields()) or (not table->populateIndexes()))
79
71
    {
80
72
      delete table;
81
 
      if (not ignore_errors)
82
 
        return false;
83
 
      else
84
 
        continue;
 
73
      return false;
85
74
    }
86
75
    tables.push_back(table);
87
76
  }
136
125
      if ((not table->populateFields()) or (not table->populateIndexes()))
137
126
      {
138
127
        delete table;
139
 
        if (not ignore_errors)
140
 
          return false;
141
 
        else
142
 
          continue;
 
128
        return false;
143
129
      }
144
130
      tables.push_back(table);
145
131
      dcon->freeResult(result);
147
133
    else
148
134
    {
149
135
      dcon->freeResult(result);
150
 
      if (not ignore_errors)
151
 
        return false;
152
 
      else
153
 
        continue;
 
136
      return false;
154
137
    }
155
138
  }
156
139
 
167
150
  if (verbose)
168
151
    std::cerr << _("-- Retrieving fields for ") << tableName << "..." << std::endl;
169
152
 
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='";
 
153
  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='";
171
154
  query.append(database->databaseName);
172
155
  query.append("' AND TABLE_NAME='");
173
156
  query.append(tableName);
184
167
    DrizzleDumpFieldMySQL *field = new DrizzleDumpFieldMySQL(fieldName, dcon);
185
168
    /* Stop valgrind warning */
186
169
    field->convertDateTime= false;
187
 
    field->isNull= (strcmp(row[3], "YES") == 0) ? true : false;
188
170
    /* Also sets collation */
189
171
    field->setType(row[1], row[8]);
190
 
    if (field->type.compare("ENUM") == 0)
191
 
      field->isNull= true;
192
 
 
193
 
    if ((row[2]) and (field->type.compare("TEXT") != 0))
 
172
    if (row[2])
194
173
    {
195
 
      field->defaultValue= row[2];
196
174
      if (field->convertDateTime)
197
175
      {
198
 
        field->dateTimeConvert();
 
176
        field->dateTimeConvert(row[2]);
199
177
      }
 
178
      else
 
179
        field->defaultValue= row[2];
200
180
    }
201
181
    else
202
 
    {
203
 
      field->defaultValue= "";
204
 
    }
 
182
     field->defaultValue= "";
205
183
 
 
184
    field->isNull= (strcmp(row[3], "YES") == 0) ? true : false;
206
185
    field->isAutoIncrement= (strcmp(row[8], "auto_increment") == 0) ? true : false;
207
186
    field->defaultIsNull= field->isNull;
208
 
 
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;
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
 
 
 
187
    field->length= (row[4]) ? boost::lexical_cast<uint32_t>(row[4]) : 0;
223
188
    field->decimalPrecision= (row[5]) ? boost::lexical_cast<uint32_t>(row[5]) : 0;
224
189
    field->decimalScale= (row[6]) ? boost::lexical_cast<uint32_t>(row[6]) : 0;
225
 
    field->comment= (row[9]) ? row[9] : "";
 
190
 
 
191
 
226
192
    fields.push_back(field);
227
193
  }
228
194
 
231
197
}
232
198
 
233
199
 
234
 
void DrizzleDumpFieldMySQL::dateTimeConvert(void)
 
200
void DrizzleDumpFieldMySQL::dateTimeConvert(const char* oldDefault)
235
201
{
236
202
  boost::match_flag_type flags = boost::match_default;
237
203
 
238
 
  if (strcmp(defaultValue.c_str(), "CURRENT_TIMESTAMP") == 0)
 
204
  if (strcmp(oldDefault, "CURRENT_TIMESTAMP") == 0)
 
205
  {
 
206
    defaultValue= oldDefault;
239
207
    return;
 
208
  }
240
209
 
241
210
  if (type.compare("INT") == 0)
242
211
  {
243
212
    /* We were a TIME, now we are an INT */
244
 
    std::string ts(defaultValue);
 
213
    std::string ts(oldDefault);
245
214
    boost::posix_time::time_duration td(boost::posix_time::duration_from_string(ts));
246
215
    defaultValue= boost::lexical_cast<std::string>(td.total_seconds());
247
216
    return;
248
217
  }
249
218
 
250
 
  boost::regex date_regex("(0000|-00)");
 
219
  boost::regex date_regex("([0-9]{3}[1-9]-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))");
251
220
 
252
 
  if (regex_search(defaultValue, date_regex, flags))
 
221
  if (regex_search(oldDefault, date_regex, flags))
 
222
  {
 
223
    defaultValue= oldDefault;
 
224
  }
 
225
  else
253
226
  {
254
227
    defaultIsNull= true;
255
228
    defaultValue="";
291
264
      index->isPrimary= (strcmp(row[2], "PRIMARY") == 0);
292
265
      index->isUnique= (strcmp(row[1], "0") == 0);
293
266
      index->isHash= (strcmp(row[10], "HASH") == 0);
294
 
      index->length= (row[7]) ? boost::lexical_cast<uint32_t>(row[7]) : 0;
295
267
      lastKey= row[2];
296
268
      firstIndex= false;
297
269
    }
304
276
  return true;
305
277
}
306
278
 
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
 
 
317
 
  query= "SHOW CREATE TABLE `";
318
 
  query.append(database->databaseName);
319
 
  query.append("`.`");
320
 
  query.append(tableName);
321
 
  query.append("`");
322
 
  result= dcon->query(query);
323
 
 
324
 
  if (result == NULL)
325
 
    return false;
326
 
 
327
 
  if ((row= drizzle_row_next(result)))
328
 
  {
329
 
    boost::match_flag_type flags = boost::match_default;
330
 
    boost::regex constraint_regex("CONSTRAINT `(.*?)` FOREIGN KEY \\((.*?)\\) REFERENCES `(.*?)` \\((.*?)\\)( ON (UPDATE|DELETE) (CASCADE|RESTRICT|SET NULL))?( ON (UPDATE|DELETE) (CASCADE|RESTRICT|SET NULL))?");
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))
339
 
    {
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= "";
360
 
 
361
 
      fkeys.push_back(fkey);
362
 
 
363
 
      start= constraint_results[0].second;
364
 
      flags |= boost::match_prev_avail; 
365
 
      flags |= boost::match_not_bob;
366
 
    }
367
 
  }
368
 
  dcon->freeResult(result);
369
 
  return true;
370
 
}
371
 
 
372
279
void DrizzleDumpFieldMySQL::setType(const char* raw_type, const char* raw_collation)
373
280
{
374
281
  std::string old_type(raw_type);
375
282
  std::string extra;
376
283
  size_t pos;
377
284
  
378
 
  if (((pos= old_type.find("(")) != std::string::npos) or
379
 
    ((pos= old_type.find(" ")) != std::string::npos))
 
285
  if ((pos= old_type.find("(")) != std::string::npos)
380
286
  {
381
287
    extra= old_type.substr(pos);
382
288
    old_type.erase(pos, std::string::npos);
387
293
    (old_type.find("TEXT") != std::string::npos))
388
294
    setCollate(raw_collation);
389
295
 
390
 
  if ((old_type.compare("BIGINT") == 0) and
391
 
    ((extra.find("unsigned") != std::string::npos)))
392
 
  {
393
 
    rangeCheck= true;
394
 
  }
395
 
 
396
296
  if ((old_type.compare("INT") == 0) and 
397
297
    ((extra.find("unsigned") != std::string::npos)))
398
298
  {
434
334
  if (old_type.compare("BINARY") == 0)
435
335
  {
436
336
    type= "VARBINARY";
437
 
    
438
337
    return;
439
338
  }
440
339
 
452
351
    /* Intended to catch TIME/DATE/TIMESTAMP/DATETIME 
453
352
       We may have a default TIME/DATE which needs converting */
454
353
    convertDateTime= true;
455
 
    isNull= true;
456
354
  }
457
355
 
458
 
  if ((old_type.compare("TIME") == 0) or (old_type.compare("YEAR") == 0))
 
356
  if (old_type.compare("TIME") == 0)
459
357
  {
460
358
    type= "INT";
461
359
    return;
467
365
    return;
468
366
  }
469
367
 
470
 
  if (old_type.compare("BIT") == 0)
471
 
  {
472
 
    type= "VARBINARY";
473
 
    return;
474
 
  }
475
 
 
476
368
  type= old_type;
477
369
  return;
478
370
}
479
371
 
480
372
void DrizzleDumpTableMySQL::setEngine(const char* newEngine)
481
373
{
482
 
  if ((strcmp(newEngine, "MyISAM") == 0) || (strcmp(newEngine, "MEMORY") == 0))
 
374
  if (strcmp(newEngine, "MyISAM") == 0)
483
375
    engineName= "InnoDB";
484
376
  else
485
377
    engineName= newEngine; 
551
443
 
552
444
  result= dcon->query(query);
553
445
  if (result == NULL)
554
 
    throw std::exception();
 
446
    throw 1;
555
447
}
556
448
 
557
449
DrizzleDumpDataMySQL::~DrizzleDumpDataMySQL()
558
450
{
559
451
  drizzle_result_free(result);
560
 
  delete result;
 
452
  if (result) delete result;
561
453
}
562
454
 
563
455
long DrizzleDumpDataMySQL::convertTime(const char* oldTime) const
572
464
{
573
465
  boost::match_flag_type flags = boost::match_default;
574
466
  std::string output;
575
 
  boost::regex date_regex("(0000|-00)");
 
467
  boost::regex date_regex("([0-9]{3}[1-9]-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))");
576
468
 
577
 
  if (not regex_search(oldDate, date_regex, flags))
 
469
  if (regex_search(oldDate, date_regex, flags))
578
470
  {
579
471
    output.push_back('\'');
580
472
    output.append(oldDate);
586
478
  return output;
587
479
}
588
480
 
589
 
std::string DrizzleDumpDataMySQL::checkDateTime(const char* item, uint32_t field) const
 
481
std::ostream& DrizzleDumpDataMySQL::checkDateTime(std::ostream &os, const char* item, uint32_t field) const
590
482
{
591
 
  std::string ret;
592
 
 
593
483
  if (table->fields[field]->convertDateTime)
594
484
  {
595
485
    if (table->fields[field]->type.compare("INT") == 0)
596
 
      ret= boost::lexical_cast<std::string>(convertTime(item));
 
486
      os << convertTime(item);
597
487
    else
598
 
      ret= convertDate(item);
 
488
      os << convertDate(item);
599
489
  }
600
 
  return ret;
 
490
  return os;
601
491
}
602
492