~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Lee Bieber
  • Date: 2010-11-07 19:34:48 UTC
  • mfrom: (1910.1.2 build)
  • Revision ID: kalebral@gmail.com-20101107193448-64kdu912qej354sh
Merge Stewart - including adapting and expanding the "differences from mysql" page from the wiki.
Merge Stewart - fix bug 668143: drizzleslap with --commit runs second iteration data load in a transaction

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