42
51
HTON_HAS_DATA_DICTIONARY |
43
52
HTON_HAS_SCHEMA_DICTIONARY |
44
53
HTON_SKIP_STORE_LOCK |
45
HTON_TEMPORARY_NOT_SUPPORTED)
54
HTON_TEMPORARY_NOT_SUPPORTED),
55
schema_cache_filled(false)
57
table_definition_ext= DEFAULT_FILE_EXTENSION;
58
pthread_rwlock_init(&schema_lock, NULL);
64
pthread_rwlock_destroy(&schema_lock);
67
int Schema::doGetTableDefinition(Session &,
72
message::Table *table_proto)
74
string proto_path(path);
75
proto_path.append(DEFAULT_FILE_EXTENSION);
77
if (access(proto_path.c_str(), F_OK))
84
if (readTableFile(proto_path, *table_proto))
93
void Schema::doGetTableNames(CachedDirectory &directory, string&, set<string>& set_of_names)
95
CachedDirectory::Entries entries= directory.getEntries();
97
for (CachedDirectory::Entries::iterator entry_iter= entries.begin();
98
entry_iter != entries.end(); ++entry_iter)
100
CachedDirectory::Entry *entry= *entry_iter;
101
const string *filename= &entry->filename;
103
assert(filename->size());
105
const char *ext= strchr(filename->c_str(), '.');
107
if (ext == NULL || my_strcasecmp(system_charset_info, ext, DEFAULT_FILE_EXTENSION) ||
108
(filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
112
char uname[NAME_LEN + 1];
113
uint32_t file_name_len;
115
file_name_len= filename_to_tablename(filename->c_str(), uname, sizeof(uname));
116
// TODO: Remove need for memory copy here
117
uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL
118
set_of_names.insert(uname);
125
CachedDirectory directory(drizzle_data_home, CachedDirectory::DIRECTORY);
126
CachedDirectory::Entries files= directory.getEntries();
128
pthread_rwlock_wrlock(&schema_lock);
130
for (CachedDirectory::Entries::iterator fileIter= files.begin();
131
fileIter != files.end(); fileIter++)
133
CachedDirectory::Entry *entry= *fileIter;
134
message::Schema schema_message;
136
if (readSchemaFile(entry->filename, schema_message))
138
pair<SchemaCache::iterator, bool> ret=
139
schema_cache.insert(make_pair(schema_message.name(), schema_message));
141
cerr << "Caching " << schema_message.name() << "\n";
143
if (ret.second == false)
145
abort(); // If this has happened, something really bad is going down.
149
pthread_rwlock_unlock(&schema_lock);
49
152
void Schema::doGetSchemaNames(std::set<std::string>& set_of_names)
154
if (not pthread_rwlock_rdlock(&schema_lock))
156
for (SchemaCache::iterator iter= schema_cache.begin();
157
iter != schema_cache.end();
160
set_of_names.insert((*iter).first);
162
pthread_rwlock_unlock(&schema_lock);
167
// If for some reason getting a lock should fail, we resort to disk
51
169
CachedDirectory directory(drizzle_data_home, CachedDirectory::DIRECTORY);
53
171
CachedDirectory::Entries files= directory.getEntries();
63
181
bool Schema::doGetSchemaDefinition(const std::string &schema_name, message::Schema &schema_message)
65
char db_opt_path[FN_REFLEN];
69
Pass an empty file name, and the database options file name as extension
70
to avoid table name to file name encoding.
72
length= build_table_filename(db_opt_path, sizeof(db_opt_path),
73
schema_name.c_str(), "", false);
74
strcpy(db_opt_path + length, MY_DB_OPT_FILE);
76
fstream input(db_opt_path, ios::in | ios::binary);
79
@note If parsing fails, either someone has done a "mkdir" or has deleted their opt file.
80
So what do we do? We muddle through the adventure by generating
81
one with a name in it, and the charset set to the default.
183
if (not pthread_rwlock_rdlock(&schema_lock))
85
if (schema_message.ParseFromIstream(&input))
185
SchemaCache::iterator iter= schema_cache.find(schema_name);
186
if (iter != schema_cache.end())
188
schema_message.CopyFrom(((*iter).second));
189
pthread_rwlock_unlock(&schema_lock);
192
pthread_rwlock_unlock(&schema_lock);
197
// Fail to disk based means
198
return readSchemaFile(schema_name, schema_message);
98
201
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
100
203
char path[FN_REFLEN+16];
101
204
uint32_t path_len;
103
206
path_len= drizzled::build_table_filename(path, sizeof(path), schema_message.name().c_str(), "", false);
104
207
path[path_len-1]= 0; // remove last '/' from path
106
209
if (mkdir(path, 0777) == -1)
109
error_erno= write_schema_file(path, schema_message);
110
if (error_erno && error_erno != EEXIST)
212
if (not writeSchemaFile(path, schema_message))
219
if (not pthread_rwlock_wrlock(&schema_lock))
221
pair<SchemaCache::iterator, bool> ret=
222
schema_cache.insert(make_pair(schema_message.name(), schema_message));
225
if (ret.second == false)
227
abort(); // If this has happened, something really bad is going down.
229
pthread_rwlock_unlock(&schema_lock);
154
275
char path[FN_REFLEN+16];
155
276
uint32_t path_len;
157
277
path_len= drizzled::build_table_filename(path, sizeof(path), schema_message.name().c_str(), "", false);
158
278
path[path_len-1]= 0; // remove last '/' from path
160
280
if (access(path, F_OK))
163
error_erno= write_schema_file(path, schema_message);
164
if (error_erno && error_erno != EEXIST)
283
if (writeSchemaFile(path, schema_message))
285
if (not pthread_rwlock_wrlock(&schema_lock))
287
schema_cache.erase(schema_message.name());
289
pair<SchemaCache::iterator, bool> ret=
290
schema_cache.insert(make_pair(schema_message.name(), schema_message));
292
if (ret.second == false)
294
abort(); // If this has happened, something really bad is going down.
297
pthread_rwlock_unlock(&schema_lock);
301
abort(); // This would leave us out of sync, suck.
187
323
int fd= mkstemp(schema_file_tmp);
192
328
if (not db.SerializeToFileDescriptor(fd))
195
331
unlink(schema_file_tmp);
199
336
if (rename(schema_file_tmp, schema_file.c_str()) == -1)
348
bool Schema::readTableFile(const std::string &path, message::Table &table_message)
350
fstream input(path.c_str(), ios::in | ios::binary);
354
if (table_message.ParseFromIstream(&input))
361
perror(path.c_str());
368
bool Schema::readSchemaFile(const std::string &schema_name, drizzled::message::Schema &schema_message)
370
char db_opt_path[FN_REFLEN];
374
Pass an empty file name, and the database options file name as extension
375
to avoid table name to file name encoding.
377
length= build_table_filename(db_opt_path, sizeof(db_opt_path),
378
schema_name.c_str(), "", false);
379
strcpy(db_opt_path + length, MY_DB_OPT_FILE);
381
fstream input(db_opt_path, ios::in | ios::binary);
384
@note If parsing fails, either someone has done a "mkdir" or has deleted their opt file.
385
So what do we do? We muddle through the adventure by generating
386
one with a name in it, and the charset set to the default.
390
if (schema_message.ParseFromIstream(&input))