~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

Add Solaris atomics fixes and test files. Add replication.h header to makefile.

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
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/my_hash.h"
35
36
#include "drizzled/cached_directory.h"
36
37
 
37
38
#include <drizzled/definitions.h>
47
48
#include "drizzled/xid.h"
48
49
#include "drizzled/sql_table.h"
49
50
#include "drizzled/global_charset_info.h"
 
51
#include "drizzled/plugin/authorization.h"
50
52
#include "drizzled/charset.h"
51
53
#include "drizzled/internal/my_sys.h"
52
54
#include "drizzled/db.h"
53
55
 
54
56
#include <drizzled/table_proto.h>
55
 
#include <drizzled/plugin/event_observer.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
 
70
67
 
71
68
static EngineVector vector_of_engines;
72
69
static EngineVector vector_of_schema_engines;
 
70
static EngineVector vector_of_data_dictionary;
73
71
 
74
 
const std::string DEFAULT_STRING("default");
75
72
const std::string UNKNOWN_STRING("UNKNOWN");
76
73
const std::string DEFAULT_DEFINITION_FILE_EXT(".dfe");
77
74
 
78
75
static std::set<std::string> set_of_table_definition_ext;
79
76
 
80
 
EngineVector &StorageEngine::getSchemaEngines()
81
 
{
82
 
  return vector_of_schema_engines;
83
 
}
84
 
 
85
 
StorageEngine::StorageEngine(const std::string name_arg,
86
 
                             const std::bitset<HTON_BIT_SIZE> &flags_arg) :
 
77
StorageEngine::StorageEngine(const string name_arg,
 
78
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
87
79
  Plugin(name_arg, "StorageEngine"),
88
80
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
89
81
  flags(flags_arg)
101
93
}
102
94
 
103
95
 
104
 
int StorageEngine::renameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
96
int StorageEngine::renameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
105
97
{
106
 
  int error;
107
98
  setTransactionReadWrite(session);
108
99
 
109
 
  if (unlikely(plugin::EventObserver::beforeRenameTable(session, from, to)))
110
 
  {
111
 
    error= ER_EVENT_OBSERVER_PLUGIN;
112
 
  }
113
 
  else
114
 
  {
115
 
    error =  doRenameTable(session, from, to);
116
 
    if (unlikely(plugin::EventObserver::afterRenameTable(session, from, to, error)))
117
 
    {
118
 
      error= ER_EVENT_OBSERVER_PLUGIN;
119
 
    }
120
 
  }
121
 
  
122
 
  return error;
 
100
  return doRenameTable(session, from, to);
123
101
}
124
102
 
125
103
/**
137
115
  @retval
138
116
    !0  Error
139
117
*/
140
 
int StorageEngine::doDropTable(Session&, const identifier::Table &identifier)
 
118
int StorageEngine::doDropTable(Session&, TableIdentifier &identifier)
141
119
                               
142
120
{
143
121
  int error= 0;
177
155
  if (engine->check_flag(HTON_BIT_SCHEMA_DICTIONARY))
178
156
    vector_of_schema_engines.push_back(engine);
179
157
 
 
158
  if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
 
159
    vector_of_data_dictionary.push_back(engine);
 
160
 
180
161
  return false;
181
162
}
182
163
 
186
167
  {
187
168
    vector_of_engines.clear();
188
169
    vector_of_schema_engines.clear();
 
170
    vector_of_data_dictionary.clear();
189
171
 
190
172
    shutdown_has_begun= true;
191
173
  }
192
174
}
193
175
 
194
176
class FindEngineByName
195
 
  : public std::unary_function<StorageEngine *, bool>
 
177
  : public unary_function<StorageEngine *, bool>
196
178
{
197
 
  const std::string &predicate;
 
179
  const string &target;
198
180
 
199
181
public:
200
 
  explicit FindEngineByName(const std::string &target_arg) :
201
 
    predicate(target_arg)
 
182
  explicit FindEngineByName(const string &target_arg) :
 
183
    target(target_arg)
202
184
  {
203
185
  }
204
 
 
205
186
  result_type operator() (argument_type engine)
206
187
  {
207
 
    return boost::iequals(engine->getName(), predicate);
 
188
    string engine_name(engine->getName());
 
189
 
 
190
    transform(engine_name.begin(), engine_name.end(),
 
191
              engine_name.begin(), ::tolower);
 
192
    return engine_name == target;
208
193
  }
209
194
};
210
195
 
211
 
StorageEngine *StorageEngine::findByName(const std::string &predicate)
 
196
StorageEngine *StorageEngine::findByName(const string &find_str)
212
197
{
213
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
 
                                            vector_of_engines.end(),
215
 
                                            FindEngineByName(predicate));
 
198
  string search_string(find_str);
 
199
  transform(search_string.begin(), search_string.end(),
 
200
            search_string.begin(), ::tolower);
 
201
 
 
202
  
 
203
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
204
                                       vector_of_engines.end(),
 
205
                                       FindEngineByName(search_string));
216
206
  if (iter != vector_of_engines.end())
217
207
  {
218
208
    StorageEngine *engine= *iter;
223
213
  return NULL;
224
214
}
225
215
 
226
 
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
 
216
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
227
217
{
228
 
  if (boost::iequals(predicate, DEFAULT_STRING))
 
218
  string search_string(find_str);
 
219
  transform(search_string.begin(), search_string.end(),
 
220
            search_string.begin(), ::tolower);
 
221
 
 
222
  if (search_string.compare("default") == 0)
229
223
    return session.getDefaultStorageEngine();
230
224
 
231
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
 
                                            vector_of_engines.end(),
233
 
                                            FindEngineByName(predicate));
 
225
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
226
                                       vector_of_engines.end(),
 
227
                                       FindEngineByName(search_string));
234
228
  if (iter != vector_of_engines.end())
