~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Brian Aker
  • Date: 2010-08-18 23:12:07 UTC
  • mto: This revision was merged to the branch mainline in revision 1719.
  • Revision ID: brian@tangent.org-20100818231207-2dgclr6o06q90np1
Test scoped ptr in the 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
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
 
20
#include "config.h"
21
21
 
22
22
#include <fcntl.h>
23
23
#include <unistd.h>
32
32
#include <google/protobuf/io/zero_copy_stream.h>
33
33
#include <google/protobuf/io/zero_copy_stream_impl.h>
34
34
 
35
 
#include <drizzled/cached_directory.h>
 
35
#include "drizzled/my_hash.h"
 
36
#include "drizzled/cached_directory.h"
36
37
 
37
38
#include <drizzled/definitions.h>
38
39
#include <drizzled/base.h>
43
44
#include <drizzled/gettext.h>
44
45
#include <drizzled/unireg.h>
45
46
#include <drizzled/data_home.h>
46
 
#include <drizzled/errmsg_print.h>
47
 
#include <drizzled/xid.h>
48
 
#include <drizzled/sql_table.h>
49
 
#include <drizzled/global_charset_info.h>
50
 
#include <drizzled/charset.h>
51
 
#include <drizzled/internal/my_sys.h>
 
47
#include "drizzled/errmsg_print.h"
 
48
#include "drizzled/xid.h"
 
49
#include "drizzled/sql_table.h"
 
50
#include "drizzled/global_charset_info.h"
 
51
#include "drizzled/charset.h"
 
52
#include "drizzled/internal/my_sys.h"
 
53
#include "drizzled/db.h"
52
54
 
53
55
#include <drizzled/table_proto.h>
54
56
#include <drizzled/plugin/event_observer.h>
55
 
#include <drizzled/internal_error_handler.h>
56
 
 
57
 
#include <drizzled/table/shell.h>
58
 
 
59
 
#include <drizzled/message/cache.h>
60
57
 
61
58
#include <boost/algorithm/string/compare.hpp>
62
59
 
63
60
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
64
61
 
 
62
using namespace std;
 
63
 
65
64
namespace drizzled
66
65
{
67
66
 
82
81
  return vector_of_schema_engines;
83
82
}
84
83
 
85
 
StorageEngine::StorageEngine(const std::string name_arg,
86
 
                             const std::bitset<HTON_BIT_SIZE> &flags_arg) :
 
84
StorageEngine::StorageEngine(const string name_arg,
 
85
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
87
86
  Plugin(name_arg, "StorageEngine"),
88
87
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
89
88
  flags(flags_arg)
101
100
}
102
101
 
103
102
 
104
 
int StorageEngine::renameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
103
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
105
104
{
106
105
  int error;
107
106
  setTransactionReadWrite(session);
137
136
  @retval
138
137
    !0  Error
139
138
*/
140
 
int StorageEngine::doDropTable(Session&, const identifier::Table &identifier)
 
139
int StorageEngine::doDropTable(Session&, const TableIdentifier &identifier)
141
140
                               
142
141
{
143
142
  int error= 0;
192
191
}
193
192
 
194
193
class FindEngineByName
195
 
  : public std::unary_function<StorageEngine *, bool>
 
194
  : public unary_function<StorageEngine *, bool>
196
195
{
197
 
  const std::string &predicate;
 
196
  const string &predicate;
198
197
 
199
198
public:
200
 
  explicit FindEngineByName(const std::string &target_arg) :
 
199
  explicit FindEngineByName(const string &target_arg) :
201
200
    predicate(target_arg)
202
201
  {
203
202
  }
208
207
  }
209
208
};
210
209
 
211
 
StorageEngine *StorageEngine::findByName(const std::string &predicate)
 
210
StorageEngine *StorageEngine::findByName(const string &predicate)
212
211
{
213
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
 
                                            vector_of_engines.end(),
215
 
                                            FindEngineByName(predicate));
 
212
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
213
                                       vector_of_engines.end(),
 
214
                                       FindEngineByName(predicate));
216
215
  if (iter != vector_of_engines.end())
217
216
  {
218
217
    StorageEngine *engine= *iter;
223
222
  return NULL;
224
223
}
225
224
 
226
 
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
 
