23 #include <drizzled/error.h>
24 #include <plugin/schema_engine/schema.h>
25 #include <drizzled/schema.h>
27 #include <drizzled/charset.h>
28 #include <drizzled/cursor.h>
29 #include <drizzled/data_home.h>
30 #include <drizzled/message/catalog.h>
32 #include <drizzled/pthread_globals.h>
34 #include <drizzled/execute.h>
36 #include <drizzled/internal/my_sys.h>
41 #include <sys/types.h>
43 #include <boost/foreach.hpp>
44 #include <google/protobuf/io/zero_copy_stream.h>
45 #include <google/protobuf/io/zero_copy_stream_impl.h>
54 const char* MY_DB_OPT_FILE=
"db.opt";
55 const char* DEFAULT_FILE_EXTENSION=
".dfe";
57 static const char* g_schema_exts[] =
64 HTON_ALTER_NOT_SUPPORTED |
65 HTON_HAS_SCHEMA_DICTIONARY |
66 HTON_SKIP_STORE_LOCK |
67 HTON_TEMPORARY_NOT_SUPPORTED),
68 schema_cache_filled(false)
70 table_definition_ext= DEFAULT_FILE_EXTENSION;
76 CachedDirectory::DIRECTORY,
true);
78 CachedDirectory::Entries files= directory.getEntries();
79 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
81 BOOST_FOREACH(CachedDirectory::Entries::reference entry, files)
83 if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
87 std::string filename= catalog_identifier.getPath();
88 filename+= FN_LIBCHAR;
89 filename+= entry->filename;
91 if (readSchemaFile(filename, schema_message))
95 schema_message.name());
97 if (! schema_message.has_catalog())
99 schema_message.set_catalog(catalog_identifier.name());
102 pair<SchemaCache::iterator, bool> ret=
103 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
114 drizzled::CachedDirectory::DIRECTORY,
116 drizzled::CachedDirectory::Entries files= directory.getEntries();
118 for (drizzled::CachedDirectory::Entries::iterator fileIter= files.begin();
119 fileIter != files.end(); fileIter++)
122 drizzled::message::catalog::shared_ptr message;
124 if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
131 prime_catalog(identifier);
135 void Schema::doGetSchemaIdentifiers(identifier::schema::vector &set_of_names)
138 BOOST_FOREACH(SchemaCache::reference iter, schema_cache)
139 set_of_names.push_back(identifier::
Schema(identifier::Catalog(iter.second->catalog()),
140 iter.second->name()));
141 mutex.unlock_shared();
144 drizzled::message::schema::shared_ptr
Schema::doGetSchemaDefinition(const identifier::
Schema &schema_identifier)
147 SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
148 if (iter != schema_cache.end())
150 drizzled::message::schema::shared_ptr schema_message= iter->second;
151 mutex.unlock_shared();
152 return schema_message;
154 mutex.unlock_shared();
155 return drizzled::message::schema::shared_ptr();
162 schema_message.name());
164 if (mkdir(schema_identifier.getPath().c_str(), 0777) == -1)
166 sql_perror(schema_identifier.getPath().c_str());
170 if (not writeSchemaFile(schema_identifier, schema_message))
172 rmdir(schema_identifier.getPath().c_str());
177 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
178 pair<SchemaCache::iterator, bool> ret=
179 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
187 string schema_file(schema_identifier.getPath());
188 schema_file.append(1, FN_LIBCHAR);
189 schema_file.append(MY_DB_OPT_FILE);
191 if (not doGetSchemaDefinition(schema_identifier))
195 if (access(schema_file.c_str(), F_OK))
197 sql_perror(schema_file.c_str());
201 if (unlink(schema_file.c_str()))
203 sql_perror(schema_file.c_str());
207 if (rmdir(schema_identifier.getPath().c_str()))
209 sql_perror(schema_identifier.getPath().c_str());
216 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
217 schema_cache.erase(schema_identifier.getPath());
225 schema_message.name());
227 if (access(schema_identifier.getPath().c_str(), F_OK))
232 if (writeSchemaFile(schema_identifier, schema_message))
234 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
235 schema_cache.erase(schema_identifier.getPath());
237 pair<SchemaCache::iterator, bool> ret=
238 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
254 char schema_file_tmp[FN_REFLEN];
255 string schema_file(schema_identifier.getPath());
258 schema_file.append(1, FN_LIBCHAR);
259 schema_file.append(MY_DB_OPT_FILE);
261 snprintf(schema_file_tmp, FN_REFLEN,
"%sXXXXXX", schema_file.c_str());
263 int fd= mkstemp(schema_file_tmp);
267 sql_perror(schema_file_tmp);
275 success= db.SerializeToFileDescriptor(fd);
284 my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
285 db.InitializationErrorString().empty() ?
"unknown" : db.InitializationErrorString().c_str());
288 sql_perror(schema_file_tmp);
290 if (unlink(schema_file_tmp))
291 sql_perror(schema_file_tmp);
298 sql_perror(schema_file_tmp);
300 if (unlink(schema_file_tmp))
301 sql_perror(schema_file_tmp);
306 if (rename(schema_file_tmp, schema_file.c_str()) == -1)
308 if (unlink(schema_file_tmp))
309 sql_perror(schema_file_tmp);
320 return readSchemaFile(schema_identifier.getPath(), schema);
329 db_opt_path.append(1, FN_LIBCHAR);
330 db_opt_path.append(MY_DB_OPT_FILE);
332 fstream input(db_opt_path.c_str(), ios::in | ios::binary);
341 if (schema.ParseFromIstream(&input))
346 my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
347 schema.InitializationErrorString().empty() ?
"unknown" : schema.InitializationErrorString().c_str());
351 sql_perror(db_opt_path.c_str());
359 drizzled::identifier::table::vector&)
365 return g_schema_exts;
TODO: Rename this file - func.h is stupid.
bool writeSchemaFile(const drizzled::identifier::Schema &schema_identifier, const drizzled::message::Schema &db)
const char ** bas_ext() const
Defines the interface to the CachedDirectory class.