~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Mark Atwood
  • Date: 2011-08-09 01:21:52 UTC
  • mfrom: (2380.1.2 drizzle-autoconf)
  • Revision ID: me@mark.atwood.name-20110809012152-zxq2dgan8e6nsvse
merge lp:~brianaker/drizzle/autoreconf

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include "config.h"
 
20
#include <config.h>
21
21
 
22
22
#include <fcntl.h>
23
23
#include <unistd.h>
32
32
#include <google/protobuf/io/zero_copy_stream.h>
33
33
#include <google/protobuf/io/zero_copy_stream_impl.h>
34
34
 
35
 
#include "drizzled/cached_directory.h"
36
 
 
 
35
#include <drizzled/cached_directory.h>
37
36
#include <drizzled/definitions.h>
38
37
#include <drizzled/base.h>
39
38
#include <drizzled/cursor.h>
41
40
#include <drizzled/session.h>
42
41
#include <drizzled/error.h>
43
42
#include <drizzled/gettext.h>
44
 
#include <drizzled/unireg.h>
45
43
#include <drizzled/data_home.h>
46
 
#include "drizzled/errmsg_print.h"
47
 
#include "drizzled/xid.h"
48
 
#include "drizzled/sql_table.h"
49
 
#include "drizzled/global_charset_info.h"
50
 
#include "drizzled/charset.h"
51
 
#include "drizzled/internal/my_sys.h"
52
 
#include "drizzled/db.h"
53
 
 
 
44
#include <drizzled/errmsg_print.h>
 
45
#include <drizzled/xid.h>
 
46
#include <drizzled/sql_table.h>
 
47
#include <drizzled/charset.h>
 
48
#include <drizzled/internal/my_sys.h>
54
49
#include <drizzled/table_proto.h>
55
50
#include <drizzled/plugin/event_observer.h>
56
 
 
57
51
#include <drizzled/table/shell.h>
58
 
 
59
 
#include "drizzled/message/cache.h"
 
52
#include <drizzled/message/cache.h>
 
53
#include <drizzled/key.h>
 
54
#include <drizzled/session/transactions.h>
 
55
#include <drizzled/open_tables_state.h>
60
56
 
61
57
#include <boost/algorithm/string/compare.hpp>
62
58
 
63
59
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
64
60
 
65
 
namespace drizzled
66
 