225
StorageEngine *StorageEngine::findByName(Session& session, const string &predicate)
227
226
{
228
227
  if (boost::iequals(predicate, DEFAULT_STRING))
229
228
    return session.getDefaultStorageEngine();
230
229
 
231
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
 
                                            vector_of_engines.end(),
233
 
                                            FindEngineByName(predicate));
 
230
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
231
                                       vector_of_engines.end(),
 
232
                                       FindEngineByName(predicate));
234
233
  if (iter != vector_of_engines.end())
235
234
  {
236
235
    StorageEngine *engine= *iter;
241
240
  return NULL;
242
241
}
243
242
 
244
 
class StorageEngineCloseConnection : public std::unary_function<StorageEngine *, void>
 
243
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
245
244
{
246
245
  Session *session;
247
246
public:
263
262
*/
264
263
void StorageEngine::closeConnection(Session* session)
265
264
{
266
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
 
                StorageEngineCloseConnection(session));
 
265
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
266
           StorageEngineCloseConnection(session));
268
267
}
269
268
 
270
269
bool StorageEngine::flushLogs(StorageEngine *engine)
271
270
{
272
271
  if (engine == NULL)
273
272
  {
274
 
    if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
 
                     std::mem_fun(&StorageEngine::flush_logs))
 
273
    if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
274
                mem_fun(&StorageEngine::flush_logs))
276
275
        != vector_of_engines.begin())
277
276
      return true;
278
277
  }
284
283
  return false;
285
284
}
286
285
 
287
 
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
 
286
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
288
287
{
289
288
  Session& session;
290
 
  const identifier::Table &identifier;
 
289
  const TableIdentifier &identifier;
291
290
  message::Table &table_message;
292
 
  drizzled::error_t &err;
 
291
  int &err;
293
292
 
294
293
public:
295
294
  StorageEngineGetTableDefinition(Session& session_arg,
296
 
                                  const identifier::Table &identifier_arg,
 
295
                                  const TableIdentifier &identifier_arg,
297
296
                                  message::Table &table_message_arg,
298
 
                                  drizzled::error_t &err_arg) :
 
297
                                  int &err_arg) :
299
298
    session(session_arg), 
300
299
    identifier(identifier_arg),
301
300
    table_message(table_message_arg), 
306
305
    int ret= engine->doGetTableDefinition(session, identifier, table_message);
307
306
 
308
307
    if (ret != ENOENT)
309
 
      err= static_cast<drizzled::error_t>(ret);
 
308
      err= ret;
310
309
 
311
 
    return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
 
310
    return err == EEXIST || err != ENOENT;
312
311
  }
313
312
};
314
313
 
315
 
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
 
314
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
316
315
{
317
316
  Session& session;
318
 
  const identifier::Table &identifier;
 
317
  const TableIdentifier &identifier;
319
318
 
320
319
public:
321
 
  StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
 
320
  StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
322
321
    session(session_arg), 
323
322
    identifier(identifier_arg) 
324
323
  { }
333
332
  Utility method which hides some of the details of getTableDefinition()
334
333
*/
335
334
bool plugin::StorageEngine::doesTableExist(Session &session,
336
 
                                           const identifier::Table &identifier,
 
335
                                           const TableIdentifier &identifier,
337
336
                                           bool include_temporary_tables)
338
337
{
339
338
  if (include_temporary_tables)
343
342
  }
344
343
 
345
344
  EngineVector::iterator iter=
346
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
 
                 StorageEngineDoesTableExist(session, identifier));
 
345
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
346
            StorageEngineDoesTableExist(session, identifier));
348
347
 
349
348
  if (iter == vector_of_engines.end())
350
349
  {
354
353
  return true;
355
354
}
356
355
 
357
 
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
 
356
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
358
357
{
359
 
  std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
 
358
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
360
359
  assert(0);
361
360
  return false;
362
361
}
363
362
 
364
 
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
365
 
                                                          identifier::Table::const_reference identifier,
366
 
                                                          bool include_temporary_tables)
 
363
/**
 
364
  Call this function in order to give the Cursor the possiblity
 
365
  to ask engine if there are any new tables that should be written to disk
 
366
  or any dropped tables that need to be removed from disk
 
367
*/
 
368
int StorageEngine::getTableDefinition(Session& session,
 
369
                                      const TableIdentifier &identifier,
 
370
                                      message::Table &table_message,
 
371
                                      bool include_temporary_tables)