235
229
  {
236
230
    StorageEngine *engine= *iter;
241
235
  return NULL;
242
236
}
243
237
 
244
 
class StorageEngineCloseConnection : public std::unary_function<StorageEngine *, void>
 
238
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
245
239
{
246
240
  Session *session;
247
241
public:
263
257
*/
264
258
void StorageEngine::closeConnection(Session* session)
265
259
{
266
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
 
                StorageEngineCloseConnection(session));
 
260
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
261
           StorageEngineCloseConnection(session));
268
262
}
269
263
 
270
264
bool StorageEngine::flushLogs(StorageEngine *engine)
271
265
{
272
266
  if (engine == NULL)
273
267
  {
274
 
    if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
 
                     std::mem_fun(&StorageEngine::flush_logs))
 
268
    if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
269
                mem_fun(&StorageEngine::flush_logs))
276
270
        != vector_of_engines.begin())
277
271
      return true;
278
272
  }
284
278
  return false;
285
279
}
286
280
 
287
 
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
 
281
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
288
282
{
289
283
  Session& session;
290
 
  const identifier::Table &identifier;
 
284
  TableIdentifier &identifier;
291
285
  message::Table &table_message;
292
 
  drizzled::error_t &err;
 
286
  int &err;
293
287
 
294
288
public:
295
289
  StorageEngineGetTableDefinition(Session& session_arg,
296
 
                                  const identifier::Table &identifier_arg,
 
290
                                  TableIdentifier &identifier_arg,
297
291
                                  message::Table &table_message_arg,
298
 
                                  drizzled::error_t &err_arg) :
 
292
                                  int &err_arg) :
299
293
    session(session_arg), 
300
294
    identifier(identifier_arg),
301
295
    table_message(table_message_arg), 
306
300
    int ret= engine->doGetTableDefinition(session, identifier, table_message);
307
301
 
308
302
    if (ret != ENOENT)
309
 
      err= static_cast<drizzled::error_t>(ret);
 
303
      err= ret;
310
304
 
311
 
    return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
 
305
    return err == EEXIST || err != ENOENT;
312
306
  }
313
307
};
314
308
 
315
 
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
 
309
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
316
310
{
317
311
  Session& session;
318
 
  const identifier::Table &identifier;
 
312
  TableIdentifier &identifier;
319
313
 
320
314
public:
321
 
  StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
 
315
  StorageEngineDoesTableExist(Session& session_arg, TableIdentifier &identifier_arg) :
322
316
    session(session_arg), 
323
317
    identifier(identifier_arg) 
324
318
  { }
333
327
  Utility method which hides some of the details of getTableDefinition()
334
328
*/
335
329
bool plugin::StorageEngine::doesTableExist(Session &session,
336
 
                                           const identifier::Table &identifier,
 
330
                                           TableIdentifier &identifier,
337
331
                                           bool include_temporary_tables)
338
332
{
339
333
  if (include_temporary_tables)
343
337
  }
344
338
 
345
339
  EngineVector::iterator iter=
346
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
 
                 StorageEngineDoesTableExist(session, identifier));
 
340
    find_if(vector_of_data_dictionary.begin(), vector_of_data_dictionary.end(),
 
341
            StorageEngineDoesTableExist(session, identifier));
348
342
 
349
 
  if (iter == vector_of_engines.end())
 
343
  if (iter == vector_of_data_dictionary.end())
350
344
  {
351
345
    return false;
352
346
  }
354
348
  return true;
355
349
}
356
350
 
357
 
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
 
351
bool plugin::StorageEngine::doDoesTableExist(Session&, TableIdentifier&)
358
352
{
359
 
  std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
 
353
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
360
354
  assert(0);
361
355
  return false;
362
356
}
367
361
  or any dropped tables that need to be removed from disk
368
362
*/
369
363
int StorageEngine::getTableDefinition(Session& session,
370
 
                                      const identifier::Table &identifier,
371
 
                                      message::table::shared_ptr &table_message,
 
364
                                      TableIdentifier &identifier,
 
365
                                      message::Table &table_message,
372
366
                                      bool include_temporary_tables)
373
367
{
374
 
  drizzled::error_t err= static_cast<drizzled::error_t>(ENOENT);
 
368
  int err= ENOENT;
375
369
 
376
370
  if (include_temporary_tables)
377
371
  {
378
 
    Table *table= session.find_temporary_table(identifier);
379
 
    if (table)
380
 
    {
381
 
      table_message.reset(new message::Table(*table->getShare()->getTableMessage()));
 
372
    if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
382
373
      return EEXIST;
383
 
    }
384
 
  }
385
 
 
386
 
  drizzled::message::table::shared_ptr table_ptr;
387
 
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
388
 
  {
389
 
    table_message= table_ptr;
390
 
  }
391
 
 
392
 
  message::Table message;
 
374
  }
 
375
 
393
376
  EngineVector::iterator iter=
394
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
395
 
                 StorageEngineGetTableDefinition(session, identifier, message, err));
 
377
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
378
            StorageEngineGetTableDefinition(session, identifier, table_message, err));
396
379
 
397
380
  if (iter == vector_of_engines.end())
398
381
  {
399
382
    return ENOENT;
400
383
  }
401
 
  table_message.reset(new message::Table(message));
402
 
 
403
 
 drizzled::message::Cache::singleton().insert(identifier, table_message);
404
384
 
405
385
  return err;
406
386
}
407
387
 
408
 
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
409
 
                                                          identifier::Table::const_reference identifier,
410
 
                                                          drizzled::error_t &error,
411
 
                                                          bool include_temporary_tables)
412
 
