~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/schema_engine/schema.cc

  • Committer: Brian Aker
  • Date: 2010-03-31 05:53:34 UTC
  • Revision ID: brian@gaz-20100331055334-yqqmzlgqb2xq1p5b
Mass overhaul to use schema_identifier.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
using namespace std;
45
45
using namespace drizzled;
46
46
 
 
47
static SchemaIdentifier TEMPORARY_IDENTIFIER("TEMPORARY");
 
48
 
47
49
#define MY_DB_OPT_FILE "db.opt"
48
50
#define DEFAULT_FILE_EXTENSION ".dfe" // Deep Fried Elephant
49
51
 
80
82
 
81
83
    if (readSchemaFile(entry->filename, schema_message))
82
84
    {
 
85
      SchemaIdentifier schema_identifier(schema_message.name());
 
86
 
83
87
      pair<SchemaCache::iterator, bool> ret=
84
 
        schema_cache.insert(make_pair(schema_message.name(), schema_message));
 
88
        schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
85
89
 
86
90
      if (ret.second == false)
87
 
      {
 
91
     {
88
92
        abort(); // If this has happened, something really bad is going down.
89
93
      }
90
94
    }
92
96
  pthread_rwlock_unlock(&schema_lock);
93
97
}
94
98
 
95
 
void Schema::doGetSchemaNames(std::set<std::string>& set_of_names)
 
99
void Schema::doGetSchemaIdentifiers(SchemaIdentifierList &set_of_names)
96
100
{
97
101
  if (not pthread_rwlock_rdlock(&schema_lock))
98
102
  {
100
104
         iter != schema_cache.end();
101
105
         iter++)
102
106
    {
103
 
      set_of_names.insert((*iter).first);
 
107
      set_of_names.push_back(SchemaIdentifier((*iter).second.name()));
104
108
    }
105
109
    pthread_rwlock_unlock(&schema_lock);
106
110
 
117
121
       fileIter != files.end(); fileIter++)
118
122
  {
119
123
    CachedDirectory::Entry *entry= *fileIter;
120
 
    set_of_names.insert(entry->filename);
 
124
    set_of_names.push_back(entry->filename);
121
125
  }
122
126
}
123
127
 
124
 
bool Schema::doGetSchemaDefinition(const std::string &schema_name, message::Schema &schema_message)
 