367
372
{
368
 
  drizzled::error_t error;
369
 
  error= static_cast<drizzled::error_t>(ENOENT);
 
373
  int err= ENOENT;
370
374
 
371
375
  if (include_temporary_tables)
372
376
  {
373
 
    Table *table= session.find_temporary_table(identifier);
374
 
    if (table)
375
 
    {
376
 
      return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
377
 
    }
378
 
  }
379
 
 
380
 
  drizzled::message::table::shared_ptr table_ptr;
381
 
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
382
 
  {
383
 
    (void)table_ptr;
384
 
  }
385
 
 
386
 
  message::Table message;
 
377
    if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
 
378
      return EEXIST;
 
379
  }
 
380
 
387
381
  EngineVector::iterator iter=
388
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
389
 
                 StorageEngineGetTableDefinition(session, identifier, message, error));
 
382
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
383
            StorageEngineGetTableDefinition(session, identifier, table_message, err));
390
384
 
391
385
  if (iter == vector_of_engines.end())
392
386
  {
393
 
    return message::table::shared_ptr();
 
387
    return ENOENT;
394
388
  }
395
 
  message::table::shared_ptr table_message(new message::Table(message));
396
 
 
397
 
  drizzled::message::Cache::singleton().insert(identifier, table_message);
398
 
 
399
 
  return table_message;
 
389
 
 
390
  return err;
400
391
}
401
392
 
402
393
/**
409
400
{
410
401
public:
411
402
  Ha_delete_table_error_handler() : Internal_error_handler() {}
412
 
  virtual bool handle_error(drizzled::error_t sql_errno,
 
403
  virtual bool handle_error(uint32_t sql_errno,
413
404
                            const char *message,
414
405
                            DRIZZLE_ERROR::enum_warning_level level,
415
406
                            Session *session);
419
410
 
420
411
bool
421
412
Ha_delete_table_error_handler::
422
 
handle_error(drizzled::error_t ,
 
413
handle_error(uint32_t ,
423
414
             const char *message,
424
415
             DRIZZLE_ERROR::enum_warning_level ,
425
416
             Session *)
429
420
  return true;
430
421
}
431
422
 
432
 
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
433
 
{
434
 
  Session::reference session;
435
 
  identifier::Table::const_reference identifier;
436
 
  drizzled::error_t &error;
437
 
 
438
 
public:
439
 
 
440
 
  DropTableByIdentifier(Session::reference session_arg,
441
 
                        identifier::Table::const_reference identifier_arg,
442
 
                        drizzled::error_t &error_arg) :
443
 
    session(session_arg),
444
 
    identifier(identifier_arg),
445
 
    error(error_arg)
446
 
  { }
447
 
 
448
 
  result_type operator() (argument_type engine)
449
 
  {
450
 
    if (not engine->doDoesTableExist(session, identifier))
451
 
      return false;
452
 
 
453
 
    int local_error= engine->doDropTable(session, identifier);
454
 
 
455
 
 
456
 
    if (not local_error)
457
 
      return true;
458
 
 
459
 
    switch (local_error)
460
 
    {
461
 
    case HA_ERR_NO_SUCH_TABLE:
462
 
    case ENOENT:
463
 
      error= static_cast<drizzled::error_t>(HA_ERR_NO_SUCH_TABLE);
464
 
      return false;
465
 
 
466
 
    default:
467
 
      error= static_cast<drizzled::error_t>(local_error);
468
 
      return true;
469
 
    }
470
 
  } 
471
 
};
472
 
 
473
 
 
474
 
bool StorageEngine::dropTable(Session::reference session,
475
 
                              identifier::Table::const_reference identifier,
476
 
                              drizzled::error_t &error)
477
 
{
478
 
  error= EE_OK;
479
 
 
480
 
  EngineVector::const_iterator iter= std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
481
 
                                                  DropTableByIdentifier(session, identifier, error));
482
 
 
483
 
  if (error)
484
 
  {
485
 
    return false;
486
 
  }
487
 
  else if (iter == vector_of_engines.end())
488
 
  {
489
 
    error= ER_BAD_TABLE_ERROR;
490
 
    return false;
491
 
  }
492
 
 
493
 
  drizzled::message::Cache::singleton().erase(identifier);
494
 
 
495
 
  return true;
496
 
}
497
 
 
498
 
bool StorageEngine::dropTable(Session& session,
499
 
                              const identifier::Table &identifier)
500
 
{
501
 
  drizzled::error_t error;
502
 
 
503
 
  if (not dropTable(session, identifier, error))
504
 
  {
505
 
    return false;
506
 
  }
507
 
 
508
 
  return true;
509
 
}
510
 
 
511
 
bool StorageEngine::dropTable(Session::reference session,
512
 
                              StorageEngine &engine,
513
 
                              identifier::Table::const_reference identifier,
514
 
                              drizzled::error_t &error)
515
 
{
516
 
  error= EE_OK;
 
423
/**
 
424
   returns ENOENT if the file doesn't exists.
 
425
*/
 
