18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
#include <plugin/schema_engine/schema.h>
24
#include <drizzled/schema.h>
25
#include <drizzled/sql_table.h>
26
#include <drizzled/global_charset_info.h>
27
#include <drizzled/charset.h>
28
#include <drizzled/charset_info.h>
29
#include <drizzled/cursor.h>
30
#include <drizzled/data_home.h>
32
#include <drizzled/pthread_globals.h>
34
#include <drizzled/execute.h>
36
#include <drizzled/internal/my_sys.h>
23
#include "plugin/schema_engine/schema.h"
24
#include "drizzled/db.h"
25
#include "drizzled/sql_table.h"
26
#include "drizzled/global_charset_info.h"
27
#include "drizzled/charset.h"
28
#include "drizzled/charset_info.h"
29
#include "drizzled/cursor.h"
31
#include "drizzled/internal/my_sys.h"
39
34
#include <sys/stat.h>
62
60
schema_cache_filled(false)
64
62
table_definition_ext= DEFAULT_FILE_EXTENSION;
63
pthread_rwlock_init(&schema_lock, NULL);
69
pthread_rwlock_destroy(&schema_lock);
71
72
void Schema::prime()
73
CachedDirectory directory(getDataHomeCatalog().file_string(), CachedDirectory::DIRECTORY);
74
CachedDirectory directory(data_home, CachedDirectory::DIRECTORY);
74
75
CachedDirectory::Entries files= directory.getEntries();
75
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
77
pthread_rwlock_wrlock(&schema_lock);
77
79
for (CachedDirectory::Entries::iterator fileIter= files.begin();
78
80
fileIter != files.end(); fileIter++)
86
88
if (readSchemaFile(entry->filename, schema_message))
88
identifier::Schema schema_identifier(schema_message.name());
90
SchemaIdentifier schema_identifier(schema_message.name());
90
92
pair<SchemaCache::iterator, bool> ret=
91
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
93
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
93
95
if (ret.second == false)
95
97
abort(); // If this has happened, something really bad is going down.
101
void Schema::startup(drizzled::Session &)
105
void Schema::doGetSchemaIdentifiers(identifier::Schema::vector &set_of_names)
101
pthread_rwlock_unlock(&schema_lock);
104
void Schema::doGetSchemaIdentifiers(SchemaIdentifierList &set_of_names)
106
if (not pthread_rwlock_rdlock(&schema_lock))
109
108
for (SchemaCache::iterator iter= schema_cache.begin();
110
109
iter != schema_cache.end();
113
set_of_names.push_back(identifier::Schema((*iter).second->name()));
112
set_of_names.push_back(SchemaIdentifier((*iter).second.name()));
116
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);
119
drizzled::message::schema::shared_ptr Schema::doGetSchemaDefinition(const identifier::Schema &schema_identifier)
133
bool Schema::doGetSchemaDefinition(const SchemaIdentifier &schema_identifier, message::Schema &schema_message)
122
SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
124
if (iter != schema_cache.end())
135
if (not pthread_rwlock_rdlock(&schema_lock))
126
drizzled::message::schema::shared_ptr schema_message;
127
schema_message= (*iter).second;
128
mutex.unlock_shared();
130
return schema_message;
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);
132
mutex.unlock_shared();
134
return drizzled::message::schema::shared_ptr();
150
// Fail to disk based means
151
return readSchemaFile(schema_identifier.getPath(), schema_message);
138
154
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
140
identifier::Schema schema_identifier(schema_message.name());
156
SchemaIdentifier schema_identifier(schema_message.name());
142
158
if (mkdir(schema_identifier.getPath().c_str(), 0777) == -1)
144
sql_perror(schema_identifier.getPath().c_str());
148
161
if (not writeSchemaFile(schema_identifier, schema_message))
168
if (not pthread_rwlock_wrlock(&schema_lock))
156
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
157
pair<SchemaCache::iterator, bool> ret=
158
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
161
if (ret.second == false)
163
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);
170
bool Schema::doDropSchema(const identifier::Schema &schema_identifier)
184
bool Schema::doDropSchema(const SchemaIdentifier &schema_identifier)
186
message::Schema schema_message;
172
188
string schema_file(schema_identifier.getPath());
173
189
schema_file.append(1, FN_LIBCHAR);
174
190
schema_file.append(MY_DB_OPT_FILE);
176
if (not doGetSchemaDefinition(schema_identifier))
192
if (not doGetSchemaDefinition(schema_identifier, schema_message))
179
195
// No db.opt file, no love from us.
180
196
if (access(schema_file.c_str(), F_OK))
182
sql_perror(schema_file.c_str());
198
perror(schema_file.c_str());
186
202
if (unlink(schema_file.c_str()))
188
sql_perror(schema_file.c_str());
204
perror(schema_file.c_str());
192
208
if (rmdir(schema_identifier.getPath().c_str()))
194
sql_perror(schema_identifier.getPath().c_str());
210
perror(schema_identifier.getPath().c_str());
195
211
//@todo If this happens, we want a report of it. For the moment I dump
196
212
//to stderr so I can catch it in Hudson.
197
213
CachedDirectory dir(schema_identifier.getPath());
201
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
202
schema_cache.erase(schema_identifier.getPath());
217
if (not pthread_rwlock_wrlock(&schema_lock))
219
schema_cache.erase(schema_identifier.getPath());
220
pthread_rwlock_unlock(&schema_lock);
207
226
bool Schema::doAlterSchema(const drizzled::message::Schema &schema_message)
209
identifier::Schema schema_identifier(schema_message.name());
228
SchemaIdentifier schema_identifier(schema_message.name());
211
230
if (access(schema_identifier.getPath().c_str(), F_OK))
214
233
if (writeSchemaFile(schema_identifier, schema_message))
216
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
217
schema_cache.erase(schema_identifier.getPath());
219
pair<SchemaCache::iterator, bool> ret=
220
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
222
if (ret.second == false)
224
abort(); // If this has happened, something really bad is going down.
235
if (not pthread_rwlock_wrlock(&schema_lock))
237
schema_cache.erase(schema_identifier.getPath());
239
pair<SchemaCache::iterator, bool> ret=
240
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
242
if (ret.second == false)
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.
302
bool Schema::readSchemaFile(const drizzled::identifier::Schema &schema_identifier, drizzled::message::Schema &schema)
329
bool Schema::readSchemaFile(const std::string &schema_file_name, drizzled::message::Schema &schema_message)
304
return readSchemaFile(schema_identifier.getPath(), schema);
331
string db_opt_path(schema_file_name);
307
bool Schema::readSchemaFile(std::string db_opt_path, drizzled::message::Schema &schema)
310
334
Pass an empty file name, and the database options file name as extension
311
335
to avoid table name to file name encoding.
323
347
if (input.good())
325
if (schema.ParseFromIstream(&input))
349
if (schema_message.ParseFromIstream(&input))
330
354
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
331
schema.InitializationErrorString().empty() ? "unknown" : schema.InitializationErrorString().c_str());
355
schema_message.InitializationErrorString().empty() ? "unknown" : schema_message.InitializationErrorString().c_str());
335
sql_perror(db_opt_path.c_str());
359
perror(db_opt_path.c_str());
365
bool Schema::doCanCreateTable(const drizzled::TableIdentifier &identifier)
367
if (static_cast<const SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
341
375
void Schema::doGetTableIdentifiers(drizzled::CachedDirectory&,
342
const drizzled::identifier::Schema&,
343
drizzled::identifier::Table::vector&)
376
const drizzled::SchemaIdentifier&,
377
drizzled::TableIdentifiers&)