~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Monty Taylor
  • Date: 2010-08-03 18:21:58 UTC
  • mto: (1680.2.6 build)
  • mto: This revision was merged to the branch mainline in revision 1683.
  • Revision ID: mordred@inaugust.com-20100803182158-nkmgnlohodud4290
Made existence of intltool and gettext optional.

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
 
 
61
 
#include <boost/algorithm/string/compare.hpp>
62
57
 
63
58
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
64
59
 
 
60
using namespace std;
 
61
 
65
62
namespace drizzled
66
63
{
67
64
 
71
68
static EngineVector vector_of_engines;
72
69
static EngineVector vector_of_schema_engines;
73
70
 
74
 
const std::string DEFAULT_STRING("default");
75
71
const std::string UNKNOWN_STRING("UNKNOWN");
76
72
const std::string DEFAULT_DEFINITION_FILE_EXT(".dfe");
77
73
 
82
78
  return vector_of_schema_engines;
83
79
}
84
80
 
85
 
StorageEngine::StorageEngine(const std::string name_arg,
86
 
                             const std::bitset<HTON_BIT_SIZE> &flags_arg) :
 
81
StorageEngine::StorageEngine(const string name_arg,
 
82
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
87
83
  Plugin(name_arg, "StorageEngine"),
88
84
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
89
85
  flags(flags_arg)
101
97
}
102
98
 
103
99
 
104
 
int StorageEngine::renameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
100
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
105
101
{
106
102
  int error;
107
103
  setTransactionReadWrite(session);
137
133
  @retval
138
134
    !0  Error
139
135
*/
140
 
int StorageEngine::doDropTable(Session&, const identifier::Table &identifier)
 
136
int StorageEngine::doDropTable(Session&, const TableIdentifier &identifier)
141
137
                               
142
138
{
143
139
  int error= 0;
192
188
}
193
189
 
194
190
class FindEngineByName
195
 
  : public std::unary_function<StorageEngine *, bool>
 
191
  : public unary_function<StorageEngine *, bool>
196
192
{
197
 
  const std::string &predicate;
 
193
  const string &target;
198
194
 
199
195
public:
200
 
  explicit FindEngineByName(const std::string &target_arg) :
201
 
    predicate(target_arg)
 
196
  explicit FindEngineByName(const string &target_arg) :
 
197
    target(target_arg)
202
198
  {
203
199
  }
204
 
 
205
200
  result_type operator() (argument_type engine)
206
201
  {
207
 
    return boost::iequals(engine->getName(), predicate);
 
202
    string engine_name(engine->getName());
 
203
 
 
204
    transform(engine_name.begin(), engine_name.end(),
 
205
              engine_name.begin(), ::tolower);
 
206
    return engine_name == target;
208
207
  }
209
208
};
210
209
 
211
 
StorageEngine *StorageEngine::findByName(const std::string &predicate)
 
210
StorageEngine *StorageEngine::findByName(const string &find_str)
212
211
{
213
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
 
                                            vector_of_engines.end(),
215
 
                                            FindEngineByName(predicate));
 
212
  string search_string(find_str);
 
213
  transform(search_string.begin(), search_string.end(),
 
214
            search_string.begin(), ::tolower);
 
215
 
 
216
  
 
217
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
218
                                       vector_of_engines.end(),
 
219
                                       FindEngineByName(search_string));
216
220
  if (iter != vector_of_engines.end())
217
221
  {
218
222
    StorageEngine *engine= *iter;
223
227
  return NULL;
224
228
}
225
229
 
226
 
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
 
230
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
227
231
{
228
 
  if (boost::iequals(predicate, DEFAULT_STRING))
 
232
  string search_string(find_str);
 
233
  transform(search_string.begin(), search_string.end(),
 
234
            search_string.begin(), ::tolower);
 
235
 
 
236
  if (search_string.compare("default") == 0)
229
237
    return session.getDefaultStorageEngine();
230
238
 
231
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
 
                                            vector_of_engines.end(),
233
 
                                            FindEngineByName(predicate));
 
239
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
240
                                       vector_of_engines.end(),
 
241
                                       FindEngineByName(search_string));
234
242
  if (iter != vector_of_engines.end())
235
243
  {
236
244
    StorageEngine *engine= *iter;
241
249
  return NULL;
242
250
}
243
251
 
