~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Patrick Crews
  • Date: 2010-09-14 20:21:03 UTC
  • mto: (1771.1.1 pcrews)
  • mto: This revision was merged to the branch mainline in revision 1772.
  • Revision ID: gleebix@gmail.com-20100914202103-1db2n0bshzafep19
Moved transaction_log tests into updated non-publisher-based tree

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
54
54
#include <drizzled/table_proto.h>
55
55
#include <drizzled/plugin/event_observer.h>
56
56
 
57
 
#include <drizzled/table/shell.h>
58
 
 
59
 
#include "drizzled/message/cache.h"
60
 
 
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
 
 
61
using namespace std;
 
62
 
65
63
namespace drizzled
66
64
{
67
65
 
82
80
  return vector_of_schema_engines;
83
81
}
84
82
 
85
 
StorageEngine::StorageEngine(const std::string name_arg,
86
 
                             const std::bitset<HTON_BIT_SIZE> &flags_arg) :
 
83
StorageEngine::StorageEngine(const string name_arg,
 
84
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
87
85
  Plugin(name_arg, "StorageEngine"),
88
86
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
89
87
  flags(flags_arg)
101
99
}
102
100
 
103
101
 
104
 
int StorageEngine::renameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
102
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
105
103
{
106
104
  int error;
107
105
  setTransactionReadWrite(session);
137
135
  @retval
138
136
    !0  Error
139
137
*/
140
 
int StorageEngine::doDropTable(Session&, const identifier::Table &identifier)
 
138
int StorageEngine::doDropTable(Session&, const TableIdentifier &identifier)
141
139
                               
142
140
{
143
141
  int error= 0;
192
190
}
193
191
 
194
192
class FindEngineByName
195
 
  : public std::unary_function<StorageEngine *, bool>
 
193
  : public unary_function<StorageEngine *, bool>
196
194
{
197
 
  const std::string &predicate;
 
195
  const string &predicate;
198
196
 
199
197
public:
200
 
  explicit FindEngineByName(const std::string &target_arg) :
 
198
  explicit FindEngineByName(const string &target_arg) :
201
199
    predicate(target_arg)
202
200
  {
203
201
  }
208
206
  }
209
207
};
210
208
 
211
 
StorageEngine *StorageEngine::findByName(const std::string &predicate)
 
209
StorageEngine *StorageEngine::findByName(const string &predicate)
212
210
{
213
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
 
                                            vector_of_engines.end(),
215
 
                                            FindEngineByName(predicate));
 
211
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
212
                                       vector_of_engines.end(),
 
213
                                       FindEngineByName(predicate));
216
214
  if (iter != vector_of_engines.end())
217
215
  {
218
216
    StorageEngine *engine= *iter;
223
221
  return NULL;
224
222
}
225
223
 
226
 
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
 
224
StorageEngine *StorageEngine::findByName(Session& session, const string &predicate)
227
225
{
228
226
  if (boost::iequals(predicate, DEFAULT_STRING))
229
227
    return session.getDefaultStorageEngine();
230
228
 
231
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
 
                                            vector_of_engines.end(),
233
 
                                            FindEngineByName(predicate));
 
229
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
230
                                       vector_of_engines.end(),
 
231
                                       FindEngineByName(predicate));
234
232
  if (iter != vector_of_engines.end())
235
233
  {
236
234
    StorageEngine *engine= *iter;
241
239
  return NULL;
242
240
}
243
241
 
244
 
class StorageEngineCloseConnection : public std::unary_function<StorageEngine *, void>
 
242
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
245
243
{
246
244
  Session *session;
247
245
public:
263
261
*/
264
262
void StorageEngine::closeConnection(Session* session)
265
263
{
266
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
 
                StorageEngineCloseConnection(session));
 
264
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
265
           StorageEngineCloseConnection(session));
268
266
}
269
267
 
270
268
bool StorageEngine::flushLogs(StorageEngine *engine)
271
269
{
272
270
  if (engine == NULL)
273
271
  {
274
 
    if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
 
                     std::mem_fun(&StorageEngine::flush_logs))
 
272
    if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
273
                mem_fun(&StorageEngine::flush_logs))
276
274
        != vector_of_engines.begin())
277
275
      return true;
278
276
  }
284
282
  return false;