{
413
 
  error= static_cast<drizzled::error_t>(ENOENT);
414
 
 
415
 
  if (include_temporary_tables)
416
 
  {
417
 
    Table *table= session.find_temporary_table(identifier);
418
 
    if (table)
419
 
    {
420
 
      error= EE_OK;
421
 
      return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
422
 
    }
423
 
  }
424
 
 
425
 
  drizzled::message::table::shared_ptr table_ptr;
426
 
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
427
 
  {
428
 
    (void)table_ptr;
429
 
  }
430
 
 
431
 
  message::Table message;
432
 
  EngineVector::iterator iter=
433
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
434
 
                 StorageEngineGetTableDefinition(session, identifier, message, error));
435
 
 
436
 
  if (iter == vector_of_engines.end())
437
 
  {
438
 
    error= static_cast<drizzled::error_t>(ENOENT);
439
 
    return message::table::shared_ptr();
440
 
  }
441
 
  message::table::shared_ptr table_message(new message::Table(message));
442
 
 
443
 
  drizzled::message::Cache::singleton().insert(identifier, table_message);
444
 
 
445
 
  return table_message;
446
 
}
447
 
 
448
388
/**
449
389
  An interceptor to hijack the text of the error message without
450
390
  setting an error in the thread. We need the text to present it
455
395
{
456
396
public:
457
397
  Ha_delete_table_error_handler() : Internal_error_handler() {}
458
 
  virtual bool handle_error(drizzled::error_t sql_errno,
 
398
  virtual bool handle_error(uint32_t sql_errno,
459
399
                            const char *message,
460
400
                            DRIZZLE_ERROR::enum_warning_level level,
461
401
                            Session *session);
465
405
 
466
406
bool
467
407
Ha_delete_table_error_handler::
468
 
handle_error(drizzled::error_t ,
 
408
handle_error(uint32_t ,
469
409
             const char *message,
470
410
             DRIZZLE_ERROR::enum_warning_level ,
471
411
             Session *)
475
415
  return true;
476
416
}
477
417
 
478
 
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
 
418
class DropTable : 
 
419
  public unary_function<StorageEngine *, void>
479
420
{
480
 
  Session::reference session;
481
 
  identifier::Table::const_reference identifier;
482
 
  drizzled::error_t &error;
 
421
  uint64_t &success_count;
 
422
  TableIdentifier &identifier;
 
423
  Session &session;
483
424
 
484
425
public:
485
426
 
486
 
  DropTableByIdentifier(Session::reference session_arg,
487
 
                        identifier::Table::const_reference identifier_arg,
488
 
                        drizzled::error_t &error_arg) :
489
 
    session(session_arg),
490
 
    identifier(identifier_arg),
491
 
    error(error_arg)
492
 
  { }
 
427
  DropTable(Session &session_arg, TableIdentifier &arg, uint64_t &count_arg) :
 
428
    success_count(count_arg),
 
429
    identifier(arg),
 
430
    session(session_arg)
 
431
  {
 
432
  }
493
433
 
494
434
  result_type operator() (argument_type engine)
495
435
  {
496
 
    if (not engine->doDoesTableExist(session, identifier))
497
 
      return false;
498
 
 
499
 
    int local_error= engine->doDropTable(session, identifier);
500
 
 
501
 
 
502
 
    if (not local_error)
503
 
      return true;
504
 
 
505
 
    switch (local_error)
506
 
    {
507
 
    case HA_ERR_NO_SUCH_TABLE:
508
 
    case ENOENT:
509
 
      error= static_cast<drizzled::error_t>(HA_ERR_NO_SUCH_TABLE);
510
 
      return false;
511
 
 
512
 
    default:
513
 
      error= static_cast<drizzled::error_t>(local_error);
514
 
      return true;
515
 
    }
516
 
  } 
 
436
    bool success= engine->doDropTable(session, identifier);
 
437
 
 
438
    if (success)
 
439
      success_count++;
 
440
  }
517
441
};
518
442
 
519
443
 
520
 
bool StorageEngine::dropTable(Session::reference session,
521
 
                              identifier::Table::const_reference identifier,
522
 
                              drizzled::error_t &error)
523
 
{
524
 
  error= EE_OK;
525
 
 
526
 
  EngineVector::const_iterator iter= std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
527
 
                                                  DropTableByIdentifier(session, identifier, error));
528
 
 
529
 
  if (error)
530
 
  {
531
 
    return false;
532
 
  }
533
 
  else if (iter == vector_of_engines.end())
534
 
  {
535
 
    error= ER_BAD_TABLE_ERROR;
536
 
    return false;
537
 
  }
538
 
 
539
 
  drizzled::message::Cache::singleton().erase(identifier);
540
 
 
541
 
  return true;
542
 
}
543
 
 
544
 
bool StorageEngine::dropTable(Session& session,
545
 
                              const identifier::Table &identifier)
546
 
{
547
 
  drizzled::error_t error;
548
 
 
549
 
  if (not dropTable(session, identifier, error))
550
 
  {
551
 
    return false;
552
 
  }
553
 
 
554
 
  return true;
555
 
}
556
 
 
557
 
bool StorageEngine::dropTable(Session::reference session,
558
 
                              StorageEngine &engine,
559
 
                              identifier::Table::const_reference identifier,
560
 
                              drizzled::error_t &error)
561
 
{
562
 
  error= EE_OK;
 
444
/**
 
445
   returns ENOENT if the file doesn't exists.
 
446
*/
 
447
int StorageEngine::dropTable(Session& session,
 
448
                             TableIdentifier &identifier)
 
449
{
 
450
  int error= 0;
 
451
  int error_proto;
 
452
  message::Table src_proto;
 
453
  StorageEngine *engine;
 
454
 
 
455
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
 
456
 
 
457
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
 
458
  {
 
459
    string error_message;
 
460
 
 
461
    error_message.append(identifier.getSQLPath());
 
462
    error_message.append(" : ");
 
463
    error_message.append(src_proto.InitializationErrorString());
 
464
 
 
465
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
 
466
 
 
467
    return ER_CORRUPT_TABLE_DEFINITION;
 
468
  }
 
469
 
 
470
  engine= StorageEngine::findByName(session, src_proto.engine().name());
 
471
 
 
472
  if (engine)
 
473
  {
 
474
    error= StorageEngine::dropTable(session, *engine, identifier);
 
475
  }
 
476
 
 
477
  if (error_proto && error == 0)
 
478
    return 0;
 
479
 
 
480
  return error;
 
481
}
 