244
 
class StorageEngineCloseConnection : public std::unary_function<StorageEngine *, void>
 
252
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
245
253
{
246
254
  Session *session;
247
255
public:
263
271
*/
264
272
void StorageEngine::closeConnection(Session* session)
265
273
{
266
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
 
                StorageEngineCloseConnection(session));
 
274
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
275
           StorageEngineCloseConnection(session));
268
276
}
269
277
 
270
278
bool StorageEngine::flushLogs(StorageEngine *engine)
271
279
{
272
280
  if (engine == NULL)
273
281
  {
274
 
    if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
 
                     std::mem_fun(&StorageEngine::flush_logs))
 
282
    if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
283
                mem_fun(&StorageEngine::flush_logs))
276
284
        != vector_of_engines.begin())
277
285
      return true;
278
286
  }
284
292
  return false;
285
293
}
286
294
 
287
 
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
 
295
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
288
296
{
289
297
  Session& session;
290
 
  const identifier::Table &identifier;
 
298
  const TableIdentifier &identifier;
291
299
  message::Table &table_message;
292
 
  drizzled::error_t &err;
 
300
  int &err;
293
301
 
294
302
public:
295
303
  StorageEngineGetTableDefinition(Session& session_arg,
296
 
                                  const identifier::Table &identifier_arg,
 
304
                                  const TableIdentifier &identifier_arg,
297
305
                                  message::Table &table_message_arg,
298
 
                                  drizzled::error_t &err_arg) :
 
306
                                  int &err_arg) :
299
307
    session(session_arg), 
300
308
    identifier(identifier_arg),
301
309
    table_message(table_message_arg), 
306
314
    int ret= engine->doGetTableDefinition(session, identifier, table_message);
307
315
 
308
316
    if (ret != ENOENT)
309
 
      err= static_cast<drizzled::error_t>(ret);
 
317
      err= ret;
310
318
 
311
 
    return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
 
319
    return err == EEXIST || err != ENOENT;
312
320
  }
313
321
};
314
322
 
315
 
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
 
323
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
316
324
{
317
325
  Session& session;
318
 
  const identifier::Table &identifier;
 
326
  const TableIdentifier &identifier;
319
327
 
320
328
public:
321
 
  StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
 
329
  StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
322
330
    session(session_arg), 
323
331
    identifier(identifier_arg) 
324
332
  { }
333
341
  Utility method which hides some of the details of getTableDefinition()
334
342
*/
335
343
bool plugin::StorageEngine::doesTableExist(Session &session,
336
 
                                           const identifier::Table &identifier,
 
344
                                           const TableIdentifier &identifier,
337
345
                                           bool include_temporary_tables)
338
346
{
339
347
  if (include_temporary_tables)
343
351
  }
344
352
 
345
353
  EngineVector::iterator iter=
346
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
 
                 StorageEngineDoesTableExist(session, identifier));
 
354
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
355
            StorageEngineDoesTableExist(session, identifier));
348
356
 
349
357
  if (iter == vector_of_engines.end())
350
358
  {
354
362
  return true;
355
363
}
356
364
 
357
 
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
 
365
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
358
366
{
359
 
  std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
 
367
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
360
368
  assert(0);
361
369
  return false;
362
370
}
363
371
 
364
 
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
365
 
                                                          identifier::Table::const_reference identifier,
366
 
                                                          bool include_temporary_tables)
 
372
/**
 
373
  Call this function in order to give the Cursor the possiblity
 
374
  to ask engine if there are any new tables that should be written to disk
 
375
  or any dropped tables that need to be removed from disk
 
376
*/
 
377
int StorageEngine::getTableDefinition(Session& session,
 
378
                                      const TableIdentifier &identifier,
 
379
                                      message::Table &table_message,
 
380
                                      bool include_temporary_tables)
367
381
{
368
 
  drizzled::error_t error;
369
 
  error= static_cast<drizzled::error_t>(ENOENT);
 
382
  int err= ENOENT;
370
383
 
371
384
  if (include_temporary_tables)
372
385
  {
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;
 
386
    if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
 
387
      return EEXIST;
 
388
  }
 
389
 
387
390
  EngineVector::iterator iter=
388
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
389
 
                 StorageEngineGetTableDefinition(session, identifier, message, error));
 