285
283
}
286
284
 
287
 
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
 
285
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
288
286
{
289
287
  Session& session;
290
 
  const identifier::Table &identifier;
 
288
  const TableIdentifier &identifier;
291
289
  message::Table &table_message;
292
 
  drizzled::error_t &err;
 
290
  int &err;
293
291
 
294
292
public:
295
293
  StorageEngineGetTableDefinition(Session& session_arg,
296
 
                                  const identifier::Table &identifier_arg,
 
294
                                  const TableIdentifier &identifier_arg,
297
295
                                  message::Table &table_message_arg,
298
 
                                  drizzled::error_t &err_arg) :
 
296
                                  int &err_arg) :
299
297
    session(session_arg), 
300
298
    identifier(identifier_arg),
301
299
    table_message(table_message_arg), 
306
304
    int ret= engine->doGetTableDefinition(session, identifier, table_message);
307
305
 
308
306
    if (ret != ENOENT)
309
 
      err= static_cast<drizzled::error_t>(ret);
 
307
      err= ret;
310
308
 
311
 
    return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
 
309
    return err == EEXIST || err != ENOENT;
312
310
  }
313
311
};
314
312
 
315
 
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
 
313
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
316
314
{
317
315
  Session& session;
318
 
  const identifier::Table &identifier;
 
316
  const TableIdentifier &identifier;
319
317
 
320
318
public:
321
 
  StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
 
319
  StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
322
320
    session(session_arg), 
323
321
    identifier(identifier_arg) 
324
322
  { }
333
331
  Utility method which hides some of the details of getTableDefinition()
334
332
*/
335
333
bool plugin::StorageEngine::doesTableExist(Session &session,
336
 
                                           const identifier::Table &identifier,
 
334
                                           const TableIdentifier &identifier,
337
335
                                           bool include_temporary_tables)
338
336
{
339
337
  if (include_temporary_tables)
343
341
  }
344
342
 
345
343
  EngineVector::iterator iter=
346
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
 
                 StorageEngineDoesTableExist(session, identifier));
 
344
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
345
            StorageEngineDoesTableExist(session, identifier));
348
346
 
349
347
  if (iter == vector_of_engines.end())
350
348
  {
354
352
  return true;
355
353
}
356
354
 
357
 
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
 
355
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
358
356
{
359
 
  std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
 
357
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
360
358
  assert(0);
361
359
  return false;
362
360
}
367
365
  or any dropped tables that need to be removed from disk
368
366
*/
369
367
int StorageEngine::getTableDefinition(Session& session,
370
 
                                      const identifier::Table &identifier,
371
 
                                      message::table::shared_ptr &table_message,
 
368
                                      const TableIdentifier &identifier,
 
369
                                      message::Table &table_message,
372
370
                                      bool include_temporary_tables)
373
371
{
374
 
  drizzled::error_t err= static_cast<drizzled::error_t>(ENOENT);
 
372
  int err= ENOENT;
375
373
 
376
374
  if (include_temporary_tables)
377
375
  {
378
 
    Table *table= session.find_temporary_table(identifier);
379
 
    if (table)
380
 
    {
381
 
      table_message.reset(new message::Table(*table->getShare()->getTableMessage()));
 
376
    if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
382
377
      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;
 
378
  }
 
379
 
393
380
  EngineVector::iterator iter=
394
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
395
 
                 StorageEngineGetTableDefinition(session, identifier, message, err));
 
381
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
382
            StorageEngineGetTableDefinition(session, identifier, table_message, err));
396
383
 
397
384
  if (iter == vector_of_engines.end())
398
385
  {
399
386
    return ENOENT;
400
387
  }
401
 
  table_message.reset(new message::Table(message));
402
 
 
403
 
 drizzled::message::Cache::singleton().insert(identifier, table_message);
404
388
 
405
389
  return err;
406
390
}
407
391
 
408
 
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
409
 
                                                          identifier::Table::const_reference identifier,
410
 
                                                          drizzled::error_t &error,
411
 
                                                          bool include_temporary_tables)
412
 