482
 
 
483
int StorageEngine::dropTable(Session& session,
 
484
                             StorageEngine &engine,
 
485
                             TableIdentifier &identifier)
 
486
{
 
487
  int error;
 
488
 
563
489
  engine.setTransactionReadWrite(session);
564
 
 
565
 
  assert(identifier.isTmp());
566
 
  
567
 
  if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
568
 
  {
569
 
    error= ER_EVENT_OBSERVER_PLUGIN;
570
 
  }
571
 
  else
572
 
  {
573
 
    error= static_cast<drizzled::error_t>(engine.doDropTable(session, identifier));
574
 
 
575
 
    if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
 
490
  error= engine.doDropTable(session, identifier);
 
491
 
 
492
  if (not error)
 
493
  {
 
494
    if (not engine.check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
576
495
    {
577
 
      error= ER_EVENT_OBSERVER_PLUGIN;
 
496
      uint64_t counter; // @todo We need to refactor to check that.
 
497
 
 
498
      for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
 
499
               DropTable(session, identifier, counter));
578
500
    }
579
501
  }
580
502
 
581
 
  drizzled::message::Cache::singleton().erase(identifier);
582
 
 
583
 
  if (error)
584
 
  {
585
 
    return false;
586
 
  }
587
 
 
588
 
  return true;
 
503
  return error;
589
504
}
590
505
 
591
 
 
592
506
/**
593
507
  Initiates table-file and calls appropriate database-creator.
594
508
 
597
511
  @retval
598
512
   1  error
599
513
*/
600
 
bool StorageEngine::createTable(Session &session,
601
 
                                const identifier::Table &identifier,
602
 
                                message::Table& table_message)
 
514
int StorageEngine::createTable(Session &session,
 
515
                               TableIdentifier &identifier,
 
516
                               bool update_create_info,
 
517
                               message::Table& table_message)
603
518
{
604
 
  drizzled::error_t error= EE_OK;
605
 
 
606
 
  TableShare share(identifier);
607
 
  table::Shell table(share);
 
519
  int error= 1;
 
520
  Table table;
 
521
  TableShare share(identifier.getDBName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
608
522
  message::Table tmp_proto;
609
523
 
610
 
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
 
524
  if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
611
525
  { 
612
526
    // @note Error occured, we should probably do a little more here.
613
 
    // ER_CORRUPT_TABLE_DEFINITION,ER_CORRUPT_TABLE_DEFINITION_ENUM 
614
 
    
615
 
    my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
616
 
 
617
 
    return false;
618
527
  }
619
528
  else
620
529
  {
 
530
    if (update_create_info)
 
531
      table.updateCreateInfo(&table_message);
 
532
 
621
533
    /* Check for legal operations against the Engine using the proto (if used) */
622
534
    if (table_message.type() == message::Table::TEMPORARY &&
623
535
        share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
631
543
    }
632
544
    else
633
545
    {
634
 
      share.storage_engine->setTransactionReadWrite(session);
635
 
 
636
 
      error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
637
 
                                                                                table,
638
 
                                                                                identifier,
639
 
                                                                                table_message));
640
 
    }
641
 
 
642
 
    if (error == ER_TABLE_PERMISSION_DENIED)
643
 
    {
644
 
      my_error(ER_TABLE_PERMISSION_DENIED, identifier);
645
 
    }
646
 
    else if (error)
647
 
    {
648
 
      std::string path;
649
 
      identifier.getSQLPath(path);
650
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
651
 
    }
652
 
 
653
 
    table.delete_table();
 
546
      bool do_create= true;
 
547
      if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
 
548
      {
 
549
        int protoerr= StorageEngine::writeDefinitionFromPath(identifier, table_message);
 
550
 
 
551
        if (protoerr)
 
552
        {
 
553
          error= protoerr;
 
554
          do_create= false;
 
555
        }
 
556
      }
 
557
 
 
558
      if (do_create)
 
559
      {
 
560
        share.storage_engine->setTransactionReadWrite(session);
 
561
 
 
562
        error= share.storage_engine->doCreateTable(&session,
 
563
                                                   table,
 
564
                                                   identifier,
 
565
                                                   table_message);
 
566
      }
 
567
    }
 
568
 
 
569
    if (error)
 
570
    {
 
571
      if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
 
572
        plugin::StorageEngine::deleteDefinitionFromPath(identifier);
 
573
 
 
574
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
 
575
    }
 
576
 
 
577
    table.closefrm(false);
654
578
  }
655
579
 
656
 
  return(error == EE_OK);
657
 
}
658
 
 
659
 
Cursor *StorageEngine::getCursor(Table &arg)
660
 
{
661
 
  return create(arg);
662
 
}
663
 
 
664
 
class AddTableIdentifier : 
665
 
  public std::unary_function<StorageEngine *, void>
666
 
{
667
 
  CachedDirectory &directory;
668
 
  const identifier::Schema &identifier;
669
 
  identifier::Table::vector &set_of_identifiers;
 
580
  share.free_table_share();
 
581
  return(error != 0);
 
582
}
 
583
 
 
584
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
 
585
{
 
586
  return create(share, alloc);
 
587
}
 
588
 
 
589
/**
 
590
  TODO -> Remove this to force all engines to implement their own file. Solves the "we only looked at dfe" problem.
 
591
*/
 
592
void StorageEngine::doGetTableNames(CachedDirectory&, string&, set<string>&)
 
593
{ }
 
594
 
 
595
class AddTableName : 
 
596
  public unary_function<StorageEngine *, void>
 
