~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

Added some special case code for directory handling on solaris.

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
 
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
 
518
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, "", 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));
594
 
    }
595
 
 
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);
605
 
    }
606
 
 
607
 
    table.delete_table();
608
 
  }
609
 
 
610
 
  return(error == EE_OK);
611
 
}
612
 
 
613
 
Cursor *StorageEngine::getCursor(Table &arg)
614
 
{
615
 
  return create(arg);
616
 
}
 
539
      error= share.storage_engine->doCreateTable(session,
 
540
                                                 table,
 
541
                                                 identifier,
 
542
                                                 table_message);
 
543
    }
 
544
 
 
545
    if (error)
 
546
    {
 
547
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
 
548
    }
 
549
 
 
550
    table.delete_table(false);
 
551
  }
 
552
 
 
553
  return(error != 0);
 
554
}
 
555
 
 
556
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
 
557
{
 
558
  return create(share, alloc);
 
559
}
 
560
 
 
561
class AddTableName : 
 
562
  public unary_function<StorageEngine *, void>
 
563
{
 
564
  CachedDirectory &directory;
 
565
  SchemaIdentifier &identifier;
 
566
  TableNameList &set_of_names;
 
567
 
 
568
public:
 
569
 
 
570
  AddTableName(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, set<string>& of_names) :
 
571
    directory(directory_arg),
 
572
    identifier(identifier_arg),
 
573
    set_of_names(of_names)
 
574
  {
 
575
  }
 
576
 
 
577
  result_type operator() (argument_type engine)
 
578
  {
 
579
    engine->doGetTableNames(directory, identifier, set_of_names);
 
580
  }
 
581
};
617
582
 
618
583
class AddTableIdentifier : 
619
 
  public std::unary_function<StorageEngine *, void>
 
584
  public unary_function<StorageEngine *, void>
620
585
{
621
586
  CachedDirectory &directory;
622
 
  const identifier::Schema &identifier;
623
 
  identifier::Table::vector &set_of_identifiers;
 
587
  SchemaIdentifier &identifier;
 
588
  TableIdentifiers &set_of_identifiers;
624
589
 
625
590
public:
626
591
 
627
 
  AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
 
592
  AddTableIdentifier(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
628
593
    directory(directory_arg),
629
594
    identifier(identifier_arg),
630
595
    set_of_identifiers(of_names)
638
603
};
639
604
 
640
605
 
641
 
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
642
 
{
643
 
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
644
 
 
645
 
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
646
 
  { }
647
 
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
648
 
  { }
649
 
  else
650
 
  {
651
 
    if (directory.fail())
652
 
    {
653
 
      errno= directory.getError();
654
 
      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
 
      }
660
 
      else
661
 
      {
662
 
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
663
 
      }
664
 
 
665
 
      return;
666
 
    }
667
 
  }
668
 
 
669
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
670
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
 
606
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
 
607
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
 
608
 
 
609
void StorageEngine::getTableNames(Session &session, SchemaIdentifier &schema_identifier, TableNameList &set_of_names)
 
610
{
 
611
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
 
612
 
 
613
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
 
614
  { }
 
615
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
 
616
  { }
 
617
  else
 
618
  {
 
619
    if (directory.fail())
 
620
    {
 
621
      errno= directory.getError();
 
622
      if (errno == ENOENT)
 
623
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
 
624
      else
 
625
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
 
626
      return;
 
627
    }
 
628
  }
 
629
 
 
630
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
631
           AddTableName(directory, schema_identifier, set_of_names));
 
632
 
 
633
  session.doGetTableNames(directory, schema_identifier, set_of_names);
 
634
}
 
635
 
 
636
void StorageEngine::getTableIdentifiers(Session &session, SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
 
637
{
 
638
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
 
639
 
 
640
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
 
641
  { }
 
642
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
 
643
  { }
 
644
  else
 
645
  {
 
646
    if (directory.fail())
 
647
    {
 
648
      errno= directory.getError();
 
649
      if (errno == ENOENT)
 
650
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
 
651
      else
 
652
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
 
653
      return;
 
654
    }
 
655
  }
 
656
 
 
657
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
658
           AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
671
659
 
672
660
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
673
661
}
674
662
 
675
 
class DropTable: public std::unary_function<identifier::Table&, bool>
 
663
class DropTable: public unary_function<TableIdentifier&, bool>
676
664
{
677
665
  Session &session;
678
666
  StorageEngine *engine;
690
678
  } 
691
679
};
692
680
 
693
 
/* This will later be converted to identifier::Tables */
694
 
class DropTables: public std::unary_function<StorageEngine *, void>
 
681
/* This will later be converted to TableIdentifiers */
 