{
413
 
  error= static_cast<drizzled::error_t>(ENOENT);
414
 
 
415
 
  if (include_temporary_tables)
416
 
  {
417
 
    Table *table= session.find_temporary_table(identifier);
418
 
    if (table)
419
 
    {
420
 
      error= EE_OK;
421
 
      return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
422
 
    }
423
 
  }
424
 
 
425
 
  drizzled::message::table::shared_ptr table_ptr;
426
 
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
427
 
  {
428
 
    (void)table_ptr;
429
 
  }
430
 
 
431
 
  message::Table message;
432
 
  EngineVector::iterator iter=
433
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
434
 
                 StorageEngineGetTableDefinition(session, identifier, message, error));
435
 
 
436
 
  if (iter == vector_of_engines.end())
437
 
  {
438
 
    error= static_cast<drizzled::error_t>(ENOENT);
439
 
    return message::table::shared_ptr();
440
 
  }
441
 
  message::table::shared_ptr table_message(new message::Table(message));
442
 
 
443
 
  drizzled::message::Cache::singleton().insert(identifier, table_message);
444
 
 
445
 
  return table_message;
446
 
}
447
 
 
448
392
/**
449
393
  An interceptor to hijack the text of the error message without
450
394
  setting an error in the thread. We need the text to present it
455
399
{
456
400
public:
457
401
  Ha_delete_table_error_handler() : Internal_error_handler() {}
458
 
  virtual bool handle_error(drizzled::error_t sql_errno,
 
402
  virtual bool handle_error(uint32_t sql_errno,
459
403
                            const char *message,
460
404
                            DRIZZLE_ERROR::enum_warning_level level,
461
405
                            Session *session);
465
409
 
466
410
bool
467
411
Ha_delete_table_error_handler::
468
 
handle_error(drizzled::error_t ,
 
412
handle_error(uint32_t ,
469
413
             const char *message,
470
414
             DRIZZLE_ERROR::enum_warning_level ,
471
415
             Session *)
475
419
  return true;
476
420
}
477
421
 
478
 
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
479
 
{
480
 
  Session::reference session;
481
 
  identifier::Table::const_reference identifier;
482
 
  drizzled::error_t &error;
483
 
 
484
 
public:
485
 
 
486
 
  DropTableByIdentifier(Session::reference session_arg,
487
 
                        identifier::Table::const_reference identifier_arg,
488
 
                        drizzled::error_t &error_arg) :
489
 
    session(session_arg),
490
 
    identifier(identifier_arg),
491
 
    error(error_arg)
492
 
  { }
493
 
 
494
 
  result_type operator() (argument_type engine)
495
 
  {
496
 
    if (not engine->doDoesTableExist(session, identifier))
497
 
      return false;
498
 
 
499
 
    int local_error= engine->doDropTable(session, identifier);
500
 
 
501
 
 
502
 
    if (not local_error)
503
 
      return true;
504
 
 
505
 
    switch (local_error)
506
 
    {
507
 
    case HA_ERR_NO_SUCH_TABLE:
508
 
    case ENOENT:
509
 
      error= static_cast<drizzled::error_t>(HA_ERR_NO_SUCH_TABLE);
510
 
      return false;
511
 
 
512
 
    default:
513
 
      error= static_cast<drizzled::error_t>(local_error);
514
 
      return true;
515
 
    }
516
 
  } 
517
 
};
518
 
 
519
 
 
520
 
bool StorageEngine::dropTable(Session::reference session,
521
 
                              identifier::Table::const_reference identifier,
522
 
                              drizzled::error_t &error)
523
 
{
524
 
  error= EE_OK;
525
 
 
526
 
  EngineVector::const_iterator iter= std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
527
 
                                                  DropTableByIdentifier(session, identifier, error));
528
 
 
529
 
  if (error)
530
 
  {
531
 
    return false;
532
 
  }
533
 
  else if (iter == vector_of_engines.end())
534
 
  {
535
 
    error= ER_BAD_TABLE_ERROR;
536
 
    return false;
537
 
  }
538
 
 
539
 
  drizzled::message::Cache::singleton().erase(identifier);
540
 
 
541
 
  return true;
542
 
}
543
 
 
544
 
bool StorageEngine::dropTable(Session& session,
545
 
                              const identifier::Table &identifier)
546
 
{
547
 
  drizzled::error_t error;
548
 
 
549
 
  if (not dropTable(session, identifier, error))
550
 
  {
551
 
    return false;
552
 
  }
553
 
 
554
 
  return true;
555
 
}
556
 
 
557
 
bool StorageEngine::dropTable(Session::reference session,
558
 
                              StorageEngine &engine,
559
 
                              identifier::Table::const_reference identifier,
560
 
                              drizzled::error_t &error)
561
 
{
562
 
  error= EE_OK;
 
422
/**
 
423
   returns ENOENT if the file doesn't exists.
 
424
*/
 
