~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-20 22:04:04 UTC
  • mfrom: (1942.1.4 b)
  • Revision ID: kalebral@gmail.com-20101120220404-2qpb4xuik9wv9u1q
Merge Lee -  Run bzr ignore for leftover files
Merge Shrews - Add a --replicate-query option to the server which controls whether or not the SQL query string is included in the GPB Statement messages.
Merge Andrew - fix bug 665119: drizzleslap has -i mapped to two options
Merge Andrew fix bug 674145: Table Names Not Case Matched

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