~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzledump_mysql.cc

  • Committer: Brian Aker
  • Date: 2010-10-28 01:45:34 UTC
  • mfrom: (1878.5.8 catalogs)
  • Revision ID: brian@tangent.org-20101028014534-b6qp4wp6crj60h7k
Merge in catalog tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
167
167
  if (verbose)
168
168
    std::cerr << _("-- Retrieving fields for ") << tableName << "..." << std::endl;
169
169
 
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='";
 
170
  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
171
  query.append(database->databaseName);
172
172
  query.append("' AND TABLE_NAME='");
173
173
  query.append(tableName);
184
184
    DrizzleDumpFieldMySQL *field = new DrizzleDumpFieldMySQL(fieldName, dcon);
185
185
    /* Stop valgrind warning */
186
186
    field->convertDateTime= false;
187
 
    field->isNull= (strcmp(row[3], "YES") == 0) ? true : false;
188
187
    /* Also sets collation */
189
188
    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))
 
189
    field->isNull= (strcmp(row[3], "YES") == 0) ? true : false;
 
190
    if (row[2])
194
191
    {
195
192
      field->defaultValue= row[2];
196
 
      if (field->convertDateTime)
197
 
      {
198
 
        field->dateTimeConvert();
199
 
      }
200
193
    }
201
194
    else
 
195
     field->defaultValue= "";
 
196
 
 
197
    if (field->convertDateTime)
202
198
    {
203
 
      field->defaultValue= "";
 
199
      field->dateTimeConvert();
204
200
    }
205
201
 
 
202
 
206
203
    field->isAutoIncrement= (strcmp(row[8], "auto_increment") == 0) ? true : false;
207
204
    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;
 
205
    field->length= (row[4]) ? boost::lexical_cast<uint32_t>(row[4]) : 0;
 
206
    if ((row[5] != NULL) and (row[6] != NULL))
 
207
    {
 
208
      field->decimalPrecision= boost::lexical_cast<uint32_t>(row[5]);
 
209
      field->decimalScale= boost::lexical_cast<uint32_t>(row[6]);
 
210
    }
212
211
    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
212
    {
220
 
      field->length= 1;
 
213
      field->decimalPrecision= 0;
 
214
      field->decimalScale= 0;
221
215
    }
222
216
 
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;
225
 
    field->comment= (row[9]) ? row[9] : "";
226
217
    fields.push_back(field);
227
218
  }
228
219
 
254
245
    defaultIsNull= true;
255
246
    defaultValue="";
256
247
  }
 
248
  isNull= true;
257
249
}
258
250
 
259
251
 
314
306
  if (verbose)
315
307
    std::cerr << _("-- Retrieving foreign keys for ") << tableName << "..." << std::endl;
316
308
 
317
 
  query= "SHOW CREATE TABLE `";
318
 
  query.append(database->databaseName);
319
 
  query.append("`.`");
320
 
  query.append(tableName);
321
 
  query.append("`");
 
309
  query= "SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'REFERENTIAL_CONSTRAINTS'";
 
310
 
322
311
  result= dcon->query(query);
323
312
 
324
313
  if (result == NULL)
325
314
    return false;
326
315
 
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];
 
316
  uint64_t search_count = drizzle_result_row_count(result);
 
317
 
 
318
  dcon->freeResult(result);
 
319
 
 
320
  /* MySQL 5.0 will be 0 and MySQL 5.1 will be 1 */
 
321
  if (search_count > 0)
 
322
  {
 
323
    query= "select rc.constraint_name, rc.referenced_table_name, group_concat(distinct concat('`',kc.column_name,'`')), rc.update_rule, rc.delete_rule, rc.match_option, group_concat(distinct concat('`',kt.column_name,'`')) from information_schema.referential_constraints rc join information_schema.key_column_usage kt on (rc.constraint_schema = kt.constraint_schema and rc.constraint_name = kt.constraint_name) join information_schema.key_column_usage kc on (rc.constraint_schema = kc.constraint_schema and rc.referenced_table_name = kc.table_name and rc.unique_constraint_name = kc.constraint_name) where rc.constraint_schema='";
 
324
    query.append(database->databaseName);
 
325
    query.append("' and rc.table_name='");
 
326
    query.append(tableName);
 
327
    query.append("' group by rc.constraint_name");
 
328
 
 
329
    result= dcon->query(query);
 
330
 
 
331
    if (result == NULL)
 
332
      return false;
 
333
 
 
334
    while ((row= drizzle_row_next(result)))
 
335
    {
 
336
      fkey= new DrizzleDumpForeignKey(row[0], dcon);
 
337
      fkey->parentColumns= row[6];
 
338
      fkey->childTable= row[1];
 
339
      fkey->childColumns= row[2];
 
340
      fkey->updateRule= (strcmp(row[3], "RESTRICT") != 0) ? row[3] : "";
 
341
      fkey->deleteRule= (strcmp(row[4], "RESTRICT") != 0) ? row[4] : "";
 
342
      fkey->matchOption= (strcmp(row[5], "NONE") != 0) ? row[5] : "";
 
343
 
 
344
      fkeys.push_back(fkey);
 
345
    }
 
346
  }
 
347
  else
 