682
class DropTables: public unary_function<StorageEngine *, void>
695
683
{
696
684
  Session &session;
697
 
  identifier::Table::vector &table_identifiers;
 
685
  TableIdentifierList &table_identifiers;
698
686
 
699
687
public:
700
688
 
701
 
  DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
 
689
  DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
702
690
    session(session_arg),
703
691
    table_identifiers(table_identifiers_arg)
704
692
  { }
707
695
  {
708
696
    // True returning from DropTable means the table has been successfully
709
697
    // 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)),
 
698
    table_identifiers.erase(remove_if(table_identifiers.begin(),
 
699
                                      table_identifiers.end(),
 
700
                                      DropTable(session, engine)),
713
701
                            table_identifiers.end());
714
702
  }
715
703
};
722
710
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
723
711
{
724
712
  CachedDirectory dir(directory, set_of_table_definition_ext);
725
 
  identifier::Table::vector table_identifiers;
 
713
  TableIdentifierList table_identifiers;
726
714
 
727
715
  if (dir.fail())
728
716
  {
738
726
       fileIter != files.end(); fileIter++)
739
727
  {
740
728
    size_t length;
741
 
    std::string path;
 
729
    string path;
742
730
    CachedDirectory::Entry *entry= *fileIter;
743
731
 
744
732
    /* We remove the file extension. */
751
739
    message::Table definition;
752
740
    if (StorageEngine::readTableFile(path, definition))
753
741
    {
754
 
      identifier::Table identifier(definition.schema(), definition.name(), path);
 
742
      TableIdentifier identifier(definition.schema(), definition.name(), path);
755
743
      table_identifiers.push_back(identifier);
756
744
    }
757
745
  }
758
746
 
759
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
760
 
                DropTables(session, table_identifiers));
761
 
 
 
747
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
748
           DropTables(session, table_identifiers));
 
749
  
762
750
  /*
763
751
    Now we just clean up anything that might left over.
764
752
 
765
753
    We rescan because some of what might have been there should
766
754
    now be all nice and cleaned up.
767
755
  */
768
 
  std::set<std::string> all_exts= set_of_table_definition_ext;
 
756
  set<string> all_exts= set_of_table_definition_ext;
769
757
 
770
758
  for (EngineVector::iterator iter= vector_of_engines.begin();
771
759
       iter != vector_of_engines.end() ; iter++)
780
768
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
781
769
       fileIter != files.end(); fileIter++)
782
770
  {
783
 
    std::string path;
 
771
    string path;
784
772
    CachedDirectory::Entry *entry= *fileIter;
785
773
 
786
774
    path+= directory;
801
789
    - table->getShare()->path
802
790
    - table->alias
803
791
*/
804
 
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
805
 
{
806
 
  drizzled::error_t textno= ER_GET_ERRNO;
 
792
void StorageEngine::print_error(int error, myf errflag, Table &table)
 
793
{
 
794
  print_error(error, errflag, &table);
 
795
}
 
796
 
 
797
void StorageEngine::print_error(int error, myf errflag, Table *table)
 
798
{
 
799
  int textno= ER_GET_ERRNO;
807
800
  switch (error) {
808
801
  case EACCES:
809
802
    textno=ER_OPEN_AS_READONLY;
824
817
    break;
825
818
  case HA_ERR_FOUND_DUPP_KEY:
826
819
  {
827
 
    uint32_t key_nr= table.get_dup_key(error);
 
820
    assert(table);
 
821
    uint32_t key_nr= table->get_dup_key(error);
828
822
    if ((int) key_nr >= 0)
829
823
    {
830
824
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
831
825
 
832
 
      print_keydup_error(key_nr, err_msg, table);
 
826
      print_keydup_error(key_nr, err_msg, *table);
833
827
 
834
828
      return;
835
829
    }
838
832
  }
839
833
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
840
834
  {
841
 
    uint32_t key_nr= table.get_dup_key(error);
 
835
    assert(table);
 
836
    uint32_t key_nr= table->get_dup_key(error);
842
837
    if ((int) key_nr >= 0)
843
838
    {
844
839
      uint32_t max_length;
848
843
      String str(key,sizeof(key),system_charset_info);
849
844
 
850
845
      /* Table is opened and defined at this point */
851
 
      key_unpack(&str, &table,(uint32_t) key_nr);
 
846
      key_unpack(&str,table,(uint32_t) key_nr);
852
847
      max_length= (DRIZZLE_ERRMSG_SIZE-
853
848
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
854
849
      if (str.length() >= max_length)
856
851
        str.length(max_length-4);
857
852
        str.append(STRING_WITH_LEN("..."));
858
853
      }
859
 
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table.getShare()->getTableName(),
 
854
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
860
855
        str.c_ptr(), key_nr+1);
861
856
      return;
862
857
    }
879
874
    textno=ER_CRASHED_ON_USAGE;
880
875
    break;
881
876
  case HA_ERR_NOT_A_TABLE:
882
 
    textno= static_cast<drizzled::error_t>(error);
 
877
    textno= error;
883
878
    break;
884
879
  case HA_ERR_CRASHED_ON_REPAIR:
885
880
    textno=ER_CRASHED_ON_REPAIR;
933
928
    textno=ER_TABLE_DEF_CHANGED;
934
929
    break;
935
930
  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
 
    }
 
931
    assert(table);
 
932
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
 
933
             table->getShare()->getTableName());
 
934
    return;
941
935
  case HA_ERR_RBR_LOGGING_FAILED:
942
936
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
943
937
    break;
944
938
  case HA_ERR_DROP_INDEX_FK:
945
939
  {
 
940
    assert(table);
946
941
    const char *ptr= "???";
947
 
    uint32_t key_nr= table.get_dup_key(error);
 
942
    uint32_t key_nr= table->get_dup_key(error);
948
943
    if ((int) key_nr >= 0)
949
 
      ptr= table.key_info[key_nr].name;
 
944
      ptr= table->key_info[key_nr].name;
950
945
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
951
946
    return;
952
947
  }
991
986
      return;
992
987
    }
993
988
  }