{
67
 
 
68
 
namespace plugin
69
 
{
70
 
 
71
 
static EngineVector vector_of_engines;
72
 
static EngineVector vector_of_schema_engines;
 
61
namespace drizzled {
 
62
namespace plugin {
 
63
 
 
64
static EngineVector g_engines;
 
65
static EngineVector g_schema_engines;
73
66
 
74
67
const std::string DEFAULT_STRING("default");
75
68
const std::string UNKNOWN_STRING("UNKNOWN");
79
72
 
80
73
EngineVector &StorageEngine::getSchemaEngines()
81
74
{
82
 
  return vector_of_schema_engines;
 
75
  return g_schema_engines;
83
76
}
84
77
 
85
 
StorageEngine::StorageEngine(const std::string name_arg,
 
78
StorageEngine::StorageEngine(const std::string &name_arg,
86
79
                             const std::bitset<HTON_BIT_SIZE> &flags_arg) :
87
80
  Plugin(name_arg, "StorageEngine"),
88
81
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
100
93
  statement_ctx.markModifiedNonTransData();
101
94
}
102
95
 
103
 
 
104
96
int StorageEngine::renameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
105
97
{
106
 
  int error;
107
98
  setTransactionReadWrite(session);
108
 
 
109
99
  if (unlikely(plugin::EventObserver::beforeRenameTable(session, from, to)))
110
 
  {
 
100
    return ER_EVENT_OBSERVER_PLUGIN;
 
101
  int error= doRenameTable(session, from, to);
 
102
  if (unlikely(plugin::EventObserver::afterRenameTable(session, from, to, error)))
111
103
    error= ER_EVENT_OBSERVER_PLUGIN;
112
 
  }
113
 
  else
114
 
  {
115
 
    error =  doRenameTable(session, from, to);
116
 
    if (unlikely(plugin::EventObserver::afterRenameTable(session, from, to, error)))
117
 
    {
118
 
      error= ER_EVENT_OBSERVER_PLUGIN;
119
 
    }
120
 
  }
121
 
  
122
104
  return error;
123
105
}
124
106
 
138
120
    !0  Error
139
121
*/
140
122
int StorageEngine::doDropTable(Session&, const identifier::Table &identifier)
141
 
                               
142
123
{
143
124
  int error= 0;
144
125
  int enoent_or_zero= ENOENT;                   // Error if no file was deleted
165
146
 
166
147
bool StorageEngine::addPlugin(StorageEngine *engine)
167
148
{
168
 
 
169
 
  vector_of_engines.push_back(engine);
 
149
  g_engines.push_back(engine);
170
150
 
171
151
  if (engine->getTableDefinitionFileExtension().length())
172
152
  {
175
155
  }
176
156
 
177
157
  if (engine->check_flag(HTON_BIT_SCHEMA_DICTIONARY))
178
 
    vector_of_schema_engines.push_back(engine);
 
158
    g_schema_engines.push_back(engine);
179
159
 
180
160
  return false;
181
161
}
182
162
 
183
163
void StorageEngine::removePlugin(StorageEngine *)
184
164
{
185
 
  if (shutdown_has_begun == false)
186
 
  {
187
 
    vector_of_engines.clear();
188
 
    vector_of_schema_engines.clear();
189
 
 
190
 
    shutdown_has_begun= true;
191
 
  }
 
165
  if (shutdown_has_begun)
 
166
    return;
 
167
  shutdown_has_begun= true;
 
168
  g_engines.clear();
 
169
  g_schema_engines.clear();
192
170
}
193
171
 
194
 
class FindEngineByName
195
 
  : public std::unary_function<StorageEngine *, bool>
196
 
{
197
 
  const std::string &predicate;
198
 
 
199
 
public:
200
 
  explicit FindEngineByName(const std::string &target_arg) :
201
 
    predicate(target_arg)
202
 
  {
203
 
  }
204
 
 
205
 
  result_type operator() (argument_type engine)
206
 
  {
207
 
    return boost::iequals(engine->getName(), predicate);
208
 
  }
209
 
};
210
 
 
211
172
StorageEngine *StorageEngine::findByName(const std::string &predicate)
212
173
{
213
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
 
                                            vector_of_engines.end(),
215
 
                                            FindEngineByName(predicate));
216
 
  if (iter != vector_of_engines.end())
 
174
  BOOST_FOREACH(EngineVector::reference it, g_engines)
217
175
  {
218
 
    StorageEngine *engine= *iter;
219
 
    if (engine->is_user_selectable())
220
 
      return engine;
 
176
    if (not boost::iequals(it->getName(), predicate))
 
177
      continue;
 
178
    if (it->is_user_selectable())
 
179
      return it;
 
180
    break;
221
181
  }
222
 
 
223
182
  return NULL;
224
183
}
225
184
 
227
186
{
228
187
  if (boost::iequals(predicate, DEFAULT_STRING))
229
188
    return session.getDefaultStorageEngine();
230
 
 
231
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
 
                                            vector_of_engines.end(),
233
 
                                            FindEngineByName(predicate));
234
 
  if (iter != vector_of_engines.end())
235
 
  {
236
 
    StorageEngine *engine= *iter;
237
 
    if (engine->is_user_selectable())
238
 
      return engine;
239
 
  }
240
 
 
241
 
  return NULL;
 
189
  return findByName(predicate);
242
190
}
243
191
 
244
 
class StorageEngineCloseConnection : public std::unary_function<StorageEngine *, void>
245
 
{
246
 
  Session *session;
247
 
public:
248
 
  StorageEngineCloseConnection(Session *session_arg) : session(session_arg) {}
249
 
  /*
250
 
    there's no need to rollback here as all transactions must
251
 
    be rolled back already
252
 
  */
253
 
  inline result_type operator() (argument_type engine)
254
 
  {
255
 
    if (*session->getEngineData(engine))
256
 
      engine->close_connection(session);
257
 
  }
258
 
};
259
 
 
260
192
/**
261
193
  @note
262
194
    don't bother to rollback here, it's done already
263
195
*/
264
 
void StorageEngine::closeConnection(Session* session)
 
196
void StorageEngine::closeConnection(Session& session)
265
197
{
266
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
 
                StorageEngineCloseConnection(session));
 
198
  BOOST_FOREACH(EngineVector::reference it, g_engines)
 
199
  {
 
200
    if (*session.getEngineData(it))
 
201
      it->close_connection(&session);
 
202
  }
268
203
}
269
204
 
270
205
bool StorageEngine::flushLogs(StorageEngine *engine)
271
206
{
272
 
  if (engine == NULL)
273
 
  {
274
 
    if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
 
                     std::mem_fun(&StorageEngine::flush_logs))
276
 
        != vector_of_engines.begin())
277
 
      return true;
278
 
  }
279
 
  else
280
 
  {
281
 
    if (engine->flush_logs())
282
 
      return true;
283
 
  }
 
207
  if (not engine)
 
208
  {
 
209
    if (std::find_if(g_engines.begin(), g_engines.end(), std::mem_fun(&StorageEngine::flush_logs))
 
210
        != g_engines.begin()) // Shouldn't this be .end()?
 
211
      return true;
 
212
  }
 
213
  else if (engine->flush_logs())
 
214
    return true;
284
215
  return false;
285
216
}
286
217
 
