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"
32
31
#include "drizzled/internal/my_sys.h"
45
44
using namespace std;
46
45
using namespace drizzled;
47
// This should always be the same value as GLOBAL_TEMPORARY_EXT but be
49
static SchemaIdentifier TEMPORARY_IDENTIFIER(".TEMPORARY");
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)
60
62
table_definition_ext= DEFAULT_FILE_EXTENSION;
63
pthread_rwlock_init(&schema_lock, NULL);
69
pthread_rwlock_destroy(&schema_lock);
67
72
void Schema::prime()
69
CachedDirectory directory(getDataHomeCatalog().file_string(), CachedDirectory::DIRECTORY);
74
CachedDirectory directory(data_home, CachedDirectory::DIRECTORY);
70
75
CachedDirectory::Entries files= directory.getEntries();
77
pthread_rwlock_wrlock(&schema_lock);
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))
83
SchemaIdentifier filename(entry->filename);
84
if (readSchemaFile(filename, schema_message))
88
if (readSchemaFile(entry->filename, schema_message))
86
90
SchemaIdentifier schema_identifier(schema_message.name());
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));
91
95
if (ret.second == false)
101
pthread_rwlock_unlock(&schema_lock);
100
void Schema::doGetSchemaIdentifiers(SchemaIdentifier::vector &set_of_names)
104
void Schema::doGetSchemaIdentifiers(SchemaIdentifierList &set_of_names)
106
if (not pthread_rwlock_rdlock(&schema_lock))
104
108
for (SchemaCache::iterator iter= schema_cache.begin();
105
109
iter != schema_cache.end();
108
set_of_names.push_back(SchemaIdentifier((*iter).second->name()));
112
set_of_names.push_back(SchemaIdentifier((*iter).second.name()));
111
mutex.unlock_shared();
114
pthread_rwlock_unlock(&schema_lock);
119
// If for some reason getting a lock should fail, we resort to disk
121
CachedDirectory directory(data_home, CachedDirectory::DIRECTORY);
123
CachedDirectory::Entries files= directory.getEntries();
125
for (CachedDirectory::Entries::iterator fileIter= files.begin();
126
fileIter != files.end(); fileIter++)
128
CachedDirectory::Entry *entry= *fileIter;
129
set_of_names.push_back(entry->filename);
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)
117
SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
119
if (iter != schema_cache.end())
135
if (not pthread_rwlock_rdlock(&schema_lock))
121
schema_message= (*iter).second;
122
mutex.unlock_shared();
137
SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
139
if (iter != schema_cache.end())
141
schema_message.CopyFrom(((*iter).second));
142
pthread_rwlock_unlock(&schema_lock);
145
pthread_rwlock_unlock(&schema_lock);
125
mutex.unlock_shared();
150
// Fail to disk based means
151
return readSchemaFile(schema_identifier.getPath(), schema_message);
131
154
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
133
156
SchemaIdentifier schema_identifier(schema_message.name());
168
if (not pthread_rwlock_wrlock(&schema_lock))
147
pair<SchemaCache::iterator, bool> ret=
148
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
151
if (ret.second == false)
153
abort(); // If this has happened, something really bad is going down.
170
pair<SchemaCache::iterator, bool> ret=
171
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
174
if (ret.second == false)
176
abort(); // If this has happened, something really bad is going down.
178
pthread_rwlock_unlock(&schema_lock);
161
bool Schema::doDropSchema(const SchemaIdentifier &schema_identifier)
184
bool Schema::doDropSchema(SchemaIdentifier &schema_identifier)
163
message::schema::shared_ptr schema_message;
186
message::Schema schema_message;
165
188
string schema_file(schema_identifier.getPath());
166
189
schema_file.append(1, FN_LIBCHAR);
208
233
if (writeSchemaFile(schema_identifier, schema_message))
235
if (not pthread_rwlock_wrlock(&schema_lock))
212
237
schema_cache.erase(schema_identifier.getPath());
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));
217
242
if (ret.second == false)
219
244
abort(); // If this has happened, something really bad is going down.
247
pthread_rwlock_unlock(&schema_lock);
251
abort(); // This would leave us out of sync, suck.
231
261
@note we do the rename to make it crash safe.
233
bool Schema::writeSchemaFile(const SchemaIdentifier &schema_identifier, const message::Schema &db)
263
bool Schema::writeSchemaFile(SchemaIdentifier &schema_identifier, const message::Schema &db)
235
265
char schema_file_tmp[FN_REFLEN];
236
266
string schema_file(schema_identifier.getPath());
256
success= db.SerializeToFileDescriptor(fd);
283
if (not db.SerializeToFileDescriptor(fd))
265
285
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
266
286
db.InitializationErrorString().empty() ? "unknown" : db.InitializationErrorString().c_str());
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)
301
string db_opt_path(schema_identifier.getPath());
321
string db_opt_path(schema_file_name);
304
324
Pass an empty file name, and the database options file name as extension
317
337
if (input.good())
319
if (schema.ParseFromIstream(&input))
339
if (schema_message.ParseFromIstream(&input))
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());
355
bool Schema::doCanCreateTable(drizzled::TableIdentifier &identifier)
357
if (static_cast<SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
335
365
void Schema::doGetTableIdentifiers(drizzled::CachedDirectory&,
336
const drizzled::SchemaIdentifier&,
337
drizzled::TableIdentifier::vector&)
366
drizzled::SchemaIdentifier&,
367
drizzled::TableIdentifiers&)