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>
52 using namespace drizzled;
54 const char* MY_DB_OPT_FILE=
"db.opt";
55 const char* DEFAULT_FILE_EXTENSION=
".dfe";
57 static const char* g_schema_exts[] =
63 drizzled::plugin::StorageEngine(
"SchemaEngine",
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)));
113 drizzled::CachedDirectory::DIRECTORY,
115 drizzled::CachedDirectory::Entries files= directory.getEntries();
117 for (drizzled::CachedDirectory::Entries::iterator fileIter= files.begin();
118 fileIter != files.end(); fileIter++)
121 drizzled::message::catalog::shared_ptr message;
123 if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
128 prime_catalog(identifier);
132 void Schema::doGetSchemaIdentifiers(identifier::schema::vector &set_of_names)
135 BOOST_FOREACH(SchemaCache::reference iter, schema_cache)
136 set_of_names.push_back(identifier::
Schema(identifier::Catalog(iter.second->catalog()),
137 iter.second->name()));
138 mutex.unlock_shared();
141 drizzled::message::schema::shared_ptr
Schema::doGetSchemaDefinition(const identifier::
Schema &schema_identifier)
144 SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
145 if (iter != schema_cache.end())
147 drizzled::message::schema::shared_ptr schema_message= iter->second;
148 mutex.unlock_shared();
149 return schema_message;
151 mutex.unlock_shared();
152 return drizzled::message::schema::shared_ptr();
159 schema_message.name());
161 if (mkdir(schema_identifier.getPath().c_str(), 0777) == -1)
163 sql_perror(schema_identifier.getPath().c_str());
167 if (not writeSchemaFile(schema_identifier, schema_message))
169 rmdir(schema_identifier.getPath().c_str());
174 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
175 pair<SchemaCache::iterator, bool> ret=
176 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
184 string schema_file(schema_identifier.getPath());
185 schema_file.append(1, FN_LIBCHAR);
186 schema_file.append(MY_DB_OPT_FILE);
188 if (not doGetSchemaDefinition(schema_identifier))
192 if (access(schema_file.c_str(), F_OK))
194 sql_perror(schema_file.c_str());
198 if (unlink(schema_file.c_str()))
200 sql_perror(schema_file.c_str());
204 if (rmdir(schema_identifier.getPath().c_str()))
206 sql_perror(schema_identifier.getPath().c_str());
213 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
214 schema_cache.erase(schema_identifier.getPath());
222 schema_message.name());
224 if (access(schema_identifier.getPath().c_str(), F_OK))
227 if (writeSchemaFile(schema_identifier, schema_message))
229 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
230 schema_cache.erase(schema_identifier.getPath());
232 pair<SchemaCache::iterator, bool> ret=
233 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
248 char schema_file_tmp[FN_REFLEN];
249 string schema_file(schema_identifier.getPath());
252 schema_file.append(1, FN_LIBCHAR);
253 schema_file.append(MY_DB_OPT_FILE);
255 snprintf(schema_file_tmp, FN_REFLEN,
"%sXXXXXX", schema_file.c_str());
257 int fd= mkstemp(schema_file_tmp);
261 sql_perror(schema_file_tmp);
269 success= db.SerializeToFileDescriptor(fd);
278 my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
279 db.InitializationErrorString().empty() ?
"unknown" : db.InitializationErrorString().c_str());
282 sql_perror(schema_file_tmp);
284 if (unlink(schema_file_tmp))
285 sql_perror(schema_file_tmp);
292 sql_perror(schema_file_tmp);
294 if (unlink(schema_file_tmp))
295 sql_perror(schema_file_tmp);
300 if (rename(schema_file_tmp, schema_file.c_str()) == -1)
302 if (unlink(schema_file_tmp))
303 sql_perror(schema_file_tmp);
314 return readSchemaFile(schema_identifier.getPath(), schema);
323 db_opt_path.append(1, FN_LIBCHAR);
324 db_opt_path.append(MY_DB_OPT_FILE);
326 fstream input(db_opt_path.c_str(), ios::in | ios::binary);
335 if (schema.ParseFromIstream(&input))
340 my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
341 schema.InitializationErrorString().empty() ?
"unknown" : schema.InitializationErrorString().c_str());
345 sql_perror(db_opt_path.c_str());
353 drizzled::identifier::table::vector&)
359 return g_schema_exts;
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.