128
bool Schema::doGetSchemaDefinition(SchemaIdentifier &schema_identifier, message::Schema &schema_message)
125
129
{
126
130
  if (not pthread_rwlock_rdlock(&schema_lock))
127
131
  {
128
 
    SchemaCache::iterator iter= schema_cache.find(schema_name);
 
132
    SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
 
133
 
129
134
    if (iter != schema_cache.end())
130
135
    {
131
136
      schema_message.CopyFrom(((*iter).second));
138
143
  }
139
144
 
140
145
  // Fail to disk based means
141
 
  return readSchemaFile(schema_name, schema_message);
 
146
  return readSchemaFile(schema_identifier.getPath(), schema_message);
142
147
}
143
148
 
144
149
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
145
150
{
146
 
  std::string path;
147
 
  drizzled::build_table_filename(path, schema_message.name().c_str(), "", false);
148
 
 
149
 
  path.erase(path.length()-1);
150
 
 
151
 
  if (mkdir(path.c_str(), 0777) == -1)
 
151
  SchemaIdentifier schema_identifier(schema_message.name());
 
152
 
 
153
  if (mkdir(schema_identifier.getPath().c_str(), 0777) == -1)
152
154
    return false;
153
155
 
154
 
  if (not writeSchemaFile(path.c_str(), schema_message))
 
156
  if (not writeSchemaFile(schema_identifier, schema_message))
155
157
  {
156
 
    rmdir(path.c_str());
 
158
    rmdir(schema_identifier.getPath().c_str());
157
159
 
158
160
    return false;
159
161
  }
161
163
  if (not pthread_rwlock_wrlock(&schema_lock))
162
164
  {
163
165
      pair<SchemaCache::iterator, bool> ret=
164
 
        schema_cache.insert(make_pair(schema_message.name(), schema_message));
 
166
        schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
165
167
 
166
168
 
167
169
      if (ret.second == false)
174
176
  return true;
175
177
}
176
178
 
177
 
bool Schema::doDropSchema(const std::string &schema_name)
 
179
bool Schema::doDropSchema(SchemaIdentifier &schema_identifier)
178
180
{
179
 
  string path;
180
181
  message::Schema schema_message;
181
182
 
182
 
  drizzled::build_table_filename(path, schema_name.c_str(), "", false);
183
 
  path.erase(path.length()-1);
184
 
 
185
 
  string schema_file(path);
 
183
  string schema_file(schema_identifier.getPath());
186
184
  schema_file.append(1, FN_LIBCHAR);
187
185
  schema_file.append(MY_DB_OPT_FILE);
188
186
 
189
 
  if (not doGetSchemaDefinition(schema_name, schema_message))
 
187
  if (not doGetSchemaDefinition(schema_identifier, schema_message))
190
188
    return false;
191
189
 
192
190
  // No db.opt file, no love from us.
202
200
    return false;
203
201
  }
204
202
 
205
 
  if (rmdir(path.c_str()))
 
203
  if (rmdir(schema_identifier.getPath().c_str()))
206
204
  {
207
 
    perror(path.c_str());
208
 
    CachedDirectory dir(path);
 
205
    perror(schema_identifier.getPath().c_str());
 
206
    //@todo If this happens, we want a report of it. For the moment I dump
 
207
    //to stderr so I can catch it in Hudson.
 
208
    CachedDirectory dir(schema_identifier.getPath());
209
209
    cerr << dir;
210
210
  }
211
211
 
212
212
  if (not pthread_rwlock_wrlock(&schema_lock))
213
213
  {
214
 
    schema_cache.erase(schema_message.name());
 
214
    schema_cache.erase(schema_identifier.getPath());
215
215
    pthread_rwlock_unlock(&schema_lock);
216
216
  }
217
217
 
220
220
 
221
221
bool Schema::doAlterSchema(const drizzled::message::Schema &schema_message)
222
222
{
223
 
  string path;
224
 
  drizzled::build_table_filename(path, schema_message.name().c_str(), "", false);
225
 
  path.erase(path.length()-1);
 
223
  SchemaIdentifier schema_identifier(schema_message.name());
226
224
 
227
 
  if (access(path.c_str(), F_OK))
 
225
  if (access(schema_identifier.getPath().c_str(), F_OK))
228
226
    return false;
229
227
 
230
 
  if (writeSchemaFile(path.c_str(), schema_message))
 
228
  if (writeSchemaFile(schema_identifier, schema_message))
231
229
  {
232
230
    if (not pthread_rwlock_wrlock(&schema_lock))
233
231
    {
234
 
      schema_cache.erase(schema_message.name());
 
232
      schema_cache.erase(schema_identifier.getPath());
235
233
 
236
234
      pair<SchemaCache::iterator, bool> ret=
237
 
        schema_cache.insert(make_pair(schema_message.name(), schema_message));
 
235
        schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
238
236
 
239
237
      if (ret.second == false)
240
238
      {
257
255
 
258
256
  @note we do the rename to make it crash safe.
259
257
*/
260
 
bool Schema::writeSchemaFile(const char *path, const message::Schema &db)
 
258
bool Schema::writeSchemaFile(SchemaIdentifier &schema_identifier, const message::Schema &db)
261
259
{
262
260
  char schema_file_tmp[FN_REFLEN];
263
 
  string schema_file(path);
 
261
  string schema_file(schema_identifier.getPath());
264
262
 
265
263
 
266
264
  schema_file.append(1, FN_LIBCHAR);
279
277
 
280
278
  if (not db.SerializeToFileDescriptor(fd))
281
279
  {
282
 
    cerr << "Couldn't write " << path << "\n";
 
280
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
 
281
             db.InitializationErrorString().c_str());
283
282
 
284
283
    if (close(fd) == -1)
285
284
      perror(schema_file_tmp);
312
311
}
313
312
 
314
313
 
315
 
bool Schema::readSchemaFile(const std::string &schema_name, drizzled::message::Schema &schema_message)
 
314
bool Schema::readSchemaFile(const std::string &schema_file_name, drizzled::message::Schema &schema_message)
316
315
{
317
 
  string db_opt_path;
 
316
  string db_opt_path(schema_file_name);
318
317
 
319
318
  /*
320
319
    Pass an empty file name, and the database options file name as extension
321
320
    to avoid table name to file name encoding.
322
321
  */
323
 
  build_table_filename(db_opt_path, schema_name.c_str(), "", false);
 
322
  db_opt_path.append(1, FN_LIBCHAR);
324
323
  db_opt_path.append(MY_DB_OPT_FILE);
325
324
 
326
325
  fstream input(db_opt_path.c_str(), ios::in | ios::binary);
336
335
    {
337
336
      return true;
338
337
    }
 
338
 
 
339
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
 
340
             schema_message.InitializationErrorString().c_str());
339
341
  }
340
342
  else
341
343
  {
345
347
  return false;
346
348
}
347
349
 
348
 
bool Schema::doCanCreateTable(const drizzled::TableIdentifier &identifier)
 
350
bool Schema::doCanCreateTable(drizzled::TableIdentifier &identifier)
349
351
{
350
 
  if (not strcasecmp(identifier.getSchemaName().c_str(), "temporary"))
 
352
  if (static_cast<SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
351
353
  {
352
354
    return false;
353
355
  }