425
int StorageEngine::dropTable(Session& session,
 
426
                             const TableIdentifier &identifier)
 
427
{
 
428
  int error= 0;
 
429
  int error_proto;
 
430
  message::Table src_proto;
 
431
  StorageEngine *engine;
 
432
 
 
433
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
 
434
 
 
435
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
 
436
  {
 
437
    string error_message;
 
438
 
 
439
    error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
 
440
    error_message.append(" : ");
 
441
    error_message.append(src_proto.InitializationErrorString());
 
442
 
 
443
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
 
444
 
 
445
    return ER_CORRUPT_TABLE_DEFINITION;
 
446
  }
 
447
 
 
448
  engine= StorageEngine::findByName(session, src_proto.engine().name());
 
449
 
 
450
  if (not engine)
 
451
  {
 
452
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
 
453
 
 
454
    return ER_CORRUPT_TABLE_DEFINITION;
 
455
  }
 
456
 
 
457
  error= StorageEngine::dropTable(session, *engine, identifier);
 
458
 
 
459
  if (error_proto && error == 0)
 
460
    return 0;
 
461
 
 
462
  return error;
 
463
}
 
464
 
 
465
int StorageEngine::dropTable(Session& session,
 
466
                             StorageEngine &engine,
 
467
                             const TableIdentifier &identifier)
 
468
{
 
469
  int error;
 
470
 
563
471
  engine.setTransactionReadWrite(session);
564
 
 
565
 
  assert(identifier.isTmp());
566
472
  
567
473
  if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
568
474
  {
570
476
  }
571
477
  else
572
478
  {
573
 
    error= static_cast<drizzled::error_t>(engine.doDropTable(session, identifier));
574
 
 
 
479
    error= engine.doDropTable(session, identifier);
575
480
    if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
576
481
    {
577
482
      error= ER_EVENT_OBSERVER_PLUGIN;
578
483
    }
579
484
  }
580
485
 
581
 
  drizzled::message::Cache::singleton().erase(identifier);
582
 
 
583
 
  if (error)
584
 
  {
585
 
    return false;
586
 
  }
587
 
 
588
 
  return true;
 
486
 
 
487
  return error;
589
488
}
590
489
 
591
490
 
597
496
  @retval
598
497
   1  error
599
498
*/
600
 
bool StorageEngine::createTable(Session &session,
601
 
                                const identifier::Table &identifier,
602
 
                                message::Table& table_message)
 
499
int StorageEngine::createTable(Session &session,
 
500
                               const TableIdentifier &identifier,
 
501
                               message::Table& table_message)
603
502
{
604
 
  drizzled::error_t error= EE_OK;
605
 
 
 
503
  int error= 1;
 
504
  Table table;
606
505
  TableShare share(identifier);
607
 
  table::Shell table(share);
608
506
  message::Table tmp_proto;
609
507
 
610
508
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
611
509
  { 
612
510
    // @note Error occured, we should probably do a little more here.
613
 
    // ER_CORRUPT_TABLE_DEFINITION,ER_CORRUPT_TABLE_DEFINITION_ENUM 
614
 
    
615
 
    my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
616
 
 
617
 
    return false;
618
511
  }
619
512
  else
620
513
  {
633
526
    {
634
527
      share.storage_engine->setTransactionReadWrite(session);
635
528
 
636
 
      error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
637
 
                                                                                table,
638
 
                                                                                identifier,
639
 
                                                                                table_message));
 
529
      error= share.storage_engine->doCreateTable(session,
 
530
                                                 table,
 
531
                                                 identifier,
 
532
                                                 table_message);
640
533
    }
641
534
 
642
 
    if (error == ER_TABLE_PERMISSION_DENIED)
643
 
    {
644
 
      my_error(ER_TABLE_PERMISSION_DENIED, identifier);
645
 
    }
