~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/schema_engine/schema.cc

  • Committer: Monty Taylor
  • Date: 2010-06-02 22:35:45 UTC
  • mto: This revision was merged to the branch mainline in revision 1586.
  • Revision ID: mordred@inaugust.com-20100602223545-q8ekf9b40a85nwuf
Rearragned unittests into a single exe because of how we need to link it
(thanks lifeless)
Link with server symbols without needing to build a library.
Added an additional atomics test which tests whatever version of the atomics
lib the running platform would actually use.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include "drizzled/charset.h"
28
28
#include "drizzled/charset_info.h"
29
29
#include "drizzled/cursor.h"
30
 
#include "drizzled/data_home.h"
31
30
 
32
31
#include "drizzled/internal/my_sys.h"
33
32
 
45
44
using namespace std;
46
45
using namespace drizzled;
47
46
 
 
47
// This should always be the same value as GLOBAL_TEMPORARY_EXT but be
 
48
// CASE_UP. --Brian
 
49
static SchemaIdentifier TEMPORARY_IDENTIFIER(".TEMPORARY");
48
50
 
49
51
#define MY_DB_OPT_FILE "db.opt"
50
52
#define DEFAULT_FILE_EXTENSION ".dfe" // Deep Fried Elephant
58
60
  schema_cache_filled(false)
59
61
{
60
62
  table_definition_ext= DEFAULT_FILE_EXTENSION;
 
63
  pthread_rwlock_init(&schema_lock, NULL);
 
64
  prime();
61
65
}
62
66
 
63
67
Schema::~Schema()
64
68
{
 
69
  pthread_rwlock_destroy(&schema_lock);
65
70
}
66
71
 
67
72
void Schema::prime()
68
73
{
69
 
  CachedDirectory directory(getDataHomeCatalog().file_string(), CachedDirectory::DIRECTORY);
 
74
  CachedDirectory directory(data_home, CachedDirectory::DIRECTORY);
70
75
  CachedDirectory::Entries files= directory.getEntries();
71
76
 
72
 
  mutex.lock();
 
77
  pthread_rwlock_wrlock(&schema_lock);
73
78
 
74
79
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
75
80
       fileIter != files.end(); fileIter++)
80
85
    if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
81
86
      continue;
82
87
 
83
 
    SchemaIdentifier filename(entry->filename);
84
 
    if (readSchemaFile(filename, schema_message))
 
88
    if (readSchemaFile(entry->filename, schema_message))
85
89
    {
86
90
      SchemaIdentifier schema_identifier(schema_message.name());
87
91
 
88
92
      pair<SchemaCache::iterator, bool> ret=
89
 
        schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
 
93
        schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
90
94
 
91
95
      if (ret.second == false)
92
96
     {
94
98
      }
95
99
    }
96
100
  }
97
 
  mutex.unlock();
 
101
  pthread_rwlock_unlock(&schema_lock);
98
102
}
99
103
 
100
 
void Schema::doGetSchemaIdentifiers(SchemaIdentifier::vector &set_of_names)
 
104
void Schema::doGetSchemaIdentifiers(SchemaIdentifierList &set_of_names)
101
105
{
102
 
  mutex.lock_shared();
 
106
  if (not pthread_rwlock_rdlock(&schema_lock))
103
107
  {
104
108
    for (SchemaCache::iterator iter= schema_cache.begin();
105
109
         iter != schema_cache.end();
106
110
         iter++)
107
111
    {
108
 
      set_of_names.push_back(SchemaIdentifier((*iter).second->name()));
 
112
      set_of_names.push_back(SchemaIdentifier((*iter).second.name()));
109
113
    }
110
 
  }
111
 
  mutex.unlock_shared();
 
114
    pthread_rwlock_unlock(&schema_lock);
 
115
 
 
116
    return;
 
117
  }
 
118
 
 
119
  // If for some reason getting a lock should fail, we resort to disk
 
120
 
 
121
  CachedDirectory directory(data_home, CachedDirectory::DIRECTORY);
 
122
 
 
123
  CachedDirectory::Entries files= directory.getEntries();
 
124
 
 
125
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
 
126
       fileIter != files.end(); fileIter++)
 
127
  {
 
128
    CachedDirectory::Entry *entry= *fileIter;
 
129
    set_of_names.push_back(entry->filename);
 
130
  }
112
131
}
113
132
 
114
 
bool Schema::doGetSchemaDefinition(const SchemaIdentifier &schema_identifier, message::schema::shared_ptr &schema_message)
 
133
bool Schema::doGetSchemaDefinition(SchemaIdentifier &schema_identifier, message::Schema &schema_message)
115
134
{
116
 
  mutex.lock_shared();
117
 
  SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
118
 
 
119
 
  if (iter != schema_cache.end())
 
135
  if (not pthread_rwlock_rdlock(&schema_lock))
120
136
  {
121
 
    schema_message= (*iter).second;
122
 
    mutex.unlock_shared();
123
 
    return true;
 
137
    SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
 
138
 
 
139
    if (iter != schema_cache.end())
 
140
    {
 
141
      schema_message.CopyFrom(((*iter).second));
 
142
      pthread_rwlock_unlock(&schema_lock);
 
143
      return true;
 
144
    }
 
145
    pthread_rwlock_unlock(&schema_lock);
 
146
 
 
147
    return false;
124
148
  }
125
 
  mutex.unlock_shared();
126
149
 
127
 
  return false;
 
150
  // Fail to disk based means
 
151
  return readSchemaFile(schema_identifier.getPath(), schema_message);
128
152
}
129
153
 