597
{
 
598
  string db;
 
599
  CachedDirectory& directory;
 
600
  TableNameList &set_of_names;
670
601
 
671
602
public:
672
603
 
673
 
  AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
 
604
  AddTableName(CachedDirectory& directory_arg, const string& database_name, set<string>& of_names) :
674
605
    directory(directory_arg),
675
 
    identifier(identifier_arg),
676
 
    set_of_identifiers(of_names)
677
 
  {
678
 
  }
679
 
 
680
 
  result_type operator() (argument_type engine)
681
 
  {
682
 
    engine->doGetTableIdentifiers(directory, identifier, set_of_identifiers);
683
 
  }
684
 
};
685
 
 
686
 
 
687
 
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
688
 
{
689
 
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
690
 
 
691
 
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
 
606
    set_of_names(of_names)
 
607
  {
 
608
    db= database_name;
 
609
  }
 
610
 
 
611
  result_type operator() (argument_type engine)
 
612
  {
 
613
    engine->doGetTableNames(directory, db, set_of_names);
 
614
  }
 
615
};
 
616
 
 
617
class AddSchemaNames : 
 
618
  public unary_function<StorageEngine *, void>
 
619
{
 
620
  SchemaNameList &set_of_names;
 
621
 
 
622
public:
 
623
 
 
624
  AddSchemaNames(set<string>& of_names) :
 
625
    set_of_names(of_names)
 
626
  {
 
627
  }
 
628
 
 
629
  result_type operator() (argument_type engine)
 
630
  {
 
631
    engine->doGetSchemaNames(set_of_names);
 
632
  }
 
633
};
 
634
 
 
635
void StorageEngine::getSchemaNames(SchemaNameList &set_of_names)
 
636
{
 
637
  // Add hook here for engines to register schema.
 
638
  for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
 
639
           AddSchemaNames(set_of_names));
 
640
 
 
641
  plugin::Authorization::pruneSchemaNames(current_session->getSecurityContext(),
 
642
                                          set_of_names);
 
643
}
 
644
 
 
645
class StorageEngineGetSchemaDefinition: public unary_function<StorageEngine *, bool>
 
646
{
 
647
  std::string schema_name;
 
648
  message::Schema &schema_proto;
 
649
 
 
650
public:
 
651
  StorageEngineGetSchemaDefinition(const std::string schema_name_arg,
 
652
                                  message::Schema &schema_proto_arg) :
 
653
    schema_name(schema_name_arg),
 
654
    schema_proto(schema_proto_arg) 
 
655
  {
 
656
    transform(schema_name.begin(), schema_name.end(),
 
657
              schema_name.begin(), ::tolower);
 
658
  }
 
659
 
 
660
  result_type operator() (argument_type engine)
 
661
  {
 
662
    return engine->doGetSchemaDefinition(schema_name, schema_proto);
 
663
  }
 
664
};
 
665
 
 
666
/*
 
667
  Return value is "if parsed"
 
668
*/
 
669
bool StorageEngine::getSchemaDefinition(TableIdentifier &identifier, message::Schema &proto)
 
670
{
 
671
  return StorageEngine::getSchemaDefinition(identifier.getSchemaName(), proto);
 
672
}
 
673
 
 
674
bool StorageEngine::getSchemaDefinition(const std::string &schema_name, message::Schema &proto)
 
675
{
 
676
  proto.Clear();
 
677
 
 
678
  EngineVector::iterator iter=
 
679
    find_if(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
 
680
            StorageEngineGetSchemaDefinition(schema_name, proto));
 
681
 
 
682
  if (iter != vector_of_schema_engines.end())
 
683
  {
 
684
    return true;
 
685
  }
 
686
 
 
687
  return false;
 
688
}
 
689
 
 
690
bool StorageEngine::doesSchemaExist(const std::string &schema_name)
 
691
{
 
692
  message::Schema proto;
 
693
 
 
694
  return StorageEngine::getSchemaDefinition(schema_name, proto);
 
695
}
 
696
 
 
697
bool StorageEngine::doesSchemaExist(TableIdentifier &identifier)
 
698
{
 
699
  message::Schema proto;
 
700
 
 
701
  return StorageEngine::getSchemaDefinition(identifier.getSchemaName(), proto);
 
702
}
 
703
 
 
704
 
 
705
const CHARSET_INFO *StorageEngine::getSchemaCollation(const std::string &schema_name)
 
706
{
 
707
  message::Schema schmema_proto;
 
708
  bool found;
 
709
 
 
710
  found= StorageEngine::getSchemaDefinition(schema_name, schmema_proto);
 
711
 
 
712
  if (found && schmema_proto.has_collation())
 
713
  {
 
714
    const string buffer= schmema_proto.collation();
 
715
    const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
 
716
 
 
717
    if (not cs)
 
718
    {
 
719
      errmsg_printf(ERRMSG_LVL_ERROR,
 
720
                    _("Error while loading database options: '%s':"), schema_name.c_str());
 
721
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
 
722
 
 
723
      return default_charset_info;
 
724
    }
 
725
 
 
726
    return cs;
 
727
  }
 
728
 
 
729
  return default_charset_info;
 
730
}
 
731
 
 
732
class CreateSchema : 
 
733
  public unary_function<StorageEngine *, void>
 
734
{
 
735
  const drizzled::message::Schema &schema_message;
 
736
 
 
737
public:
 
738
 
 
739
  CreateSchema(const drizzled::message::Schema &arg) :
 
740
    schema_message(arg)
 
741
  {
 
742
  }
 
743
 
 
744
  result_type operator() (argument_type engine)
 
745
  {
 
746
    // @todo eomeday check that at least one engine said "true"
 
747
    (void)engine->doCreateSchema(schema_message);
 
748
  }
 
749
};
 
750
 
 
751
bool StorageEngine::createSchema(const drizzled::message::Schema &schema_message)
 