994
 
 
995
 
  my_error(textno, errflag, table.getShare()->getTableName(), error);
 
989
  my_error(textno, errflag, table->getShare()->getTableName(), error);
996
990
}
997
991
 
998
992
 
1005
999
  @return
1006
1000
    Returns true if this is a temporary error
1007
1001
*/
1008
 
bool StorageEngine::get_error_message(int , String* ) const
 
1002
bool StorageEngine::get_error_message(int , String* )
1009
1003
{
1010
1004
  return false;
1011
1005
}
1012
1006
 
1013
1007
 
1014
 
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
 
1008
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1015
1009
{
1016
1010
  /* Write the duplicated key in the error message */
1017
1011
  char key[MAX_KEY_LENGTH];
1039
1033
}
1040
1034
 
1041
1035
 
1042
 
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
 
1036
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1043
1037
{
1044
 
  std::string path(identifier.getPath());
 
1038
  string path(identifier.getPath());
1045
1039
 
1046
1040
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1047
1041
 
1048
1042
  return internal::my_delete(path.c_str(), MYF(0));
1049
1043
}
1050
1044
 
1051
 
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
 
1045
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1052
1046
{
1053
1047
  message::Table table_message;
1054
 
  std::string src_path(src.getPath());
1055
 
  std::string dest_path(dest.getPath());
 
1048
  string src_path(src.getPath());
 
1049
  string dest_path(dest.getPath());
1056
1050
 
1057
1051
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1058
1052
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1077
1071
  return error;
1078
1072
}
1079
1073
 
1080
 
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, message::Table &table_message)
 
1074
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1081
1075
{
1082
1076
  char definition_file_tmp[FN_REFLEN];
1083
 
  std::string file_name(identifier.getPath());
 
1077
  string file_name(identifier.getPath());
1084
1078
 
1085
1079
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1086
1080
 
1099
1093
 
1100
1094
  bool success;
1101
1095
 
1102
 
  try
1103
 
  {
 
1096
  try {
1104
1097
    success= table_message.SerializeToZeroCopyStream(output);
1105
1098
  }
1106
1099
  catch (...)
1110
1103
 
1111
1104
  if (not success)
1112
1105
  {
1113
 
    std::string error_message;
1114
 
    identifier.getSQLPath(error_message);
1115
 
 
1116
1106
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1117
 
             error_message.c_str(),
1118
1107
             table_message.InitializationErrorString().c_str());
1119
1108
    delete output;
1120
1109
 
1154
1143
  return 0;
1155
1144
}
1156
1145
 
1157
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
 
1146
class CanCreateTable: public unary_function<StorageEngine *, bool>
1158
1147
{
1159
 
  const identifier::Table &identifier;
 
1148
  const TableIdentifier &identifier;
1160
1149
 
1161
1150
public:
1162
 
  CanCreateTable(const identifier::Table &identifier_arg) :
 
1151
  CanCreateTable(const TableIdentifier &identifier_arg) :
1163
1152
    identifier(identifier_arg)
1164
1153
  { }
1165
1154
 
1173
1162
/**
1174
1163
  @note on success table can be created.
1175
1164
*/
1176
 
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
 
1165
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1177
1166
{
1178
1167
  EngineVector::iterator iter=
1179
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1180
 
                 CanCreateTable(identifier));
 
1168
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
1169
            CanCreateTable(identifier));
1181
1170
 
1182
1171
  if (iter == vector_of_engines.end())
1183
1172
  {
1189
1178
 
1190
1179
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1191
1180
{
1192
 
  std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
 
1181
  fstream input(path.c_str(), ios::in | ios::binary);
1193
1182
 
1194
1183
  if (input.good())
1195
1184
  {
1202
1191
    catch (...)
1203
1192
    {
1204
1193
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1205
 
               table_message.name().empty() ? path.c_str() : table_message.name().c_str(),
1206
1194
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1207
1195
    }
1208
1196
  }
1214
1202
  return false;
1215
1203
}
1216
1204
 
1217
 
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine)
1218
 
{
1219
 
  output << "StorageEngine:(";
1220
 
  output <<  engine.getName();
1221
 
  output << ")";
1222
1205
 
1223
 
  return output;
1224
 
}
1225
1206
 
1226
1207
} /* namespace plugin */
1227
1208
} /* namespace drizzled */