~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Eric Day
  • Date: 2010-03-25 19:28:37 UTC
  • mfrom: (1405 staging)
  • mto: This revision was merged to the branch mainline in revision 1409.
  • Revision ID: eday@oddments.org-20100325192837-4exmacbrywjovsqp
Merged trunk, rsolved conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
static std::set<std::string> set_of_table_definition_ext;
75
75
 
76
76
StorageEngine::StorageEngine(const string name_arg,
77
 
                             const bitset<HTON_BIT_SIZE> &flags_arg)
78
 
    : Plugin(name_arg, "StorageEngine"),
79
 
      MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
80
 
      flags(flags_arg)
 
77
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
 
78
  Plugin(name_arg, "StorageEngine"),
 
79
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
 
80
  flags(flags_arg)
81
81
{
82
 
  pthread_mutex_init(&proto_cache_mutex, NULL);
83
82
}
84
83
 
85
84
StorageEngine::~StorageEngine()
86
85
{
87
 
  pthread_mutex_destroy(&proto_cache_mutex);
88
86
}
89
87
 
90
88
void StorageEngine::setTransactionReadWrite(Session& session)
93
91
  statement_ctx.markModifiedNonTransData();
94
92
}
95
93
 
96
 
int StorageEngine::doRenameTable(Session *,
97
 
                                 const char *from,
98
 
                                 const char *to)
 
94
 
 
95
int StorageEngine::renameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
99
96
{
100
 
  int error= 0;
101
 
  for (const char **ext= bas_ext(); *ext ; ext++)
102
 
  {
103
 
    if (rename_file_ext(from, to, *ext))
104
 
    {
105
 
      if ((error=errno) != ENOENT)
106
 
        break;
107
 
      error= 0;
108
 
    }
109
 
  }
110
 
  return error;
 
97
  setTransactionReadWrite(session);
 
98
 
 
99
  return doRenameTable(session, from, to);
111
100
}
112
101
 