312
243
  }
313
244
};
314
245
 
315
 
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
316
 
{
317
 
  Session& session;
318
 
  const identifier::Table &identifier;
319
 
 
320
 
public:
321
 
  StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
322
 
    session(session_arg), 
323
 
    identifier(identifier_arg) 
324
 
  { }
325
 
 
326
 
  result_type operator() (argument_type engine)
327
 
  {
328
 
    return engine->doDoesTableExist(session, identifier);
329
 
  }
330
 
};
331
 
 
332
246
/**
333
247
  Utility method which hides some of the details of getTableDefinition()
334
248
*/
336
250
                                           const identifier::Table &identifier,
337
251
                                           bool include_temporary_tables)
338
252
{
339
 
  if (include_temporary_tables)
340
 
  {
341
 
    if (session.doDoesTableExist(identifier))
342
 
      return true;
343
 
  }
344
 
 
345
 
  EngineVector::iterator iter=
346
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
 
                 StorageEngineDoesTableExist(session, identifier));
348
 
 
349
 
  if (iter == vector_of_engines.end())
350
 
  {
351
 
    return false;
352
 
  }
353
 
 
354
 
  return true;
 
253
  if (include_temporary_tables && session.open_tables.doDoesTableExist(identifier))
 
254
      return true;
 
255
  BOOST_FOREACH(EngineVector::reference it, g_engines)
 
256
  {
 
257
    if (it->doDoesTableExist(session, identifier))
 
258
      return true;
 
259
  }
 
260
  return false;
355
261
}
356
262
 
357
263
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
361
267
  return false;
362
268
}
363
269
 
364
 
/**
365
 
  Call this function in order to give the Cursor the possiblity
366
 
  to ask engine if there are any new tables that should be written to disk
367
 
  or any dropped tables that need to be removed from disk
368
 
*/
369
 
int StorageEngine::getTableDefinition(Session& session,
370
 
                                      const identifier::Table &identifier,
371
 
                                      message::table::shared_ptr &table_message,
372
 
                                      bool include_temporary_tables)
373
 
{
374
 
  drizzled::error_t err= static_cast<drizzled::error_t>(ENOENT);
375
 
 
376
 
  if (include_temporary_tables)
377
 
  {
378
 
    Table *table= session.find_temporary_table(identifier);
379
 
    if (table)
380
 
    {
381
 
      table_message.reset(new message::Table(*table->getShare()->getTableMessage()));
382
 
      return EEXIST;
383
 
    }
384
 
  }
385
 
 
386
 
  drizzled::message::table::shared_ptr table_ptr;
387
 
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
388
 
  {
389
 
    table_message= table_ptr;
390
 
  }
391
 
 
392
 
  message::Table message;
393
 
  EngineVector::iterator iter=
394
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
395
 
                 StorageEngineGetTableDefinition(session, identifier, message, err));
396
 
 
397
 
  if (iter == vector_of_engines.end())
398
 
  {
399
 
    return ENOENT;
400
 
  }
401
 
  table_message.reset(new message::Table(message));
402
 
 
403
 
 drizzled::message::Cache::singleton().insert(identifier, table_message);
404
 
 
405
 
  return err;
406
 
}
407
 
 
408
270
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
409
 
                                                          identifier::Table::const_reference identifier,
410
 
                                                          drizzled::error_t &error,
 
271
                                                          const identifier::Table& identifier,
411
272
                                                          bool include_temporary_tables)