646
 
    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);
 
535
    if (error)
 
536
    {
 
537
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
651
538
    }
652
539
 
653
540
    table.delete_table();
654
541
  }
655
542
 
656
 
  return(error == EE_OK);
 
543
  return(error != 0);
657
544
}
658
545
 
659
 
Cursor *StorageEngine::getCursor(Table &arg)
 
546
Cursor *StorageEngine::getCursor(TableShare &share)
660
547
{
661
 
  return create(arg);
 
548
  return create(share);
662
549
}
663
550
 
664
551
class AddTableIdentifier : 
665
 
  public std::unary_function<StorageEngine *, void>
 
552
  public unary_function<StorageEngine *, void>
666
553
{
667
554
  CachedDirectory &directory;
668
 
  const identifier::Schema &identifier;
669
 
  identifier::Table::vector &set_of_identifiers;
 
555
  const SchemaIdentifier &identifier;
 
556
  TableIdentifiers &set_of_identifiers;
670
557
 
671
558
public:
672
559
 
673
 
  AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
 
560
  AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
674
561
    directory(directory_arg),
675
562
    identifier(identifier_arg),
676
563
    set_of_identifiers(of_names)
684
571
};
685
572
 
686
573
 
687
 
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
 
574
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
 
575
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
 
576
 
 
577
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
688
578
{
689
579
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
690
580
 
698
588
    {
699
589
      errno= directory.getError();
700
590
      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
 
      }
 
591
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
706
592
      else
707
 
      {
708
593
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
709
 
      }
710
 
 
711
594
      return;
712
595
    }
713
596
  }
714
597
 
715
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
716
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
 
598
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
599
           AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
717
600
 
718
601
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
719
602
}
720
603
 
721
 
class DropTable: public std::unary_function<identifier::Table&, bool>
 
604
class DropTable: public unary_function<TableIdentifier&, bool>
722
605
{
723
606
  Session &session;
724
607
  StorageEngine *engine;
736
619
  } 
737
620
};
738
621
 
739
 
/* This will later be converted to identifier::Tables */
740
 
class DropTables: public std::unary_function<StorageEngine *, void>
 
622
/* This will later be converted to TableIdentifiers */
 
623
class DropTables: public unary_function<StorageEngine *, void>
741
624
{
742
625
  Session &session;
743
 
  identifier::Table::vector &table_identifiers;
 
626
  TableIdentifiers &table_identifiers;
744
627
 
745
628
public:
746
629
 
747
 
  DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
 
630
  DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
748
631
    session(session_arg),
749
632
    table_identifiers(table_identifiers_arg)
750
633
  { }
753
636
  {
754
637
    // True returning from DropTable means the table has been successfully
755
638
    // 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)),
 
639
    table_identifiers.erase(remove_if(table_identifiers.begin(),
 
640
                                      table_identifiers.end(),
 
641
                                      DropTable(session, engine)),
759
642
                            table_identifiers.end());
760
643
  }
761
644
};
768
651
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
769
652
{
770
653
  CachedDirectory dir(directory, set_of_table_definition_ext);
771
 
  identifier::Table::vector table_identifiers;
 
654
  TableIdentifiers table_identifiers;
772
655
 
773
656
  if (dir.fail())
774
657
  {
784
667
       fileIter != files.end(); fileIter++)
785
668
  {
786
669
    size_t length;
787
 
    std::string path;
 
670
    string path;
788
671
    CachedDirectory::Entry *entry= *fileIter;
789
672
 
790
673
    /* We remove the file extension. */
797
680
    message::Table definition;
798
681
    if (StorageEngine::readTableFile(path, definition))
799
682
    {
800
 
      identifier::Table identifier(definition.schema(), definition.name(), path);
 
683
      TableIdentifier identifier(definition.schema(), definition.name(), path);
801
684
      table_identifiers.push_back(identifier);
802
685
    }
803
686
  }
804
687
 
805
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
806
 
                DropTables(session, table_identifiers));
807
 
 
 
688
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
689
           DropTables(session, table_identifiers));
 
690
  
808
691
  /*
809
692
    Now we just clean up anything that might left over.
810
693
 
811
694
    We rescan because some of what might have been there should
812
695
    now be all nice and cleaned up.
813
696
  */
