~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Brian Aker
  • Date: 2010-03-27 04:12:14 UTC
  • mfrom: (1395.1.18 build)
  • Revision ID: brian@gaz-20100327041214-2pm5eay51312xjvq
Merge (fixes known issues in ALTER TABLE not resetting correctly DFE).

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <string>
26
26
#include <vector>
27
27
#include <set>
 
28
#include <fstream>
28
29
#include <algorithm>
29
30
#include <functional>
30
31
 
131
132
        break;
132
133
    }
133
134
    else
 
135
    {
134
136
      enoent_or_zero= 0;                        // No error for ENOENT
 
137
    }
 
138
 
135
139
    error= enoent_or_zero;
136
140
  }
137
141
  return error;
293
297
 
294
298
  result_type operator() (argument_type engine)
295
299
  {
296
 
    int ret= engine->doGetTableDefinition(session,
297
 
                                          identifier,
298
 
                                          table_message);
 
300
    int ret= engine->doGetTableDefinition(session, identifier, table_message);
299
301
 
300
302
    if (ret != ENOENT)
301
303
      err= ret;
448
450
  int error= 0;
449
451
  int error_proto;
450
452
  message::Table src_proto;
451
 
  StorageEngine* engine;
 
453
  StorageEngine *engine;
452
454
 
453
455
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
454
456
 
455
457
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
456
458
  {
457
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
458
 
             src_proto.InitializationErrorString().c_str());
 
459
    string error_message;
 
460
 
 
461
    error_message.append(identifier.getSQLPath());
 
462
    error_message.append(" : ");
 
463
    error_message.append(src_proto.InitializationErrorString());
 
464
 
 
465
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
 
466
 
459
467
    return ER_CORRUPT_TABLE_DEFINITION;
460
468
  }
461
469
 
463
471
 
464
472
  if (engine)
465
473
  {
466
 
    std::string path(identifier.getPath());
467
 
    engine->setTransactionReadWrite(session);
468
 
    error= engine->doDropTable(session, identifier);
469
 
 
470
 
    if (not error)
471
 
    {
472
 
      if (not engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
473
 
      {
474
 
        uint64_t counter; // @todo We need to refactor to check that.
475
 
 
476
 
        for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
477
 
                 DropTable(session, identifier, counter));
478
 
      }
479
 
    }
 
474
    error= StorageEngine::dropTable(session, *engine, identifier);
480
475
  }
481
476
 
482
477
  if (error_proto && error == 0)
485
480
  return error;
486
481
}
487
482
 
 
483
int StorageEngine::dropTable(Session& session,
 
484
                             StorageEngine &engine,
 
485
                             TableIdentifier &identifier)
 
486
{
 
487
  int error;
 
488
 
 
489
  engine.setTransactionReadWrite(session);
 
490
  error= engine.doDropTable(session, identifier);
 
491
 
 
492
  if (not error)
 
493
  {
 
494
    if (not engine.check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
 
495
    {
 
496
      uint64_t counter; // @todo We need to refactor to check that.
 
497
 
 
498
      for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
 
499
               DropTable(session, identifier, counter));
 
500
    }
 
501
  }
 
502
 
 
503
  return error;
 
504
}
 
505
 
488
506
/**
489
507
  Initiates table-file and calls appropriate database-creator.
490
508
 
626
644
 
627
645
class StorageEngineGetSchemaDefinition: public unary_function<StorageEngine *, bool>
628
646
{
629
 
  const std::string &schema_name;
 
647
  std::string schema_name;
630
648
  message::Schema &schema_proto;
631
649
 
632
650
public:
633
 
  StorageEngineGetSchemaDefinition(const std::string &schema_name_arg,
 
651
  StorageEngineGetSchemaDefinition(const std::string schema_name_arg,
634
652
                                  message::Schema &schema_proto_arg) :
635
653
    schema_name(schema_name_arg),
636
654
    schema_proto(schema_proto_arg) 
637
 
  { }
 
655
  {
 
656
    transform(schema_name.begin(), schema_name.end(),
 
657
              schema_name.begin(), ::tolower);
 
658
  }
638
659
 
639
660
  result_type operator() (argument_type engine)
640
661
  {
645
666
/*
646
667
  Return value is "if parsed"
647
668
*/
 
669
bool StorageEngine::getSchemaDefinition(TableIdentifier &identifier, message::Schema &proto)
 
670
{
 
671
  return StorageEngine::getSchemaDefinition(identifier.getSchemaName(), proto);
 
672
}
 