391
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
392
            StorageEngineGetTableDefinition(session, identifier, table_message, err));
390
393
 
391
394
  if (iter == vector_of_engines.end())
392
395
  {
393
 
    return message::table::shared_ptr();
 
396
    return ENOENT;
394
397
  }
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;
 
398
 
 
399
  return err;
400
400
}
401
401
 
402
402
/**
409
409
{
410
410
public:
411
411
  Ha_delete_table_error_handler() : Internal_error_handler() {}
412
 
  virtual bool handle_error(drizzled::error_t sql_errno,
 
412
  virtual bool handle_error(uint32_t sql_errno,
413
413
                            const char *message,
414
414
                            DRIZZLE_ERROR::enum_warning_level level,
415
415
                            Session *session);
419
419
 
420
420
bool
421
421
Ha_delete_table_error_handler::
422
 
handle_error(drizzled::error_t ,
 
422
handle_error(uint32_t ,
423
423
             const char *message,
424
424
             DRIZZLE_ERROR::enum_warning_level ,
425
425
             Session *)
429
429
  return true;
430
430
}
431
431
 
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;
 
432
/**
 
433
   returns ENOENT if the file doesn't exists.
 
434
*/
 
435
int StorageEngine::dropTable(Session& session,
 
436
                             const TableIdentifier &identifier)
 
437
{
 
438
  int error= 0;
 
439
  int error_proto;
 
440
  message::Table src_proto;
 
441
  StorageEngine *engine;
 
442
 
 
443
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
 
444
 
 
445
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
 
446
  {
 
447
    string error_message;
 
448
 
 
449
    error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
 
450
    error_message.append(" : ");
 
451
    error_message.append(src_proto.InitializationErrorString());
 
452
 
 
453
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
 
454
 
 
455
    return ER_CORRUPT_TABLE_DEFINITION;
 
456
  }
 
457
 
 
458
  engine= StorageEngine::findByName(session, src_proto.engine().name());
 
459
 
 
460
  if (not engine)
 
461
  {
 
462
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
 
463
 
 
464
    return ER_CORRUPT_TABLE_DEFINITION;
 
465
  }
 
466
 
 
467
  error= StorageEngine::dropTable(session, *engine, identifier);
 
468
 
 
469
  if (error_proto && error == 0)
 
470
    return 0;
 
471
 
 
472
  return error;
 
473
}
 
474
 
 
475
int StorageEngine::dropTable(Session& session,
 
476
                             StorageEngine &engine,
 
477
                             const TableIdentifier &identifier)
 
478
{
 
479
  int error;
 
480
 
517
481
  engine.setTransactionReadWrite(session);
518
 
 
519
 
  assert(identifier.isTmp());
520
482
  
521
483
  if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
522
484
  {
524
486
  }
525
487
  else
526
488
  {
527
 
    error= static_cast<drizzled::error_t>(engine.doDropTable(session, identifier));
528
 
 
 
489
    error= engine.doDropTable(session, identifier);
529
490
    if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
530
491
    {
531
492
      error= ER_EVENT_OBSERVER_PLUGIN;
532
493
    }
533
494
  }
534
495
 
535
 
  drizzled::message::Cache::singleton().erase(identifier);
536
 
 
537
 
  if (error)
538
 
  {
539
 
    return false;
540
 
  }
541
 
 
542
 
  return true;
 
496
 
 
497
  return error;
543
498
}
544
499
 
545
500
 
551
506
  @retval
552
507
   1  error
553
508
*/
554
 
bool StorageEngine::createTable(Session &session,
555
 
                                const identifier::Table &identifier,
556
 
                                message::Table& table_message)
 
509
int StorageEngine::createTable(Session &session,
 
510
                               const TableIdentifier &identifier,
 
511
                               message::Table& table_message)
557
512
{
558
 
  drizzled::error_t error= EE_OK;
559
 
 
 
513
  int error= 1;
 
514
  Table table;
560
515
  TableShare share(identifier);
561
 
  table::Shell table(share);
562
516
  message::Table tmp_proto;
563
517
 
564
518
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
565
519
  { 
566
520
    // @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
521
  }
573
522
  else
574
523
  {
587
536
    {
588
537
      share.storage_engine->setTransactionReadWrite(session);
589
538
 
590
 
      error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
591
 
                                                                                table,
592
 
                                                                                identifier,
593
 
                                                                                table_message));
 
539
      error= share.storage_engine->doCreateTable(session,
 
540
                                                 table,
 
541
                                                 identifier,
 
542
                                                 table_message);
594
543
    }