814
 
  std::set<std::string> all_exts= set_of_table_definition_ext;
 
697
  set<string> all_exts= set_of_table_definition_ext;
815
698
 
816
699
  for (EngineVector::iterator iter= vector_of_engines.begin();
817
700
       iter != vector_of_engines.end() ; iter++)
826
709
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
827
710
       fileIter != files.end(); fileIter++)
828
711
  {
829
 
    std::string path;
 
712
    string path;
830
713
    CachedDirectory::Entry *entry= *fileIter;
831
714
 
832
715
    path+= directory;
847
730
    - table->getShare()->path
848
731
    - table->alias
849
732
*/
850
 
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
851
 
{
852
 
  drizzled::error_t textno= ER_GET_ERRNO;
 
733
void StorageEngine::print_error(int error, myf errflag, Table &table)
 
734
{
 
735
  print_error(error, errflag, &table);
 
736
}
 
737
 
 
738
void StorageEngine::print_error(int error, myf errflag, Table *table)
 
739
{
 
740
  int textno= ER_GET_ERRNO;
853
741
  switch (error) {
854
742
  case EACCES:
855
743
    textno=ER_OPEN_AS_READONLY;
870
758
    break;
871
759
  case HA_ERR_FOUND_DUPP_KEY:
872
760
  {
873
 
    uint32_t key_nr= table.get_dup_key(error);
 
761
    assert(table);
 
762
    uint32_t key_nr= table->get_dup_key(error);
874
763
    if ((int) key_nr >= 0)
875
764
    {
876
765
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
877
766
 
878
 
      print_keydup_error(key_nr, err_msg, table);
 
767
      print_keydup_error(key_nr, err_msg, *table);
879
768
 
880
769
      return;
881
770
    }
884
773
  }
885
774
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
886
775
  {
887
 
    uint32_t key_nr= table.get_dup_key(error);
 
776
    assert(table);
 
777
    uint32_t key_nr= table->get_dup_key(error);
888
778
    if ((int) key_nr >= 0)
889
779
    {
890
780
      uint32_t max_length;
894
784
      String str(key,sizeof(key),system_charset_info);
895
785
 
896
786
      /* Table is opened and defined at this point */
897
 
      key_unpack(&str, &table,(uint32_t) key_nr);
 
787
      key_unpack(&str,table,(uint32_t) key_nr);
898
788
      max_length= (DRIZZLE_ERRMSG_SIZE-
899
789
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
900
790
      if (str.length() >= max_length)
902
792
        str.length(max_length-4);
903
793
        str.append(STRING_WITH_LEN("..."));
904
794
      }
905
 
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table.getShare()->getTableName(),
 
795
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
906
796
        str.c_ptr(), key_nr+1);
907
797
      return;
908
798
    }
925
815
    textno=ER_CRASHED_ON_USAGE;
926
816
    break;
927
817
  case HA_ERR_NOT_A_TABLE:
928
 
    textno= static_cast<drizzled::error_t>(error);
 
818
    textno= error;
929
819
    break;
930
820
  case HA_ERR_CRASHED_ON_REPAIR:
931
821
    textno=ER_CRASHED_ON_REPAIR;
979
869
    textno=ER_TABLE_DEF_CHANGED;
980
870
    break;
981
871
  case HA_ERR_NO_SUCH_TABLE:
982
 
    {
983
 
      identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
984
 
      my_error(ER_TABLE_UNKNOWN, identifier);
985
 
      return;
986
 
    }
 
872
    assert(table);
 
873
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
 
874
             table->getShare()->getTableName());
 
875
    return;
987
876
  case HA_ERR_RBR_LOGGING_FAILED:
988
877
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
989
878
    break;
990
879
  case HA_ERR_DROP_INDEX_FK:
991
880
  {
 
881
    assert(table);
992
882
    const char *ptr= "???";
993
 
    uint32_t key_nr= table.get_dup_key(error);
 
883
    uint32_t key_nr= table->get_dup_key(error);
994
884
    if ((int) key_nr >= 0)
995
 
      ptr= table.key_info[key_nr].name;
 
885
      ptr= table->key_info[key_nr].name;
996
886
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
997
887
    return;
998
888
  }
1037
927
      return;
1038
928
    }
1039
929
  }
1040
 
 
1041
 
  my_error(textno, errflag, table.getShare()->getTableName(), error);
 
930
  my_error(textno, errflag, table->getShare()->getTableName(), error);
1042
931
}
1043
932
 