426
int StorageEngine::dropTable(Session& session,
 
427
                             const TableIdentifier &identifier)
 
428
{
 
429
  int error= 0;
 
430
  int error_proto;
 
431
  message::Table src_proto;
 
432
  StorageEngine *engine;
 
433
 
 
434
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
 
435
 
 
436
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
 
437
  {
 
438
    string error_message;
 
439
 
 
440
    error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
 
441
    error_message.append(" : ");
 
442
    error_message.append(src_proto.InitializationErrorString());
 
443
 
 
444
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
 
445
 
 
446
    return ER_CORRUPT_TABLE_DEFINITION;
 
447
  }
 
448
 
 
449
  engine= StorageEngine::findByName(session, src_proto.engine().name());
 
450
 
 
451
  if (not engine)
 
452
  {
 
453
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
 
454
 
 
455
    return ER_CORRUPT_TABLE_DEFINITION;
 
456
  }
 
457
 
 
458
  error= StorageEngine::dropTable(session, *engine, identifier);
 
459
 
 
460
  if (error_proto && error == 0)
 
461
    return 0;
 
462
 
 
463
  return error;
 
464
}
 
465
 
 
466
int StorageEngine::dropTable(Session& session,
 
467
                             StorageEngine &engine,
 
468
                             const TableIdentifier &identifier)
 
469
{
 
470
  int error;
 
471
 
517
472
  engine.setTransactionReadWrite(session);
518
 
 
519
 
  assert(identifier.isTmp());
520
473
  
521
474
  if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
522
475
  {
524
477
  }
525
478
  else
526
479
  {
527
 
    error= static_cast<drizzled::error_t>(engine.doDropTable(session, identifier));
528
 
 
 
480
    error= engine.doDropTable(session, identifier);
529
481
    if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
530
482
    {
531
483
      error= ER_EVENT_OBSERVER_PLUGIN;
532
484
    }
533
485
  }
534
486
 
535
 
  drizzled::message::Cache::singleton().erase(identifier);
536
 
 
537
 
  if (error)
538
 
  {
539
 
    return false;
540
 
  }
541
 
 
542
 
  return true;
 
487
 
 
488
  return error;
543
489
}
544
490
 
545
491
 
551
497
  @retval
552
498
   1  error
553
499
*/
554
 
bool StorageEngine::createTable(Session &session,
555
 
                                const identifier::Table &identifier,
556
 
                                message::Table& table_message)
 
500
int StorageEngine::createTable(Session &session,
 
501
                               const TableIdentifier &identifier,
 
502
                               message::Table& table_message)
557
503
{
558
 
  drizzled::error_t error= EE_OK;
559
 
 
 
504
  int error= 1;
 
505
  Table table;
560
506
  TableShare share(identifier);
561
 
  table::Shell table(share);
562
507
  message::Table tmp_proto;
563
508
 
564
509
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
565
510
  { 
566
511
    // @note Error occured, we should probably do a little more here.
567
 
    // ER_CORRUPT_TABLE_DEFINITION,ER_CORRUPT_TABLE_DEFINITION_ENUM 
568
 
    
569
 
    my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
570
 
 
571
 
    return false;
572
512
  }
573
513
  else
574
514
  {
587
527
    {
588
528
      share.storage_engine->setTransactionReadWrite(session);
589
529
 
590
 
      error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
591
 
                                                                                table,
592
 
                                                                                identifier,
593
 
                                                                                table_message));
 
530
      error= share.storage_engine->doCreateTable(session,
 
531
                                                 table,
 
532
                                                 identifier,
 
533
                                                 table_message);
594
534
    }
595
535
 
596
 
    if (error == ER_TABLE_PERMISSION_DENIED)
597
 
    {
598
 
      my_error(ER_TABLE_PERMISSION_DENIED, identifier);
599
 
    }
600
 
    else if (error)