113
 
 
114
102
/**
115
103
  Delete all files with extension from bas_ext().
116
104
 
140
128
    if (internal::my_delete_with_symlink(buff, MYF(0)))
141
129
    {
142
130
      if ((error= errno) != ENOENT)
143
 
        break;
 
131
        break;
144
132
    }
145
133
    else
146
134
      enoent_or_zero= 0;                        // No error for ENOENT
184
172
class FindEngineByName
185
173
  : public unary_function<StorageEngine *, bool>
186
174
{
187
 
  const string target;
 
175
  const string &target;
 
176
 
188
177
public:
189
 
  explicit FindEngineByName(const string target_arg)
190
 
    : target(target_arg)
191
 
  {}
 
178
  explicit FindEngineByName(const string &target_arg) :
 
179
    target(target_arg)
 
180
  {
 
181
  }
192
182
  result_type operator() (argument_type engine)
193
183
  {
194
184
    string engine_name(engine->getName());
199
189
  }
200
190
};
201
191
 
202
 
StorageEngine *StorageEngine::findByName(string find_str)
 
192
StorageEngine *StorageEngine::findByName(const string &find_str)
203
193
{
204
 
  transform(find_str.begin(), find_str.end(),
205
 
            find_str.begin(), ::tolower);
 
194
  string search_string(find_str);
 
195
  transform(search_string.begin(), search_string.end(),
 
196
            search_string.begin(), ::tolower);
206
197
 
207
198
  
208
199
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
209
200
                                       vector_of_engines.end(),
210
 
                                       FindEngineByName(find_str));
 
201
                                       FindEngineByName(search_string));
211
202
  if (iter != vector_of_engines.end())
212
203
  {
213
204
    StorageEngine *engine= *iter;
218
209
  return NULL;
219
210
}
220
211
 
221
 
StorageEngine *StorageEngine::findByName(Session& session,
222
 
                                                         string find_str)
 
212
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
223
213
{
224
 
  
225
 
  transform(find_str.begin(), find_str.end(),
226
 
            find_str.begin(), ::tolower);
 
214
  string search_string(find_str);
 
215
  transform(search_string.begin(), search_string.end(),
 
216
            search_string.begin(), ::tolower);
227
217
 
228
 
  if (find_str.compare("default") == 0)
 
218
  if (search_string.compare("default") == 0)
229
219
    return session.getDefaultStorageEngine();
230
220
 
231
221
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
232
222
                                       vector_of_engines.end(),
233
 
                                       FindEngineByName(find_str));
 
223
                                       FindEngineByName(search_string));
234
224
  if (iter != vector_of_engines.end())
235
225
  {
236
226
    StorageEngine *engine= *iter;
241
231
  return NULL;
242
232
}
243
233
 
244
 
class StorageEngineCloseConnection
245
 
: public unary_function<StorageEngine *, void>
 
234
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
246
235
{
247
236
  Session *session;
248
237
public:
290
279
  Session& session;
291
280
  TableIdentifier &identifier;
292
281
  message::Table &table_message;
293
 
  int *err;
 
282
  int &err;
294
283
 
295
284
public:
296
285
  StorageEngineGetTableDefinition(Session& session_arg,
297
286
                                  TableIdentifier &identifier_arg,
298
287
                                  message::Table &table_message_arg,
299
 
                                  int *err_arg) :
 
288
                                  int &err_arg) :
300
289
    session(session_arg), 
301
290
    identifier(identifier_arg),
302
291
    table_message(table_message_arg), 
309
298
                                          table_message);
310
299
 
311
300
    if (ret != ENOENT)
312
 
      *err= ret;
 
301
      err= ret;
313
302
 
314
 
    return *err == EEXIST || *err != ENOENT;
 
303
    return err == EEXIST || err != ENOENT;
315
304
  }
316
305
};
317
306
 
384
373
 
385
374
  EngineVector::iterator iter=
386
375
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
387
 
            StorageEngineGetTableDefinition(session, identifier, table_message, &err));
 
376
            StorageEngineGetTableDefinition(session, identifier, table_message, err));
388
377
 
389
378
  if (iter == vector_of_engines.end())
390
379
  {
442
431
 
443
432
  result_type operator() (argument_type engine)
444
433
  {
445
 
    // @todo someday check that at least one engine said "true"
446
 
    std::string path(identifier.getPath());
447
 
    bool success= engine->doDropTable(session, identifier, path);
 
434
    bool success= engine->doDropTable(session, identifier);
448
435
 
449
436
    if (success)
450
437
      success_count++;
478
465
  {
479
466
    std::string path(identifier.getPath());
480
467
    engine->setTransactionReadWrite(session);
481
 
    error= engine->doDropTable(session, identifier, path);
 
468
    error= engine->doDropTable(session, identifier);
482
469
 
483
470
    if (not error)
484
471
    {
505
492
   0  ok
506
493
  @retval
507
494
   1  error
508
 
 
509
 
   @todo refactor to remove goto
510
495
*/
511
 