752
{
 
753
  // Add hook here for engines to register schema.
 
754
  for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
 
755
           CreateSchema(schema_message));
 
756
 
 
757
  return true;
 
758
}
 
759
 
 
760
class DropSchema : 
 
761
  public unary_function<StorageEngine *, void>
 
762
{
 
763
  uint64_t &success_count;
 
764
  const string &schema_name;
 
765
 
 
766
public:
 
767
 
 
768
  DropSchema(const string &arg, uint64_t &count_arg) :
 
769
    success_count(count_arg),
 
770
    schema_name(arg)
 
771
  {
 
772
  }
 
773
 
 
774
  result_type operator() (argument_type engine)
 
775
  {
 
776
    // @todo someday check that at least one engine said "true"
 
777
    bool success= engine->doDropSchema(schema_name);
 
778
 
 
779
    if (success)
 
780
      success_count++;
 
781
  }
 
782
};
 
783
 
 
784
bool StorageEngine::dropSchema(const string &schema_name)
 
785
{
 
786
  uint64_t counter= 0;
 
787
  // Add hook here for engines to register schema.
 
788
  for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
 
789
           DropSchema(schema_name, counter));
 
790
 
 
791
  return counter ? true : false;
 
792
}
 
793
 
 
794
class AlterSchema : 
 
795
  public unary_function<StorageEngine *, void>
 
796
{
 
797
  uint64_t &success_count;
 
798
  const drizzled::message::Schema &schema_message;
 
799
 
 
800
public:
 
801
 
 
802
  AlterSchema(const drizzled::message::Schema &arg, uint64_t &count_arg) :
 
803
    success_count(count_arg),
 
804
    schema_message(arg)
 
805
  {
 
806
  }
 
807
 
 
808
  result_type operator() (argument_type engine)
 
809
  {
 
810
    // @todo eomeday check that at least one engine said "true"
 
811
    bool success= engine->doAlterSchema(schema_message);
 
812
 
 
813
    if (success)
 
814
      success_count++;
 
815
  }
 
816
};
 
817
 
 
818
bool StorageEngine::alterSchema(const drizzled::message::Schema &schema_message)
 
819
{
 
820
  uint64_t success_count= 0;
 
821
 
 
822
  for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
 
823
           AlterSchema(schema_message, success_count));
 
824
 
 
825
  return success_count ? true : false;
 
826
}
 
827
 
 
828
 
 
829
void StorageEngine::getTableNames(const string &schema_name, TableNameList &set_of_names)
 
830
{
 
831
  string tmp_path;
 
832
 
 
833
  build_table_filename(tmp_path, schema_name.c_str(), "", false);
 
834
 
 
835
  CachedDirectory directory(tmp_path, set_of_table_definition_ext);
 
836
 
 
837
  if (not schema_name.compare("information_schema"))
692
838
  { }
693
 
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
 
839
  else if (not schema_name.compare("data_dictionary"))
694
840
  { }
695
841
  else
696
842
  {
698
844
    {
699
845
      errno= directory.getError();
700
846
      if (errno == ENOENT)
701
 
      {
702
 
        std::string path;
703
 
        schema_identifier.getSQLPath(path);
704
 
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
705
 
      }
 
847
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_name.c_str());
706
848
      else
707
 
      {
708
849
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
709
 
      }
710
 
 
711
850
      return;
712
851
    }
713
852
  }
714
853
 
715
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
716
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
717
 
 
718
 
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
 
854
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
855
           AddTableName(directory, schema_name, set_of_names));
 
856
 
 
857
  Session *session= current_session;
 
858
 
 
859
  session->doGetTableNames(directory, schema_name, set_of_names);
 
860
 
719
861
}
720
862
 
721
 
class DropTable: public std::unary_function<identifier::Table&, bool>
722
 
{
723
 
  Session &session;
724
 
  StorageEngine *engine;
725
 
 
726
 
public:
727
 
 
728
 
  DropTable(Session &session_arg, StorageEngine *engine_arg) :
729
 
    session(session_arg),
730
 
    engine(engine_arg)
731
 
  { }
732
 
 
733
 
  result_type operator() (argument_type identifier)
734
 
  {
735
 
    return engine->doDropTable(session, identifier) == 0;
736
 
  } 
737
 
};
738
 
 
739
 
/* This will later be converted to identifier::Tables */
740
 
class DropTables: public std::unary_function<StorageEngine *, void>
741
 
{
742
 
  Session &session;
743
 
  identifier::Table::vector &table_identifiers;
744
 
 
745
 
public:
746
 
 
747
 
  DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
 
863
/* This will later be converted to TableIdentifiers */
 
864
class DropTables: public unary_function<StorageEngine *, void>
 
865
{
 
866
  Session &session;
 
867
  TableIdentifierList &table_identifiers;
 
868
 
 
869
public:
 
870
 
 
871
  DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
748
872
    session(session_arg),
749
873
    table_identifiers(table_identifiers_arg)
750
874
  { }
751
875
 
752
876
  result_type operator() (argument_type engine)
753
877
  {
754
 
    // True returning from DropTable means the table has been successfully
755
 
    // deleted, so it should be removed from the list of tables to drop
756
 
    table_identifiers.erase(std::remove_if(table_identifiers.begin(),
757
 
                                           table_identifiers.end(),
758
 
                                           DropTable(session, engine)),
759
 
                            table_identifiers.end());
 
878
    for (TableIdentifierList::iterator iter= table_identifiers.begin();
 
879
         iter != table_identifiers.end();
 
880
         iter++)
 
881
    {
 
882
      int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
 
883
 
 
884
      // On a return of zero we know we found and deleted the table. So we
 
885
      // remove it from our search.
 
886
      if (not error)
 
887
        table_identifiers.erase(iter);
 
888
    }
760
889
  }
761
890
};
762
891
 
768
897
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
769
898
{
770
899
  CachedDirectory dir(directory, set_of_table_definition_ext);
771
 
  identifier::Table::vector table_identifiers;
 
900
  TableIdentifierList table_identifiers;
772
901
 
773
902
  if (dir.fail())
774
903
  {
784
913
       fileIter != files.end(); fileIter++)
785
914
  {
786
915
    size_t length;
787
 
    std::string path;
 
916
    string path;
788
917
    CachedDirectory::Entry *entry= *fileIter;
789
918
 
790
919
    /* We remove the file extension. */
797
926
    message::Table definition;
798
927
    if (StorageEngine::readTableFile(path, definition))
799
928
    {
800
 
      identifier::Table identifier(definition.schema(), definition.name(), path);
 
929
      TableIdentifier identifier(definition.schema(), definition.name(), path);
801
930
      table_identifiers.push_back(identifier);
802
931
    }
803
932
  }
804
933
 
805
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
806
 
                DropTables(session, table_identifiers));
807
 
 
 
934
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
935
           DropTables(session, table_identifiers));
 