412
273
{
413
 
  error= static_cast<drizzled::error_t>(ENOENT);
414
 
 
 
274
  drizzled::error_t error= static_cast<drizzled::error_t>(ENOENT);
415
275
  if (include_temporary_tables)
416
276
  {
417
 
    Table *table= session.find_temporary_table(identifier);
418
 
    if (table)
 
277
    if (Table *table= session.open_tables.find_temporary_table(identifier))
419
278
    {
420
 
      error= EE_OK;
421
279
      return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
422
280
    }
423
281
  }
430
288
 
431
289
  message::Table message;
432
290
  EngineVector::iterator iter=
433
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
291
    std::find_if(g_engines.begin(), g_engines.end(),
434
292
                 StorageEngineGetTableDefinition(session, identifier, message, error));
435
293
 
436
 
  if (iter == vector_of_engines.end())
 
294
  if (iter == g_engines.end())
437
295
  {
438
 
    error= static_cast<drizzled::error_t>(ENOENT);
439
296
    return message::table::shared_ptr();
440
297
  }
441
298
  message::table::shared_ptr table_message(new message::Table(message));
445
302
  return table_message;
446
303
}
447
304
 
448
 
/**
449
 
  An interceptor to hijack the text of the error message without
450
 
  setting an error in the thread. We need the text to present it
451
 
  in the form of a warning to the user.
452
 
*/
453
 
 
454
 
class Ha_delete_table_error_handler: public Internal_error_handler
455
 
{
456
 
public:
457
 
  Ha_delete_table_error_handler() : Internal_error_handler() {}
458
 
  virtual bool handle_error(drizzled::error_t sql_errno,
459
 
                            const char *message,
460
 
                            DRIZZLE_ERROR::enum_warning_level level,
461
 
                            Session *session);
462
 
  char buff[DRIZZLE_ERRMSG_SIZE];
463
 
};
464
 
 
465
 
 
466
 
bool
467
 
Ha_delete_table_error_handler::
468
 
handle_error(drizzled::error_t ,
469
 
             const char *message,
470
 
             DRIZZLE_ERROR::enum_warning_level ,
471
 
             Session *)
472
 
{
473
 
  /* Grab the error message */
474
 
  strncpy(buff, message, sizeof(buff)-1);
475
 
  return true;
476
 
}
477
 
 
478
305
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
479
306
{
480
 
  Session::reference session;
481
 
  identifier::Table::const_reference identifier;
 
307
  Session& session;
 
308
  const identifier::Table& identifier;
482
309
  drizzled::error_t &error;
483
310
 
484
311
public:
485
312
 
486
 
  DropTableByIdentifier(Session::reference session_arg,
487
 
                        identifier::Table::const_reference identifier_arg,
 
313
  DropTableByIdentifier(Session& session_arg,
 
314
                        const identifier::Table& identifier_arg,
488
315
                        drizzled::error_t &error_arg) :
489
316
    session(session_arg),
490
317
    identifier(identifier_arg),
517
344
};
518
345
 
519
346
 
520
 
bool StorageEngine::dropTable(Session::reference session,
521
 
                              identifier::Table::const_reference identifier,
 
347
bool StorageEngine::dropTable(Session& session,
 
348
                              const identifier::Table& identifier,
522
349
                              drizzled::error_t &error)
523
350
{
524
351
  error= EE_OK;
525
352
 
526
 
  EngineVector::const_iterator iter= std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
353
  EngineVector::const_iterator iter= std::find_if(g_engines.begin(), g_engines.end(),
527
354
                                                  DropTableByIdentifier(session, identifier, error));
528
355
 
529
356
  if (error)
530
357
  {
531
358
    return false;
532
359
  }
533
 
  else if (iter == vector_of_engines.end())
 
360
  else if (iter == g_engines.end())
534
361
  {
535
362
    error= ER_BAD_TABLE_ERROR;
536
363
    return false;
545
372
                              const identifier::Table &identifier)
546
373
{
547
374
  drizzled::error_t error;
548
 
 
549
 
  if (not dropTable(session, identifier, error))
550
 
  {
551
 
    return false;
552
 
  }
553
 
 
554
 
  return true;
 
375
  return dropTable(session, identifier, error);
555
376
}
556
377
 
557
 
bool StorageEngine::dropTable(Session::reference session,
 
378
bool StorageEngine::dropTable(Session& session,
558
379
                              StorageEngine &engine,
559
 
                              identifier::Table::const_reference identifier,
 
380
                              const identifier::Table& identifier,
560
381
                              drizzled::error_t &error)
561
382
{
562
383
  error= EE_OK;
577
398
      error= ER_EVENT_OBSERVER_PLUGIN;
578
399
    }
579
400
  }
580
 
 
581
401
  drizzled::message::Cache::singleton().erase(identifier);
582
 
 
583
 
  if (error)
584
 
  {
585
 
    return false;
586
 
  }
587
 
 
588
 
  return true;
 
402
  return not error;
589
403
}
590
404
 
591
405
 
640
454
    }
641
455
 
642
456
    if (error == ER_TABLE_PERMISSION_DENIED)
643
 
    {
644
457
      my_error(ER_TABLE_PERMISSION_DENIED, identifier);
645
 
    }
646
458
    else if (error)
647
 
    {
648
 
      std::string path;
649
 
      identifier.getSQLPath(path);
650
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
651
 
    }
652
 
 
 
459
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
653
460
    table.delete_table();
654
461
  }