601
 
    {
602
 
      std::string path;
603
 
      identifier.getSQLPath(path);
604
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
 
536
    if (error)
 
537
    {
 
538
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
605
539
    }
606
540
 
607
541
    table.delete_table();
608
542
  }
609
543
 
610
 
  return(error == EE_OK);
 
544
  return(error != 0);
611
545
}
612
546
 
613
 
Cursor *StorageEngine::getCursor(Table &arg)
 
547
Cursor *StorageEngine::getCursor(TableShare &share)
614
548
{
615
 
  return create(arg);
 
549
  return create(share);
616
550
}
617
551
 
618
552
class AddTableIdentifier : 
619
 
  public std::unary_function<StorageEngine *, void>
 
553
  public unary_function<StorageEngine *, void>
620
554
{
621
555
  CachedDirectory &directory;
622
 
  const identifier::Schema &identifier;
623
 
  identifier::Table::vector &set_of_identifiers;
 
556
  const SchemaIdentifier &identifier;
 
557
  TableIdentifiers &set_of_identifiers;
624
558
 
625
559
public:
626
560
 
627
 
  AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
 
561
  AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
628
562
    directory(directory_arg),
629
563
    identifier(identifier_arg),
630
564
    set_of_identifiers(of_names)
638
572
};
639
573
 
640
574
 
641
 
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
 
575
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
 
576
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
 
577
 
 
578
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
642
579
{
643
580
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
644
581
 
652
589
    {
653
590
      errno= directory.getError();
654
591
      if (errno == ENOENT)
655
 
      {
656
 
        std::string path;
657
 
        schema_identifier.getSQLPath(path);
658
 
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
659
 
      }
 
592
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
660
593
      else
661
 
      {
662
594
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
663
 
      }
664
 
 
665
595
      return;
666
596
    }
667
597
  }
668
598
 
669
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
670
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
 
599
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
600
           AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
671
601
 
672
602
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
673
603
}
674
604
 
675
 
class DropTable: public std::unary_function<identifier::Table&, bool>
 
605
class DropTable: public unary_function<TableIdentifier&, bool>
676
606
{
677
607
  Session &session;
678
608
  StorageEngine *engine;
690
620
  } 
691
621
};
692
622
 
693
 
/* This will later be converted to identifier::Tables */
694
 
class DropTables: public std::unary_function<StorageEngine *, void>
 
623
/* This will later be converted to TableIdentifiers */
 
624
class DropTables: public unary_function<StorageEngine *, void>
695
625
{
696
626
  Session &session;
697
 
  identifier::Table::vector &table_identifiers;
 
627
  TableIdentifiers &table_identifiers;
698
628
 
699
629
public:
700
630
 
701
 
  DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
 
631
  DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
702
632
    session(session_arg),
703
633
    table_identifiers(table_identifiers_arg)
704
634
  { }
707
637
  {
708
638
    // True returning from DropTable means the table has been successfully
709
639
    // deleted, so it should be removed from the list of tables to drop
710
 
    table_identifiers.erase(std::remove_if(table_identifiers.begin(),
711
 
                                           table_identifiers.end(),
712
 
                                           DropTable(session, engine)),
 
640
    table_identifiers.erase(remove_if(table_identifiers.begin(),
 
641
                                      table_identifiers.end(),
 
642
                                      DropTable(session, engine)),
713
643
                            table_identifiers.end());
714
644
  }
715
645
};
722
652
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
723
653
{
724
654
  CachedDirectory dir(directory, set_of_table_definition_ext);
725
 
  identifier::Table::vector table_identifiers;
 
655
  TableIdentifiers table_identifiers;
726
656
 
727
657
  if (dir.fail())
728
658
  {
738
668
       fileIter != files.end(); fileIter++)
739
669
  {
740
670
    size_t length;
741
 
    std::string path;
 
671
    string path;
742
672
    CachedDirectory::Entry *entry= *fileIter;
743
673
 
744
674
    /* We remove the file extension. */
751
681
    message::Table definition;
752
682
    if (StorageEngine::readTableFile(path, definition))
753
683
    {
754
 
      identifier::Table identifier(definition.schema(), definition.name(), path);
 
684
      TableIdentifier identifier(definition.schema(), definition.name(), path);
755
685
      table_identifiers.push_back(identifier);
756
686
    }
757
687
  }
758
688
 
759
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
760
 
                DropTables(session, table_identifiers));
761
 
 
 
689
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
690
           DropTables(session, table_identifiers));
 