595
544
 
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);
 
545
    if (error)
 
546
    {
 
547
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
605
548
    }
606
549
 
607
550
    table.delete_table();
608
551
  }
609
552
 
610
 
  return(error == EE_OK);
 
553
  return(error != 0);
611
554
}
612
555
 
613
 
Cursor *StorageEngine::getCursor(Table &arg)
 
556
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
614
557
{
615
 
  return create(arg);
 
558
  return create(share, alloc);
616
559
}
617
560
 
618
561
class AddTableIdentifier : 
619
 
  public std::unary_function<StorageEngine *, void>
 
562
  public unary_function<StorageEngine *, void>
620
563
{
621
564
  CachedDirectory &directory;
622
 
  const identifier::Schema &identifier;
623
 
  identifier::Table::vector &set_of_identifiers;
 
565
  const SchemaIdentifier &identifier;
 
566
  TableIdentifiers &set_of_identifiers;
624
567
 
625
568
public:
626
569
 
627
 
  AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
 
570
  AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
628
571
    directory(directory_arg),
629
572
    identifier(identifier_arg),
630
573
    set_of_identifiers(of_names)
638
581
};
639
582
 
640
583
 
641
 
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
 
584
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
 
585
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
 
586
 
 
587
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
642
588
{
643
589
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
644
590
 
652
598
    {
653
599
      errno= directory.getError();
654
600
      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
 
      }
 
601
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
660
602
      else
661
 
      {
662
603
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
663
 
      }
664
 
 
665
604
      return;
666
605
    }
667
606
  }
668
607
 
669
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
670
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
 
608
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
609
           AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
671
610
 
672
611
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
673
612
}
674
613
 
675
 
class DropTable: public std::unary_function<identifier::Table&, bool>
 
614
class DropTable: public unary_function<TableIdentifier&, bool>
676
615
{
677
616
  Session &session;
678
617
  StorageEngine *engine;
690
629
  } 
691
630
};
692
631
 
693
 
/* This will later be converted to identifier::Tables */
694
 
class DropTables: public std::unary_function<StorageEngine *, void>
 
632
/* This will later be converted to TableIdentifiers */
 
633
class DropTables: public unary_function<StorageEngine *, void>
695
634
{
696
635
  Session &session;
697
 
  identifier::Table::vector &table_identifiers;
 
636
  TableIdentifiers &table_identifiers;
698
637
 
699
638
public:
700
639
 
701
 
  DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
 
640
  DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
702
641
    session(session_arg),
703
642
    table_identifiers(table_identifiers_arg)
704
643
  { }
707
646
  {
708
647
    // True returning from DropTable means the table has been successfully
709
648
    // 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)),
 
649
    table_identifiers.erase(remove_if(table_identifiers.begin(),
 
650
                                      table_identifiers.end(),
 
651
                                      DropTable(session, engine)),
713
652
                            table_identifiers.end());
714
653
  }
715
654
};
722
661
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
723
662
{
724
663
  CachedDirectory dir(directory, set_of_table_definition_ext);
725
 
  identifier::Table::vector table_identifiers;
 
664
  TableIdentifiers table_identifiers;
726
665
 
727
666
  if (dir.fail())
728
667
  {
738
677
       fileIter != files.end(); fileIter++)
739
678
  {
740
679
    size_t length;
741
 
    std::string path;
 
680
    string path;
742
681
    CachedDirectory::Entry *entry= *fileIter;
743
682
 
744
683
    /* We remove the file extension. */
751
690
    message::Table definition;
752
691
    if (StorageEngine::readTableFile(path, definition))
753
692
    {
754
 
      identifier::Table identifier(definition.schema(), definition.name(), path);
 
693
      TableIdentifier identifier(definition.schema(), definition.name(), path);
755
694
      table_identifiers.push_back(identifier);
756
695
    }
757
696
  }
758
697
 
759
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
760
 
                DropTables(session, table_identifiers));
761
 
 
 