673
 
648
674
bool StorageEngine::getSchemaDefinition(const std::string &schema_name, message::Schema &proto)
649
675
{
650
676
  proto.Clear();
668
694
  return StorageEngine::getSchemaDefinition(schema_name, proto);
669
695
}
670
696
 
 
697
bool StorageEngine::doesSchemaExist(TableIdentifier &identifier)
 
698
{
 
699
  message::Schema proto;
 
700
 
 
701
  return StorageEngine::getSchemaDefinition(identifier.getSchemaName(), proto);
 
702
}
 
703
 
671
704
 
672
705
const CHARSET_INFO *StorageEngine::getSchemaCollation(const std::string &schema_name)
673
706
{
831
864
class DropTables: public unary_function<StorageEngine *, void>
832
865
{
833
866
  Session &session;
834
 
  TableNameList &set_of_names;
 
867
  TableIdentifierList &table_identifiers;
835
868
 
836
869
public:
837
870
 
838
 
  DropTables(Session &session_arg, set<string>& of_names) :
 
871
  DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
839
872
    session(session_arg),
840
 
    set_of_names(of_names)
 
873
    table_identifiers(table_identifiers_arg)
841
874
  { }
842
875
 
843
876
  result_type operator() (argument_type engine)
844
877
  {
845
 
    for (TableNameList::iterator iter= set_of_names.begin();
846
 
         iter != set_of_names.end();
 
878
    for (TableIdentifierList::iterator iter= table_identifiers.begin();
 
879
         iter != table_identifiers.end();
847
880
         iter++)
848
881
    {
849
 
      TableIdentifier dummy((*iter).c_str());
850
 
      int error= engine->doDropTable(session, dummy);
 
882
      int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
851
883
 
852
884
      // On a return of zero we know we found and deleted the table. So we
853
885
      // remove it from our search.
854
886
      if (not error)
855
 
        set_of_names.erase(iter);
 
887
        table_identifiers.erase(iter);
856
888
    }
857
889
  }
858
890
};
865
897
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
866
898
{
867
899
  CachedDirectory dir(directory, set_of_table_definition_ext);
868
 
  set<string> set_of_table_names;
 
900
  TableIdentifierList table_identifiers;
869
901
 
870
902
  if (dir.fail())
871
903
  {
891
923
    path+= directory;
892
924
    path+= FN_LIBCHAR;
893
925
    path+= entry->filename;
894
 
    set_of_table_names.insert(path);
 
926
    message::Table definition;
 
927
    if (StorageEngine::readTableFile(path, definition))
 
928
    {
 
929
      TableIdentifier identifier(definition.schema(), definition.name(), path);
 
930
      table_identifiers.push_back(identifier);
 
931
    }
895
932
  }
896
933
 
897
934
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
898
 
           DropTables(session, set_of_table_names));
 
935
           DropTables(session, table_identifiers));
899
936
  
900
937
  /*
901
938
    Now we just clean up anything that might left over.
1201
1238
 
1202
1239
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
1203
1240
{
 
1241
  message::Table table_message;
1204
1242
  string src_path(src.getPath());
1205
1243
  string dest_path(dest.getPath());
1206
1244
 
1207
1245
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1208
1246
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1209
1247
 
1210
 
  int fd= open(src_path.c_str(), O_RDONLY);
1211
 
 
1212
 
  if (fd == -1)
1213
 
  {
1214
 
    perror(src_path.c_str());
1215
 
    return errno;
1216
 
  }
1217
 
 
1218
 
  google::protobuf::io::ZeroCopyInputStream* input=
1219
 
    new google::protobuf::io::FileInputStream(fd);
1220
 
 
1221
 
  if (not input)
1222
 
    return HA_ERR_CRASHED_ON_USAGE;
1223
 
 
1224
 
  message::Table table_message;
1225
 
  if (not table_message.ParseFromZeroCopyStream(input))
1226
 
  {
1227
 
    close(fd);
1228
 
    delete input;
1229
 
    if (not table_message.IsInitialized())
1230
 
    {
1231
 
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1232
 
               table_message.InitializationErrorString().c_str());
1233
 
      return ER_CORRUPT_TABLE_DEFINITION;
1234
 
    }
1235
 
 
1236
 
    return HA_ERR_CRASHED_ON_USAGE;
1237
 
  }
1238
 
  close(fd);
1239
 
  delete input;
 
1248
  bool was_read= StorageEngine::readTableFile(src_path.c_str(), table_message);
 
1249
 
 
1250
  if (not was_read)
 
1251
  {
 
1252
    return ENOENT;
 
1253
  }
1240
1254
 
1241
1255
  dest.copyToTableMessage(table_message);
1242
1256
 
1243
 
  // We have to update the source to have the right information before we
1244
 
  // make it the master.
1245
 
  int error=  StorageEngine::writeDefinitionFromPath(src, table_message);
1246
 
  if (error)
 
1257
  int error= StorageEngine::writeDefinitionFromPath(dest, table_message);
 
1258
 
 
1259
  if (not error)
1247
1260
  {
1248
 
    perror(src_path.c_str());
1249
 
    return error;
 
1261
    if (unlink(src_path.c_str()))
 
1262
      perror(src_path.c_str());
1250
1263
  }
1251
1264
 
1252
 
  return internal::my_rename(src_path.c_str(), dest_path.c_str(), MYF(MY_WME));
 
1265
  return error;
1253
1266
}
1254
1267
 
1255
1268
int StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_message)
1256
1269
{
 
1270
  char definition_file_tmp[FN_REFLEN];
1257
1271
  string file_name(identifier.getPath());
1258
1272
 
1259
1273
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1260
1274
 
1261
 
  int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, internal::my_umask);
 
1275
  snprintf(definition_file_tmp, sizeof(definition_file_tmp), "%s.%sXXXXXX", file_name.c_str(), DEFAULT_DEFINITION_FILE_EXT.c_str());
 
1276
 
 
1277
  int fd= mkstemp(definition_file_tmp);
1262
1278
 
1263
1279
  if (fd == -1)
1264
1280
  {
1265
 
    perror(file_name.c_str());
 
1281
    perror(definition_file_tmp);
1266
1282
    return errno;
1267
1283
  }
1268
1284
 
1269
1285
  google::protobuf::io::ZeroCopyOutputStream* output=
1270
1286
    new google::protobuf::io::FileOutputStream(fd);
1271
1287
 
1272
 
  if (table_message.SerializeToZeroCopyStream(output) == false)
 
1288
  if (not table_message.SerializeToZeroCopyStream(output))
1273
1289
  {
 
1290
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
 
1291
             table_message.InitializationErrorString().c_str());
1274
1292
    delete output;
1275
 
    close(fd);
1276
 
    perror(file_name.c_str());
1277
 
    return errno;
 
1293
 
 
1294
    if (close(fd) == -1)
 
1295
      perror(definition_file_tmp);
 
1296
 
 
1297
    if (unlink(definition_file_tmp) == -1)
 
1298
      perror(definition_file_tmp);
 
1299
 
 
1300
    return ER_CORRUPT_TABLE_DEFINITION;
1278
1301
  }
1279
1302
 
1280
1303
  delete output;
1281
 
  close(fd);
 
1304
 
 
1305
  if (close(fd) == -1)
 
1306
  {
 
1307
    int error= errno;
 
1308
    perror(definition_file_tmp);
 
1309
 
 
1310
    if (unlink(definition_file_tmp))
 
1311
      perror(definition_file_tmp);
 
1312
 
 
1313
    return error;
 
1314
  }
 
1315
 
 
1316
  if (rename(definition_file_tmp, file_name.c_str()) == -1)
 
1317
  {
 
1318
    int error= errno;
 
1319
    perror(definition_file_tmp);
 
1320
 
 
1321
    if (unlink(definition_file_tmp))
 
1322
      perror(definition_file_tmp);
 
1323
 
 
1324
    return error;
 
1325
  }
1282
1326
 
1283
1327
  return 0;
1284
1328
}
1316
1360
  return false;
1317
1361
}
1318
1362
 
 
1363
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
 
1364
{
 
1365
  fstream input(path.c_str(), ios::in | ios::binary);
 
1366
 
 
1367
  if (input.good())
 
1368
  {
 
1369
    if (table_message.ParseFromIstream(&input))
 
1370
    {
 
1371
      return true;
 
1372
    }
 
1373
 
 
1374
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
 
1375
             table_message.InitializationErrorString().c_str());
 
1376
  }
 
1377
  else
 
1378
  {
 
1379
    perror(path.c_str());
 
1380
  }
 
1381
 
 
1382
  return false;
 
1383
}
 
1384
 
 
1385
 
 
1386
 
1319
1387
} /* namespace plugin */
1320
1388
} /* namespace drizzled */