1044
933
 
1051
940
  @return
1052
941
    Returns true if this is a temporary error
1053
942
*/
1054
 
bool StorageEngine::get_error_message(int , String* ) const
 
943
bool StorageEngine::get_error_message(int , String* )
1055
944
{
1056
945
  return false;
1057
946
}
1058
947
 
1059
948
 
1060
 
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
 
949
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1061
950
{
1062
951
  /* Write the duplicated key in the error message */
1063
952
  char key[MAX_KEY_LENGTH];
1085
974
}
1086
975
 
1087
976
 
1088
 
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
 
977
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1089
978
{
1090
 
  std::string path(identifier.getPath());
 
979
  string path(identifier.getPath());
1091
980
 
1092
981
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1093
982
 
1094
983
  return internal::my_delete(path.c_str(), MYF(0));
1095
984
}
1096
985
 
1097
 
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
 
986
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1098
987
{
1099
988
  message::Table table_message;
1100
 
  std::string src_path(src.getPath());
1101
 
  std::string dest_path(dest.getPath());
 
989
  string src_path(src.getPath());
 
990
  string dest_path(dest.getPath());
1102
991
 
1103
992
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1104
993
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1123
1012
  return error;
1124
1013
}
1125
1014
 
1126
 
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, message::Table &table_message)
 
1015
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1127
1016
{
1128
1017
  char definition_file_tmp[FN_REFLEN];
1129
 
  std::string file_name(identifier.getPath());
 
1018
  string file_name(identifier.getPath());
1130
1019
 
1131
1020
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1132
1021
 
1145
1034
 
1146
1035
  bool success;
1147
1036
 
1148
 
  try
1149
 
  {
 
1037
  try {
1150
1038
    success= table_message.SerializeToZeroCopyStream(output);
1151
1039
  }
1152
1040
  catch (...)
1156
1044
 
1157
1045
  if (not success)
1158
1046
  {
1159
 
    std::string error_message;
1160
 
    identifier.getSQLPath(error_message);
1161
 
 
1162
1047
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1163
 
             error_message.c_str(),
1164
1048
             table_message.InitializationErrorString().c_str());
1165
1049
    delete output;
1166
1050
 
1200
1084
  return 0;
1201
1085
}
1202
1086
 
1203
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
 
1087
class CanCreateTable: public unary_function<StorageEngine *, bool>
1204
1088
{
1205
 
  const identifier::Table &identifier;
 
1089
  const TableIdentifier &identifier;
1206
1090
 
1207
1091
public:
1208
 
  CanCreateTable(const identifier::Table &identifier_arg) :
 
1092
  CanCreateTable(const TableIdentifier &identifier_arg) :
1209
1093
    identifier(identifier_arg)
1210
1094
  { }
1211
1095
 
1219
1103
/**
1220
1104
  @note on success table can be created.
1221
1105
*/
1222
 
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
 
1106
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1223
1107
{
1224
1108
  EngineVector::iterator iter=
1225
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1226
 
                 CanCreateTable(identifier));
 
1109
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
1110
            CanCreateTable(identifier));
1227
1111
 
1228
1112
  if (iter == vector_of_engines.end())
1229
1113
  {
1235
1119
 
1236
1120
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1237
1121
{
1238
 
  std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
 
1122
  fstream input(path.c_str(), ios::in | ios::binary);
1239
1123
 
1240
1124
  if (input.good())
1241
1125
  {
1248
1132
    catch (...)
1249
1133
    {
1250
1134
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1251
 
               table_message.name().empty() ? path.c_str() : table_message.name().c_str(),
1252
1135
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1253
1136
    }
1254
1137
  }
1260
1143
  return false;
1261
1144
}
1262
1145
 
1263
 
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine)
1264
 
{
1265
 
  output << "StorageEngine:(";
1266
 
  output <<  engine.getName();
1267
 
  output << ")";
1268
1146
 
1269
 
  return output;
1270
 
}
1271
1147
 
1272
1148
} /* namespace plugin */
1273
1149
} /* namespace drizzled */