698
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
699
           DropTables(session, table_identifiers));
 
700
  
762
701
  /*
763
702
    Now we just clean up anything that might left over.
764
703
 
765
704
    We rescan because some of what might have been there should
766
705
    now be all nice and cleaned up.
767
706
  */
768
 
  std::set<std::string> all_exts= set_of_table_definition_ext;
 
707
  set<string> all_exts= set_of_table_definition_ext;
769
708
 
770
709
  for (EngineVector::iterator iter= vector_of_engines.begin();
771
710
       iter != vector_of_engines.end() ; iter++)
780
719
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
781
720
       fileIter != files.end(); fileIter++)
782
721
  {
783
 
    std::string path;
 
722
    string path;
784
723
    CachedDirectory::Entry *entry= *fileIter;
785
724
 
786
725
    path+= directory;
801
740
    - table->getShare()->path
802
741
    - table->alias
803
742
*/
804
 
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
805
 
{
806
 
  drizzled::error_t textno= ER_GET_ERRNO;
 
743
void StorageEngine::print_error(int error, myf errflag, Table &table)
 
744
{
 
745
  print_error(error, errflag, &table);
 
746
}
 
747
 
 
748
void StorageEngine::print_error(int error, myf errflag, Table *table)
 
749
{
 
750
  int textno= ER_GET_ERRNO;
807
751
  switch (error) {
808
752
  case EACCES:
809
753
    textno=ER_OPEN_AS_READONLY;
824
768
    break;
825
769
  case HA_ERR_FOUND_DUPP_KEY:
826
770
  {
827
 
    uint32_t key_nr= table.get_dup_key(error);
 
771
    assert(table);
 
772
    uint32_t key_nr= table->get_dup_key(error);
828
773
    if ((int) key_nr >= 0)
829
774
    {
830
775
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
831
776
 
832
 
      print_keydup_error(key_nr, err_msg, table);
 
777
      print_keydup_error(key_nr, err_msg, *table);
833
778
 
834
779
      return;
835
780
    }
838
783
  }
839
784
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
840
785
  {
841
 
    uint32_t key_nr= table.get_dup_key(error);
 
786
    assert(table);
 
787
    uint32_t key_nr= table->get_dup_key(error);
842
788
    if ((int) key_nr >= 0)
843
789
    {
844
790
      uint32_t max_length;
848
794
      String str(key,sizeof(key),system_charset_info);
849
795
 
850
796
      /* Table is opened and defined at this point */
851
 
      key_unpack(&str, &table,(uint32_t) key_nr);
 
797
      key_unpack(&str,table,(uint32_t) key_nr);
852
798
      max_length= (DRIZZLE_ERRMSG_SIZE-
853
799
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
854
800
      if (str.length() >= max_length)
856
802
        str.length(max_length-4);
857
803
        str.append(STRING_WITH_LEN("..."));
858
804
      }
859
 
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table.getShare()->getTableName(),
 
805
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
860
806
        str.c_ptr(), key_nr+1);
861
807
      return;
862
808
    }
879
825
    textno=ER_CRASHED_ON_USAGE;
880
826
    break;
881
827
  case HA_ERR_NOT_A_TABLE:
882
 
    textno= static_cast<drizzled::error_t>(error);
 
828
    textno= error;
883
829
    break;
884
830
  case HA_ERR_CRASHED_ON_REPAIR:
885
831
    textno=ER_CRASHED_ON_REPAIR;
933
879
    textno=ER_TABLE_DEF_CHANGED;
934
880
    break;
935
881
  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
 
    }
 
882
    assert(table);
 
883
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
 
884
             table->getShare()->getTableName());
 
885
    return;
941
886
  case HA_ERR_RBR_LOGGING_FAILED:
942
887
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
943
888
    break;
944
889
  case HA_ERR_DROP_INDEX_FK:
945
890
  {
 
891
    assert(table);
946
892
    const char *ptr= "???";
947
 
    uint32_t key_nr= table.get_dup_key(error);
 
893
    uint32_t key_nr= table->get_dup_key(error);
948
894
    if ((int) key_nr >= 0)
949
 
      ptr= table.key_info[key_nr].name;
 
895
      ptr= table->key_info[key_nr].name;
950
896
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
951
897
    return;
952
898
  }
991
937
      return;
992
938
    }
993
939
  }