691
  
762
692
  /*
763
693
    Now we just clean up anything that might left over.
764
694
 
765
695
    We rescan because some of what might have been there should
766
696
    now be all nice and cleaned up.
767
697
  */
768
 
  std::set<std::string> all_exts= set_of_table_definition_ext;
 
698
  set<string> all_exts= set_of_table_definition_ext;
769
699
 
770
700
  for (EngineVector::iterator iter= vector_of_engines.begin();
771
701
       iter != vector_of_engines.end() ; iter++)
780
710
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
781
711
       fileIter != files.end(); fileIter++)
782
712
  {
783
 
    std::string path;
 
713
    string path;
784
714
    CachedDirectory::Entry *entry= *fileIter;
785
715
 
786
716
    path+= directory;
801
731
    - table->getShare()->path
802
732
    - table->alias
803
733
*/
804
 
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
805
 
{
806
 
  drizzled::error_t textno= ER_GET_ERRNO;
 
734
void StorageEngine::print_error(int error, myf errflag, Table &table)
 
735
{
 
736
  print_error(error, errflag, &table);
 
737
}
 
738
 
 
739
void StorageEngine::print_error(int error, myf errflag, Table *table)
 
740
{
 
741
  int textno= ER_GET_ERRNO;
807
742
  switch (error) {
808
743
  case EACCES:
809
744
    textno=ER_OPEN_AS_READONLY;
824
759
    break;
825
760
  case HA_ERR_FOUND_DUPP_KEY:
826
761
  {
827
 
    uint32_t key_nr= table.get_dup_key(error);
 
762
    assert(table);
 
763
    uint32_t key_nr= table->get_dup_key(error);
828
764
    if ((int) key_nr >= 0)
829
765
    {
830
766
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
831
767
 
832
 
      print_keydup_error(key_nr, err_msg, table);
 
768
      print_keydup_error(key_nr, err_msg, *table);
833
769
 
834
770
      return;
835
771
    }
838
774
  }
839
775
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
840
776
  {
841
 
    uint32_t key_nr= table.get_dup_key(error);
 
777
    assert(table);
 
778
    uint32_t key_nr= table->get_dup_key(error);
842
779
    if ((int) key_nr >= 0)
843
780
    {
844
781
      uint32_t max_length;
848
785
      String str(key,sizeof(key),system_charset_info);
849
786
 
850
787
      /* Table is opened and defined at this point */
851
 
      key_unpack(&str, &table,(uint32_t) key_nr);
 
788
      key_unpack(&str,table,(uint32_t) key_nr);
852
789
      max_length= (DRIZZLE_ERRMSG_SIZE-
853
790
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
854
791
      if (str.length() >= max_length)
856
793
        str.length(max_length-4);
857
794
        str.append(STRING_WITH_LEN("..."));
858
795
      }
859
 
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table.getShare()->getTableName(),
 
796
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
860
797
        str.c_ptr(), key_nr+1);
861
798
      return;
862
799
    }
879
816
    textno=ER_CRASHED_ON_USAGE;
880
817
    break;
881
818
  case HA_ERR_NOT_A_TABLE:
882
 
    textno= static_cast<drizzled::error_t>(error);
 
819
    textno= error;
883
820
    break;
884
821
  case HA_ERR_CRASHED_ON_REPAIR:
885
822
    textno=ER_CRASHED_ON_REPAIR;
933
870
    textno=ER_TABLE_DEF_CHANGED;
934
871
    break;
935
872
  case HA_ERR_NO_SUCH_TABLE:
936
 
    {
937
 
      identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
938
 
      my_error(ER_TABLE_UNKNOWN, identifier);
939
 
      return;
940
 
    }
 
873
    assert(table);
 
874
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
 
875
             table->getShare()->getTableName());
 
876
    return;
941
877
  case HA_ERR_RBR_LOGGING_FAILED:
942
878
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
943
879
    break;
944
880
  case HA_ERR_DROP_INDEX_FK:
945
881
  {
 
882
    assert(table);
946
883
    const char *ptr= "???";
947
 
    uint32_t key_nr= table.get_dup_key(error);
 
884
    uint32_t key_nr= table->get_dup_key(error);
948
885
    if ((int) key_nr >= 0)
949
 
      ptr= table.key_info[key_nr].name;
 
886
      ptr= table->key_info[key_nr].name;
950
887
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
951
888
    return;
952
889
  }
991
928
      return;
992
929
    }
993
930
  }
994
 
 
995
 
  my_error(textno, errflag, table.getShare()->getTableName(), error);
 
931
  my_error(textno, errflag, table->getShare()->getTableName(), error);
996
932
}
997
933
 