655
 
 
656
462
  return(error == EE_OK);
657
463
}
658
464
 
661
467
  return create(arg);
662
468
}
663
469
 
664
 
class AddTableIdentifier : 
665
 
  public std::unary_function<StorageEngine *, void>
666
 
{
667
 
  CachedDirectory &directory;
668
 
  const identifier::Schema &identifier;
669
 
  identifier::Table::vector &set_of_identifiers;
670
 
 
671
 
public:
672
 
 
673
 
  AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
674
 
    directory(directory_arg),
675
 
    identifier(identifier_arg),
676
 
    set_of_identifiers(of_names)
677
 
  {
678
 
  }
679
 
 
680
 
  result_type operator() (argument_type engine)
681
 
  {
682
 
    engine->doGetTableIdentifiers(directory, identifier, set_of_identifiers);
683
 
  }
684
 
};
685
 
 
686
 
 
687
 
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
 
470
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::table::vector &set_of_identifiers)
688
471
{
689
472
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
690
473
 
691
474
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
692
 
  { }
 
475
  { 
 
476
        }
693
477
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
694
 
  { }
695
 
  else
 
478
  { 
 
479
        }
 
480
  else if (directory.fail())
696
481
  {
697
 
    if (directory.fail())
698
 
    {
699
 
      errno= directory.getError();
700
 
      if (errno == ENOENT)
701
 
      {
702
 
        std::string path;
703
 
        schema_identifier.getSQLPath(path);
704
 
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
705
 
      }
706
 
      else
707
 
      {
708
 
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
709
 
      }
710
 
 
711
 
      return;
712
 
    }
 
482
    errno= directory.getError();
 
483
    if (errno == ENOENT)
 
484
      my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
 
485
    else
 
486
      my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
 
487
    return;
713
488
  }
714
489
 
715
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
716
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
 
490
  BOOST_FOREACH(EngineVector::reference it, g_engines)
 
491
    it->doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
717
492
 
718
 
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
 
493
  session.open_tables.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
719
494
}
720
495
 
721
496
class DropTable: public std::unary_function<identifier::Table&, bool>
736
511
  } 
737
512
};
738
513
 
739
 
/* This will later be converted to identifier::Tables */
740
 
class DropTables: public std::unary_function<StorageEngine *, void>
741
 
{
742
 
  Session &session;
743
 
  identifier::Table::vector &table_identifiers;
744
 
 
745
 
public:
746
 
 
747
 
  DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
748
 
    session(session_arg),
749
 
    table_identifiers(table_identifiers_arg)
750
 
  { }
751
 
 
752
 
  result_type operator() (argument_type engine)
753
 
  {
754
 
    // True returning from DropTable means the table has been successfully
755
 
    // deleted, so it should be removed from the list of tables to drop
756
 
    table_identifiers.erase(std::remove_if(table_identifiers.begin(),
757
 
                                           table_identifiers.end(),
758
 
                                           DropTable(session, engine)),
759
 
                            table_identifiers.end());
760
 
  }
761
 
};
762
 
 
763
514
/*
764
515
  This only works for engines which use file based DFE.
765
516
 
768
519
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
769
520
{
770
521
  CachedDirectory dir(directory, set_of_table_definition_ext);
771
 
  identifier::Table::vector table_identifiers;
 
522
  identifier::table::vector table_identifiers;
772
523
 
773
524
  if (dir.fail())
774
525
  {
802
553
    }
803
554
  }
804
555
 
805
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
806
 
                DropTables(session, table_identifiers));
 
556
  BOOST_FOREACH(EngineVector::reference it, g_engines)
 
557
  {
 
558
    table_identifiers.erase(std::remove_if(table_identifiers.begin(), table_identifiers.end(), DropTable(session, it)),
 
559
      table_identifiers.end());
 
560
  }
807
561
 
808
562
  /*
809
563
    Now we just clean up anything that might left over.
813
567
  */