130
 
 
131
154
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
132
155
{
133
156
  SchemaIdentifier schema_identifier(schema_message.name());
142
165
    return false;
143
166
  }
144
167
 
145
 
  mutex.lock();
 
168
  if (not pthread_rwlock_wrlock(&schema_lock))
146
169
  {
147
 
    pair<SchemaCache::iterator, bool> ret=
148
 
      schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
149
 
 
150
 
 
151
 
    if (ret.second == false)
152
 
    {
153
 
      abort(); // If this has happened, something really bad is going down.
154
 
    }
 
170
      pair<SchemaCache::iterator, bool> ret=
 
171
        schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
 
172
 
 
173
 
 
174
      if (ret.second == false)
 
175
      {
 
176
        abort(); // If this has happened, something really bad is going down.
 
177
      }
 
178
    pthread_rwlock_unlock(&schema_lock);
155
179
  }
156
 
  mutex.unlock();
157
180
 
158
181
  return true;
159
182
}
160
183
 
161
 
bool Schema::doDropSchema(const SchemaIdentifier &schema_identifier)
 
184
bool Schema::doDropSchema(SchemaIdentifier &schema_identifier)
162
185
{
163
 
  message::schema::shared_ptr schema_message;
 
186
  message::Schema schema_message;
164
187
 
165
188
  string schema_file(schema_identifier.getPath());
166
189
  schema_file.append(1, FN_LIBCHAR);
191
214
    cerr << dir;
192
215
  }
193
216
 
194
 
  mutex.lock();
195
 
  schema_cache.erase(schema_identifier.getPath());
196
 
  mutex.unlock();
 
217
  if (not pthread_rwlock_wrlock(&schema_lock))
 
218
  {
 
219
    schema_cache.erase(schema_identifier.getPath());
 
220
    pthread_rwlock_unlock(&schema_lock);
 
221
  }
197
222
 
198
223
  return true;
199
224
}
207
232
 
208
233
  if (writeSchemaFile(schema_identifier, schema_message))
209
234
  {
210
 
    mutex.lock();
 
235
    if (not pthread_rwlock_wrlock(&schema_lock))
211
236
    {
212
237
      schema_cache.erase(schema_identifier.getPath());
213
238
 
214
239
      pair<SchemaCache::iterator, bool> ret=
215
 
        schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
 
240
        schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
216
241
 
217
242
      if (ret.second == false)
218
243
      {
219
244
        abort(); // If this has happened, something really bad is going down.
220
245
      }
221
 
    }
222
 
    mutex.unlock();
 
246
 
 
247
      pthread_rwlock_unlock(&schema_lock);
 
248
    }
 
249
    else
 
250
    {
 
251
      abort(); // This would leave us out of sync, suck.
 
252
    }
223
253
  }
224
254
 
225
255
  return true;
230
260
 
231
261
  @note we do the rename to make it crash safe.
232
262
*/
233
 
bool Schema::writeSchemaFile(const SchemaIdentifier &schema_identifier, const message::Schema &db)
 
263
bool Schema::writeSchemaFile(SchemaIdentifier &schema_identifier, const message::Schema &db)
234
264
{
235
265
  char schema_file_tmp[FN_REFLEN];
236
266
  string schema_file(schema_identifier.getPath());
250
280
    return false;
251
281
  }
252
282
 
253
 
  bool success;
254
 
 
255
 
  try {
256
 
    success= db.SerializeToFileDescriptor(fd);
257
 
  }
258
 
  catch (...)
259
 
  {
260
 
    success= false;
261
 
  }
262
 
 
263
 
  if (not success)
 
283
  if (not db.SerializeToFileDescriptor(fd))
264
284
  {
265
285
    my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
266
286
             db.InitializationErrorString().empty() ? "unknown" :  db.InitializationErrorString().c_str());
296
316
}
297
317
 
298
318
 
299
 
bool Schema::readSchemaFile(const drizzled::SchemaIdentifier &schema_identifier, drizzled::message::Schema &schema)
 
319
bool Schema::readSchemaFile(const std::string &schema_file_name, drizzled::message::Schema &schema_message)
300
320
{
301
 
  string db_opt_path(schema_identifier.getPath());
 
321
  string db_opt_path(schema_file_name);
302
322
 
303
323
  /*
304
324
    Pass an empty file name, and the database options file name as extension
316
336
  */
317
337
  if (input.good())
318
338
  {
319
 
    if (schema.ParseFromIstream(&input))
 
339
    if (schema_message.ParseFromIstream(&input))
320
340
    {
321
341
      return true;
322
342
    }
323
343
 
324
344
    my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
325
 
             schema.InitializationErrorString().empty() ? "unknown" :  schema.InitializationErrorString().c_str());
 
345
             schema_message.InitializationErrorString().empty() ? "unknown" :  schema_message.InitializationErrorString().c_str());
326
346
  }
327
347
  else
328
348
  {
332
352
  return false;
333
353
}
334
354
 
 
355
bool Schema::doCanCreateTable(drizzled::TableIdentifier &identifier)
 
356
{
 
357
  if (static_cast<SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
 
358
  {
 
359
    return false;
 
360
  }
 
361
 
 
362
  return true;
 
363
}
 
364
 
335
365
void Schema::doGetTableIdentifiers(drizzled::CachedDirectory&,
336
 
                                   const drizzled::SchemaIdentifier&,
337
 
                                   drizzled::TableIdentifier::vector&)
 
366
                                   drizzled::SchemaIdentifier&,
 
367
                                   drizzled::TableIdentifiers&)
338
368
{
339
369
}