994
 
 
995
 
  my_error(textno, errflag, table.getShare()->getTableName(), error);
 
940
  my_error(textno, errflag, table->getShare()->getTableName(), error);
996
941
}
997
942
 
998
943
 
1005
950
  @return
1006
951
    Returns true if this is a temporary error
1007
952
*/
1008
 
bool StorageEngine::get_error_message(int , String* ) const
 
953
bool StorageEngine::get_error_message(int , String* )
1009
954
{
1010
955
  return false;
1011
956
}
1012
957
 
1013
958
 
1014
 
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
 
959
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1015
960
{
1016
961
  /* Write the duplicated key in the error message */
1017
962
  char key[MAX_KEY_LENGTH];
1039
984
}
1040
985
 
1041
986
 
1042
 
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
 
987
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1043
988
{
1044
 
  std::string path(identifier.getPath());
 
989
  string path(identifier.getPath());
1045
990
 
1046
991
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1047
992
 
1048
993
  return internal::my_delete(path.c_str(), MYF(0));
1049
994
}
1050
995
 
1051
 
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
 
996
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1052
997
{
1053
998
  message::Table table_message;
1054
 
  std::string src_path(src.getPath());
1055
 
  std::string dest_path(dest.getPath());
 
999
  string src_path(src.getPath());
 
1000
  string dest_path(dest.getPath());
1056
1001
 
1057
1002
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1058
1003
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1077
1022
  return error;
1078
1023
}
1079
1024
 
1080
 
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, message::Table &table_message)
 
1025
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1081
1026
{
1082
1027
  char definition_file_tmp[FN_REFLEN];
1083
 
  std::string file_name(identifier.getPath());
 
1028
  string file_name(identifier.getPath());
1084
1029
 
1085
1030
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1086
1031
 
1099
1044
 
1100
1045
  bool success;
1101
1046
 
1102
 
  try
1103
 
  {
 
1047
  try {
1104
1048
    success= table_message.SerializeToZeroCopyStream(output);
1105
1049
  }
1106
1050
  catch (...)
1110
1054
 
1111
1055
  if (not success)
1112
1056
  {
1113
 
    std::string error_message;
1114
 
    identifier.getSQLPath(error_message);
1115
 
 
1116
1057
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1117
 
             error_message.c_str(),
1118
1058
             table_message.InitializationErrorString().c_str());
1119
1059
    delete output;
1120
1060
 
1154
1094
  return 0;
1155
1095
}
1156
1096
 
1157
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
 
1097
class CanCreateTable: public unary_function<StorageEngine *, bool>
1158
1098
{
1159
 
  const identifier::Table &identifier;
 
1099
  const TableIdentifier &identifier;
1160
1100
 
1161
1101
public:
1162
 
  CanCreateTable(const identifier::Table &identifier_arg) :
 
1102
  CanCreateTable(const TableIdentifier &identifier_arg) :
1163
1103
    identifier(identifier_arg)
1164
1104
  { }
1165
1105
 
1173
1113
/**
1174
1114
  @note on success table can be created.
1175
1115
*/
1176
 
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
 
1116
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1177
1117
{
1178
1118
  EngineVector::iterator iter=
1179
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1180
 
                 CanCreateTable(identifier));
 
1119
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
1120
            CanCreateTable(identifier));
1181
1121
 
1182
1122
  if (iter == vector_of_engines.end())
1183
1123
  {
1189
1129
 
1190
1130
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1191
1131
{
1192
 
  std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
 
1132
  fstream input(path.c_str(), ios::in | ios::binary);
1193
1133
 
1194
1134
  if (input.good())
1195
1135
  {
1202
1142
    catch (...)
1203
1143
    {
1204
1144
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1205
 
               table_message.name().empty() ? path.c_str() : table_message.name().c_str(),
1206
1145
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1207
1146
    }
1208
1147
  }
1214
1153
  return false;
1215
1154
}
1216
1155
 
1217
 
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine)
1218
 
{
1219
 
  output << "StorageEngine:(";
1220
 
  output <<  engine.getName();
1221
 
  output << ")";
1222
1156
 
1223
 
  return output;
1224
 
}
1225
1157
 
1226
1158
} /* namespace plugin */
1227
1159
} /* namespace drizzled */