814
568
  std::set<std::string> all_exts= set_of_table_definition_ext;
815
569
 
816
 
  for (EngineVector::iterator iter= vector_of_engines.begin();
817
 
       iter != vector_of_engines.end() ; iter++)
 
570
  for (EngineVector::iterator iter= g_engines.begin();
 
571
       iter != g_engines.end() ; iter++)
818
572
  {
819
573
    for (const char **ext= (*iter)->bas_ext(); *ext ; ext++)
820
574
      all_exts.insert(*ext);
965
719
  {
966
720
    String str;
967
721
    get_error_message(error, &str);
968
 
    my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe());
 
722
    my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_str());
969
723
    return;
970
724
  }
971
725
  case HA_ERR_NO_REFERENCED_ROW:
972
726
  {
973
727
    String str;
974
728
    get_error_message(error, &str);
975
 
    my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe());
 
729
    my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_str());
976
730
    return;
977
731
  }
978
732
  case HA_ERR_TABLE_DEF_CHANGED:
1009
763
    textno= ER_WARN_DATA_OUT_OF_RANGE;
1010
764
    break;
1011
765
  case HA_ERR_LOCK_OR_ACTIVE_TRANSACTION:
1012
 
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1013
 
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
766
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1014
767
    return;
1015
768
  default:
1016
769
    {
1021
774
      bool temporary= false;
1022
775
      String str;
1023
776
      temporary= get_error_message(error, &str);
1024
 
      if (!str.is_empty())
 
777
      if (!str.empty())
1025
778
      {
1026
779
        const char* engine_name= getName().c_str();
1027
780
        if (temporary)
1028
 
          my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(),
1029
 
                   engine_name);
 
781
          my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine_name);
1030
782
        else
1031
783
          my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine_name);
1032
784
      }
1123
875
  return error;
1124
876
}
1125
877
 
1126
 
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, message::Table &table_message)
 
878
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, const message::Table &table_message)
1127
879
{
1128
880
  char definition_file_tmp[FN_REFLEN];
1129
881
  std::string file_name(identifier.getPath());
1156
908
 
1157
909
  if (not success)
1158
910
  {
1159
 
    std::string error_message;
1160
 
    identifier.getSQLPath(error_message);
1161
 
 
1162
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1163
 
             error_message.c_str(),
1164
 
             table_message.InitializationErrorString().c_str());
 
911
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), identifier.getSQLPath().c_str(), table_message.InitializationErrorString().c_str());
1165
912
    delete output;
1166
913
 
1167
914
    if (close(fd) == -1)
1200
947
  return 0;
1201
948
}
1202
949
 
1203
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
1204
 
{
1205
 
  const identifier::Table &identifier;
1206
 
 
1207
 
public:
1208
 
  CanCreateTable(const identifier::Table &identifier_arg) :
1209
 
    identifier(identifier_arg)
1210
 
  { }
1211
 
 
1212
 
  result_type operator() (argument_type engine)
1213
 
  {
1214
 
    return not engine->doCanCreateTable(identifier);
1215
 
  }
1216
 
};
1217
 
 
1218
 
 
1219
950
/**
1220
951
  @note on success table can be created.
1221
952
*/
1222
953
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
1223
954
{
1224
 
  EngineVector::iterator iter=
1225
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1226
 
                 CanCreateTable(identifier));
1227
 
 
1228
 
  if (iter == vector_of_engines.end())
 
955
  BOOST_FOREACH(EngineVector::reference it, g_engines)
1229
956
  {
1230
 
    return true;
 
957
    if (not it->doCanCreateTable(identifier))
 
958
      return false;
1231
959
  }
1232
 
 
1233
 
  return false;
 
960
  return true;
1234
961
}
1235
962
 
1236
963
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1262
989
 
1263
990
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine)
1264
991
{
1265
 
  output << "StorageEngine:(";
1266
 
  output <<  engine.getName();
1267
 
  output << ")";
1268
 
 
1269
 
  return output;
 
992
  return output << "StorageEngine:(" <<  engine.getName() << ")";
1270
993
}
1271
994
 
1272
995
} /* namespace plugin */