int StorageEngine::createTable(Session& session,
 
496
int StorageEngine::createTable(Session &session,
512
497
                               TableIdentifier &identifier,
513
498
                               bool update_create_info,
514
499
                               message::Table& table_message)
518
503
  TableShare share(identifier.getDBName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
519
504
  message::Table tmp_proto;
520
505
 
521
 
  if (parse_table_proto(session, table_message, &share))
522
 
    goto err;
523
 
 
524
 
  if (open_table_from_share(&session, &share, "", 0, 0,
525
 
                            &table))
526
 
    goto err;
527
 
 
528
 
  if (update_create_info)
529
 
    table.updateCreateInfo(&table_message);
530
 
 
531
 
  /* Check for legal operations against the Engine using the proto (if used) */
532
 
  if (table_message.type() == message::Table::TEMPORARY &&
533
 
      share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
534
 
  {
535
 
    error= HA_ERR_UNSUPPORTED;
536
 
    goto err2;
537
 
  }
538
 
  else if (table_message.type() != message::Table::TEMPORARY &&
539
 
           share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true)
540
 
  {
541
 
    error= HA_ERR_UNSUPPORTED;
542
 
    goto err2;
543
 
  }
544
 
 
545
 
  {
546
 
    if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
547
 
    {
548
 
      int protoerr= StorageEngine::writeDefinitionFromPath(identifier, table_message);
549
 
 
550
 
      if (protoerr)
551
 
      {
552
 
        error= protoerr;
553
 
        goto err2;
554
 
      }
555
 
    }
556
 
 
557
 
    share.storage_engine->setTransactionReadWrite(session);
558
 
 
559
 
    error= share.storage_engine->doCreateTable(&session,
560
 
                                               table,
561
 
                                               identifier,
562
 
                                               table_message);
563
 
  }
564
 
 
565
 
err2:
566
 
  if (error)
567
 
  {
568
 
    if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
569
 
      plugin::StorageEngine::deleteDefinitionFromPath(identifier);
570
 
 
571
 
    my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
572
 
  }
573
 
 
574
 
  table.closefrm(false);
575
 
 
576
 
err:
 
506
  if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
 
507
  { 
 
508
    // @note Error occured, we should probably do a little more here.
 
509
  }
 
510
  else
 
511
  {
 
512
    if (update_create_info)
 
513
      table.updateCreateInfo(&table_message);
 
514
 
 
515
    /* Check for legal operations against the Engine using the proto (if used) */
 
516
    if (table_message.type() == message::Table::TEMPORARY &&
 
517
        share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
 
518
    {
 
519
      error= HA_ERR_UNSUPPORTED;
 
520
    }
 
521
    else if (table_message.type() != message::Table::TEMPORARY &&
 
522
             share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true)
 
523
    {
 
524
      error= HA_ERR_UNSUPPORTED;
 
525
    }
 
526
    else
 
527
    {
 
528
      bool do_create= true;
 
529
      if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
 
530
      {
 
531
        int protoerr= StorageEngine::writeDefinitionFromPath(identifier, table_message);
 
532
 
 
533
        if (protoerr)
 
534
        {
 
535
          error= protoerr;
 
536
          do_create= false;
 
537
        }
 
538
      }
 
539
 
 
540
      if (do_create)
 
541
      {
 
542
        share.storage_engine->setTransactionReadWrite(session);
 
543
 
 
544
        error= share.storage_engine->doCreateTable(&session,
 
545
                                                   table,
 
546
                                                   identifier,
 
547
                                                   table_message);
 
548
      }
 
549
    }
 
550
 
 
551
    if (error)
 
552
    {
 
553
      if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
 
554
        plugin::StorageEngine::deleteDefinitionFromPath(identifier);
 
555
 
 
556
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
 
557
    }
 
558
 
 
559
    table.closefrm(false);
 
560
  }
 
561
 
577
562
  share.free_table_share();
578
563
  return(error != 0);
579
564
}
862
847
         iter++)
863
848
    {
864
849
      TableIdentifier dummy((*iter).c_str());
865
 
      int error= engine->doDropTable(session, dummy, *iter);
 
850
      int error= engine->doDropTable(session, dummy);
866
851
 
867
852
      // On a return of zero we know we found and deleted the table. So we
868
853
      // remove it from our search.
1222
1207
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1223
1208
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1224
1209
 
 
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;
 
1240
 
 
1241
  dest.copyToTableMessage(table_message);
 
1242
 
 
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)
 
1247
  {
 
1248
    perror(src_path.c_str());
 
1249
    return error;
 
1250
  }
 
1251
 
1225
1252
  return internal::my_rename(src_path.c_str(), dest_path.c_str(), MYF(MY_WME));
1226
1253
}
1227
1254
 
1234
1261
  int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, internal::my_umask);
1235
1262
 
1236
1263
  if (fd == -1)
 
1264
  {
 
1265
    perror(file_name.c_str());
1237
1266
    return errno;
 
1267
  }
1238
1268
 
1239
1269
  google::protobuf::io::ZeroCopyOutputStream* output=
1240
1270
    new google::protobuf::io::FileOutputStream(fd);
1243
1273
  {
1244
1274
    delete output;
1245
1275
    close(fd);
 
1276
    perror(file_name.c_str());
1246
1277
    return errno;
1247
1278
  }
1248
1279
 
1249
1280
  delete output;
1250
1281
  close(fd);
 
1282
 
1251
1283
  return 0;
1252
1284
}
1253
1285