936
  
808
937
  /*
809
938
    Now we just clean up anything that might left over.
810
939
 
811
940
    We rescan because some of what might have been there should
812
941
    now be all nice and cleaned up.
813
942
  */
814
 
  std::set<std::string> all_exts= set_of_table_definition_ext;
 
943
  set<string> all_exts= set_of_table_definition_ext;
815
944
 
816
945
  for (EngineVector::iterator iter= vector_of_engines.begin();
817
946
       iter != vector_of_engines.end() ; iter++)
826
955
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
827
956
       fileIter != files.end(); fileIter++)
828
957
  {
829
 
    std::string path;
 
958
    string path;
830
959
    CachedDirectory::Entry *entry= *fileIter;
831
960
 
832
961
    path+= directory;
844
973
  @note
845
974
    In case of delete table it's only safe to use the following parts of
846
975
    the 'table' structure:
847
 
    - table->getShare()->path
 
976
    - table->s->path
848
977
    - table->alias
849
978
*/
850
 
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
851
 
{
852
 
  drizzled::error_t textno= ER_GET_ERRNO;
 
979
void StorageEngine::print_error(int error, myf errflag, Table &table)
 
980
{
 
981
  print_error(error, errflag, &table);
 
982
}
 
983
 
 
984
void StorageEngine::print_error(int error, myf errflag, Table *table)
 
985
{
 
986
  int textno= ER_GET_ERRNO;
853
987
  switch (error) {
854
988
  case EACCES:
855
989
    textno=ER_OPEN_AS_READONLY;
870
1004
    break;
871
1005
  case HA_ERR_FOUND_DUPP_KEY:
872
1006
  {
873
 
    uint32_t key_nr= table.get_dup_key(error);
 
1007
    assert(table);
 
1008
    uint32_t key_nr= table->get_dup_key(error);
874
1009
    if ((int) key_nr >= 0)
875
1010
    {
876
1011
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
877
1012
 
878
 
      print_keydup_error(key_nr, err_msg, table);
 
1013
      if (key_nr == 0 &&
 
1014
          (table->key_info[0].key_part[0].field->flags &
 
1015
           AUTO_INCREMENT_FLAG)
 
1016
          && (current_session)->lex->sql_command == SQLCOM_ALTER_TABLE)
 
1017
      {
 
1018
        err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
 
1019
      }
879
1020
 
 
1021
      print_keydup_error(key_nr, err_msg, *table);
880
1022
      return;
881
1023
    }
882
1024
    textno=ER_DUP_KEY;
884
1026
  }
885
1027
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
886
1028
  {
887
 
    uint32_t key_nr= table.get_dup_key(error);
 
1029
    assert(table);
 
1030
    uint32_t key_nr= table->get_dup_key(error);
888
1031
    if ((int) key_nr >= 0)
889
1032
    {
890
1033
      uint32_t max_length;
894
1037
      String str(key,sizeof(key),system_charset_info);
895
1038
 
896
1039
      /* Table is opened and defined at this point */
897
 
      key_unpack(&str, &table,(uint32_t) key_nr);
 
1040
      key_unpack(&str,table,(uint32_t) key_nr);
898
1041
      max_length= (DRIZZLE_ERRMSG_SIZE-
899
1042
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
900
1043
      if (str.length() >= max_length)
902
1045
        str.length(max_length-4);
903
1046
        str.append(STRING_WITH_LEN("..."));
904
1047
      }
905
 
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table.getShare()->getTableName(),
 
1048
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->s->table_name.str,
906
1049
        str.c_ptr(), key_nr+1);
907
1050
      return;
908
1051
    }
925
1068
    textno=ER_CRASHED_ON_USAGE;
926
1069
    break;
927
1070
  case HA_ERR_NOT_A_TABLE:
928
 
    textno= static_cast<drizzled::error_t>(error);
 
1071
    textno= error;
929
1072
    break;
930
1073
  case HA_ERR_CRASHED_ON_REPAIR:
931
1074
    textno=ER_CRASHED_ON_REPAIR;
979
1122
    textno=ER_TABLE_DEF_CHANGED;
980
1123
    break;
981
1124
  case HA_ERR_NO_SUCH_TABLE:
982
 
    {
983
 
      identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
984
 
      my_error(ER_TABLE_UNKNOWN, identifier);
985
 
      return;
986
 
    }
 
1125
    assert(table);
 
1126
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->s->getSchemaName(),
 
1127
             table->s->table_name.str);
 
1128
    return;
987
1129
  case HA_ERR_RBR_LOGGING_FAILED:
988
1130
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
989
1131
    break;
990
1132
  case HA_ERR_DROP_INDEX_FK:
991
1133
  {
 
1134
    assert(table);
992
1135
    const char *ptr= "???";
993
 
    uint32_t key_nr= table.get_dup_key(error);
 
1136
    uint32_t key_nr= table->get_dup_key(error);
994
1137
    if ((int) key_nr >= 0)
995
 
      ptr= table.key_info[key_nr].name;
 
1138
      ptr= table->key_info[key_nr].name;
996
1139
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
997
1140
    return;
998
1141
  }
1037
1180
      return;
1038
1181
    }
1039
1182
  }
1040
 
 
1041
 
  my_error(textno, errflag, table.getShare()->getTableName(), error);
 
1183
  my_error(textno, errflag, table->s->table_name.str, error);
1042
1184
}
1043
1185
 