998
934
 
1005
941
  @return
1006
942
    Returns true if this is a temporary error
1007
943
*/
1008
 
bool StorageEngine::get_error_message(int , String* ) const
 
944
bool StorageEngine::get_error_message(int , String* )
1009
945
{
1010
946
  return false;
1011
947
}
1012
948
 
1013
949
 
1014
 
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
 
950
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1015
951
{
1016
952
  /* Write the duplicated key in the error message */
1017
953
  char key[MAX_KEY_LENGTH];
1039
975
}
1040
976
 
1041
977
 
1042
 
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
 
978
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1043
979
{
1044
 
  std::string path(identifier.getPath());
 
980
  string path(identifier.getPath());
1045
981
 
1046
982
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1047
983
 
1048
984
  return internal::my_delete(path.c_str(), MYF(0));
1049
985
}
1050
986
 
1051
 
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
 
987
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1052
988
{
1053
989
  message::Table table_message;
1054
 
  std::string src_path(src.getPath());
1055
 
  std::string dest_path(dest.getPath());
 
990
  string src_path(src.getPath());
 
991
  string dest_path(dest.getPath());
1056
992
 
1057
993
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1058
994
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1077
1013
  return error;
1078
1014
}
1079
1015
 
1080
 
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, message::Table &table_message)
 
1016
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1081
1017
{
1082
1018
  char definition_file_tmp[FN_REFLEN];
1083
 
  std::string file_name(identifier.getPath());
 
1019
  string file_name(identifier.getPath());
1084
1020
 
1085
1021
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1086
1022
 
1099
1035
 
1100
1036
  bool success;
1101
1037
 
1102
 
  try
1103
 
  {
 
1038
  try {
1104
1039
    success= table_message.SerializeToZeroCopyStream(output);
1105
1040
  }
1106
1041
  catch (...)
1110
1045
 
1111
1046
  if (not success)
1112
1047
  {
1113
 
    std::string error_message;
1114
 
    identifier.getSQLPath(error_message);
1115
 
 
1116
1048
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1117
 
             error_message.c_str(),
1118
1049
             table_message.InitializationErrorString().c_str());
1119
1050
    delete output;
1120
1051
 
1154
1085
  return 0;
1155
1086
}
1156
1087
 
1157
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
 
1088
class CanCreateTable: public unary_function<StorageEngine *, bool>
1158
1089
{
1159
 
  const identifier::Table &identifier;
 
1090
  const TableIdentifier &identifier;
1160
1091
 
1161
1092
public:
1162
 
  CanCreateTable(const identifier::Table &identifier_arg) :
 
1093
  CanCreateTable(const TableIdentifier &identifier_arg) :
1163
1094
    identifier(identifier_arg)
1164
1095
  { }
1165
1096
 
1173
1104
/**
1174
1105
  @note on success table can be created.
1175
1106
*/
1176
 
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
 
1107
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1177
1108
{
1178
1109
  EngineVector::iterator iter=
1179
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1180
 
                 CanCreateTable(identifier));
 
1110
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
1111
            CanCreateTable(identifier));
1181
1112
 
1182
1113
  if (iter == vector_of_engines.end())
1183
1114
  {
1189
1120
 
1190
1121
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1191
1122
{
1192
 
  std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
 
1123
  fstream input(path.c_str(), ios::in | ios::binary);
1193
1124
 
1194
1125
  if (input.good())
1195
1126
  {
1202
1133
    catch (...)
1203
1134
    {
1204
1135
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1205
 
               table_message.name().empty() ? path.c_str() : table_message.name().c_str(),
1206
1136
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1207
1137
    }
1208
1138
  }
1214
1144
  return false;
1215
1145
}
1216
1146
 
1217
 
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine)
1218
 
{
1219
 
  output << "StorageEngine:(";
1220
 
  output <<  engine.getName();
1221
 
  output << ")";
1222
1147
 
1223
 
  return output;
1224
 
}
1225
1148
 
1226
1149
} /* namespace plugin */
1227
1150
} /* namespace drizzled */