348
  {
 
349
    query= "SHOW CREATE TABLE `";
 
350
    query.append(database->databaseName);
 
351
    query.append("`.`");
 
352
    query.append(tableName);
 
353
    query.append("`");
 
354
    result= dcon->query(query);
 
355
 
 
356
    if (result == NULL)
 
357
      return false;
 
358
 
 
359
    if ((row= drizzle_row_next(result)))
 
360
    {
 
361
      boost::match_flag_type flags = boost::match_default;
 
362
      boost::regex constraint_regex("CONSTRAINT `(.*)` FOREIGN KEY \\((.*)\\) REFERENCES `(.*)` \\((.*)\\)( ON (UPDATE|DELETE) (CASCADE|RESTRICT|SET NULL))?( ON (UPDATE|DELETE) (CASCADE|RESTRICT|SET NULL))?");
 
363
 
 
364
      boost::match_results<std::string::const_iterator> constraint_results;
 
365
 
 
366
      std::string search_body(row[1]);
 
367
      std::string::const_iterator start, end;
 
368
      start= search_body.begin();
 
369
      end= search_body.end();
 
370
      while (regex_search(start, end, constraint_results, constraint_regex, flags))
 
371
      {
 
372
        fkey= new DrizzleDumpForeignKey(constraint_results[1], dcon);
 
373
        fkey->parentColumns= constraint_results[2];
 
374
        fkey->childTable= constraint_results[3];
 
375
        fkey->childColumns= constraint_results[4];
344
376
        
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;
 
377
        if (constraint_results[5].compare("") != 0)
 
378
        {
 
379
          if (constraint_results[6].compare("UPDATE") == 0)
 
380
            fkey->updateRule= constraint_results[7];
 
381
          else if (constraint_results[6].compare("DELETE") == 0)
 
382
            fkey->deleteRule= constraint_results[7];
 
383
        }
 
384
        if (constraint_results[8].compare("") != 0)
 
385
        {
 
386
          if (constraint_results[9].compare("UPDATE") == 0)
 
387
            fkey->updateRule= constraint_results[10];
 
388
          else if (constraint_results[9].compare("DELETE") == 0)
 
389
            fkey->deleteRule= constraint_results[10];
 
390
        }
 
391
        fkey->matchOption= "";
 
392
 
 
393
        fkeys.push_back(fkey);
 
394
 
 
395
        start= constraint_results[0].second;
 
396
        flags |= boost::match_prev_avail; 
 
397
        flags |= boost::match_not_bob;
 
398
      }
366
399
    }
367
400
  }
368
401
  dcon->freeResult(result);
375
408
  std::string extra;
376
409
  size_t pos;
377
410
  
378
 
  if (((pos= old_type.find("(")) != std::string::npos) or
379
 
    ((pos= old_type.find(" ")) != std::string::npos))
 
411
  if ((pos= old_type.find("(")) != std::string::npos)
380
412
  {
381
413
    extra= old_type.substr(pos);
382
414
    old_type.erase(pos, std::string::npos);
387
419
    (old_type.find("TEXT") != std::string::npos))
388
420
    setCollate(raw_collation);
389
421
 
390
 
  if ((old_type.compare("BIGINT") == 0) and
391
 
    ((extra.find("unsigned") != std::string::npos)))
392
 
  {
393
 
    rangeCheck= true;
394
 
  }
395
 
 
396
422
  if ((old_type.compare("INT") == 0) and 
397
423
    ((extra.find("unsigned") != std::string::npos)))
398
424
  {
434
460
  if (old_type.compare("BINARY") == 0)
435
461
  {
436
462
    type= "VARBINARY";
437
 
    
438
463
    return;
439
464
  }
440
465
 
452
477
    /* Intended to catch TIME/DATE/TIMESTAMP/DATETIME 
453
478
       We may have a default TIME/DATE which needs converting */
454
479
    convertDateTime= true;
455
 
    isNull= true;
456
480
  }
457
481
 
458
482
  if ((old_type.compare("TIME") == 0) or (old_type.compare("YEAR") == 0))
467
491
    return;
468
492
  }
469
493
 
470
 
  if (old_type.compare("BIT") == 0)
471
 
  {
472
 
    type= "VARBINARY";
473
 
    return;
474
 
  }
475
 
 
476
494
  type= old_type;
477
495
  return;
478
496
}
479
497
 
480
498
void DrizzleDumpTableMySQL::setEngine(const char* newEngine)
481
499
{
482
 
  if ((strcmp(newEngine, "MyISAM") == 0) || (strcmp(newEngine, "MEMORY") == 0))
 
500
  if (strcmp(newEngine, "MyISAM") == 0)
483
501
    engineName= "InnoDB";
484
502
  else
485
503
    engineName= newEngine; 
551
569
 
552
570
  result= dcon->query(query);
553
571
  if (result == NULL)
554
 
    throw std::exception();
 
572
    throw 1;
555
573
}
556
574
 
557
575
DrizzleDumpDataMySQL::~DrizzleDumpDataMySQL()
558
576
{
559
577
  drizzle_result_free(result);
560
 
  delete result;
 
578
  if (result) delete result;
561
579
}
562
580
 
563
581
long DrizzleDumpDataMySQL::convertTime(const char* oldTime) const