1044
1186
 
1051
1193
  @return
1052
1194
    Returns true if this is a temporary error
1053
1195
*/
1054
 
bool StorageEngine::get_error_message(int , String* ) const
 
1196
bool StorageEngine::get_error_message(int , String* )
1055
1197
{
1056
1198
  return false;
1057
1199
}
1058
1200
 
1059
1201
 
1060
 
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
 
1202
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1061
1203
{
1062
1204
  /* Write the duplicated key in the error message */
1063
1205
  char key[MAX_KEY_LENGTH];
1085
1227
}
1086
1228
 
1087
1229
 
1088
 
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
 
1230
int StorageEngine::deleteDefinitionFromPath(TableIdentifier &identifier)
1089
1231
{
1090
 
  std::string path(identifier.getPath());
 
1232
  string path(identifier.getPath());
1091
1233
 
1092
1234
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1093
1235
 
1094
1236
  return internal::my_delete(path.c_str(), MYF(0));
1095
1237
}
1096
1238
 
1097
 
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
 
1239
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
1098
1240
{
1099
1241
  message::Table table_message;
1100
 
  std::string src_path(src.getPath());
1101
 
  std::string dest_path(dest.getPath());
 
1242
  string src_path(src.getPath());
 
1243
  string dest_path(dest.getPath());
1102
1244
 
1103
1245
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1104
1246
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1123
1265
  return error;
1124
1266
}
1125
1267
 
1126
 
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, message::Table &table_message)
 
1268
int StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_message)
1127
1269
{
1128
1270
  char definition_file_tmp[FN_REFLEN];
1129
 
  std::string file_name(identifier.getPath());
 
1271
  string file_name(identifier.getPath());
1130
1272
 
1131
1273
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1132
1274
 
1133
 
  snprintf(definition_file_tmp, sizeof(definition_file_tmp), "%sXXXXXX", file_name.c_str());
 
1275
  snprintf(definition_file_tmp, sizeof(definition_file_tmp), "%s.%sXXXXXX", file_name.c_str(), DEFAULT_DEFINITION_FILE_EXT.c_str());
1134
1276
 
1135
1277
  int fd= mkstemp(definition_file_tmp);
1136
1278
 
1143
1285
  google::protobuf::io::ZeroCopyOutputStream* output=
1144
1286
    new google::protobuf::io::FileOutputStream(fd);
1145
1287
 
1146
 
  bool success;
1147
 
 
1148
 
  try
1149
 
  {
1150
 
    success= table_message.SerializeToZeroCopyStream(output);
1151
 
  }
1152
 
  catch (...)
1153
 
  {
1154
 
    success= false;
1155
 
  }
1156
 
 
1157
 
  if (not success)
1158
 
  {
1159
 
    std::string error_message;
1160
 
    identifier.getSQLPath(error_message);
1161
 
 
 
1288
  if (not table_message.SerializeToZeroCopyStream(output))
 
1289
  {
1162
1290
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1163
 
             error_message.c_str(),
1164
1291
             table_message.InitializationErrorString().c_str());
1165
1292
    delete output;
1166
1293
 
1200
1327
  return 0;
1201
1328
}
1202
1329
 
1203
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
 
1330
class CanCreateTable: public unary_function<StorageEngine *, bool>
1204
1331
{
1205
 
  const identifier::Table &identifier;
 
1332
  const TableIdentifier &identifier;
1206
1333
 
1207
1334
public:
1208
 
  CanCreateTable(const identifier::Table &identifier_arg) :
 
1335
  CanCreateTable(const TableIdentifier &identifier_arg) :
1209
1336
    identifier(identifier_arg)
1210
1337
  { }
1211
1338
 
1219
1346
/**
1220
1347
  @note on success table can be created.
1221
1348
*/
1222
 
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
 
1349
bool StorageEngine::canCreateTable(drizzled::TableIdentifier &identifier)
1223
1350
{
1224
1351
  EngineVector::iterator iter=
1225
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1226
 
                 CanCreateTable(identifier));
 
1352
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
1353
            CanCreateTable(identifier));
1227
1354
 
1228
1355
  if (iter == vector_of_engines.end())
1229
1356
  {
1235
1362
 
1236
1363
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1237
1364
{
1238
 
  std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
 
1365
  fstream input(path.c_str(), ios::in | ios::binary);
1239
1366
 
1240
1367
  if (input.good())
1241
1368
  {
1242
 
    try {
1243
 
      if (table_message.ParseFromIstream(&input))
1244
 
      {
1245
 
        return true;
1246
 
      }
1247
 
    }
1248
 
    catch (...)
 
1369
    if (table_message.ParseFromIstream(&input))
1249
1370
    {
1250
 
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1251
 
               table_message.name().empty() ? path.c_str() : table_message.name().c_str(),
1252
 
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
 
1371
      return true;
1253
1372
    }
 
1373
 
 
1374
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
 
1375
             table_message.InitializationErrorString().c_str());
1254
1376
  }
1255
1377
  else
1256
1378
  {
1260
1382
  return false;
1261
1383
}
1262
1384
 
1263
 
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine)
1264
 
{
1265
 
  output << "StorageEngine:(";
1266
 
  output <<  engine.getName();
1267
 
  output << ")";
1268
1385
 
1269
 
  return output;
1270
 
}
1271
1386
 
1272
1387
} /* namespace plugin */
1273
1388
} /* namespace drizzled */