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/catalog/local.h>
31 #include <drizzled/pthread_globals.h>
33 #include <drizzled/execute.h>
35 #include <drizzled/internal/my_sys.h>
40 #include <sys/types.h>
42 #include <boost/foreach.hpp>
43 #include <google/protobuf/io/zero_copy_stream.h>
44 #include <google/protobuf/io/zero_copy_stream_impl.h>
51 using namespace drizzled;
53 const char* MY_DB_OPT_FILE=
"db.opt";
54 const char* DEFAULT_FILE_EXTENSION=
".dfe";
56 static const char* g_schema_exts[] =
62 drizzled::plugin::StorageEngine(
"SchemaEngine",
63 HTON_ALTER_NOT_SUPPORTED |
64 HTON_HAS_SCHEMA_DICTIONARY |
65 HTON_SKIP_STORE_LOCK |
66 HTON_TEMPORARY_NOT_SUPPORTED),
67 schema_cache_filled(false)
69 table_definition_ext= DEFAULT_FILE_EXTENSION;
75 CachedDirectory::DIRECTORY,
true);
77 CachedDirectory::Entries files= directory.getEntries();
78 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
80 BOOST_FOREACH(CachedDirectory::Entries::reference entry, files)
82 if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
86 std::string filename= catalog::local_identifier().getPath();
87 filename+= FN_LIBCHAR;
88 filename+= entry->filename;
90 if (readSchemaFile(filename, schema_message))
94 pair<SchemaCache::iterator, bool> ret=
95 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
102 void Schema::doGetSchemaIdentifiers(identifier::schema::vector &set_of_names)
105 BOOST_FOREACH(SchemaCache::reference iter, schema_cache)
106 set_of_names.push_back(identifier::
Schema(iter.second->name()));
107 mutex.unlock_shared();
110 drizzled::message::schema::shared_ptr
Schema::doGetSchemaDefinition(const identifier::
Schema &schema_identifier)
113 SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
114 if (iter != schema_cache.end())
116 drizzled::message::schema::shared_ptr schema_message= iter->second;
117 mutex.unlock_shared();
118 return schema_message;
120 mutex.unlock_shared();
121 return drizzled::message::schema::shared_ptr();
129 if (mkdir(schema_identifier.getPath().c_str(), 0777) == -1)
131 sql_perror(schema_identifier.getPath().c_str());
135 if (not writeSchemaFile(schema_identifier, schema_message))
137 rmdir(schema_identifier.getPath().c_str());
142 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
143 pair<SchemaCache::iterator, bool> ret=
144 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
152 string schema_file(schema_identifier.getPath());
153 schema_file.append(1, FN_LIBCHAR);
154 schema_file.append(MY_DB_OPT_FILE);
156 if (not doGetSchemaDefinition(schema_identifier))
160 if (access(schema_file.c_str(), F_OK))
162 sql_perror(schema_file.c_str());
166 if (unlink(schema_file.c_str()))
168 sql_perror(schema_file.c_str());
172 if (rmdir(schema_identifier.getPath().c_str()))
174 sql_perror(schema_identifier.getPath().c_str());
181 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
182 schema_cache.erase(schema_identifier.getPath());
191 if (access(schema_identifier.getPath().c_str(), F_OK))
194 if (writeSchemaFile(schema_identifier, schema_message))
196 boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
197 schema_cache.erase(schema_identifier.getPath());
199 pair<SchemaCache::iterator, bool> ret=
200 schema_cache.insert(make_pair(schema_identifier.getPath(),
new message::Schema(schema_message)));
215 char schema_file_tmp[FN_REFLEN];
216 string schema_file(schema_identifier.getPath());
219 schema_file.append(1, FN_LIBCHAR);
220 schema_file.append(MY_DB_OPT_FILE);
222 snprintf(schema_file_tmp, FN_REFLEN,
"%sXXXXXX", schema_file.c_str());
224 int fd= mkstemp(schema_file_tmp);
228 sql_perror(schema_file_tmp);
236 success= db.SerializeToFileDescriptor(fd);
245 my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
246 db.InitializationErrorString().empty() ?
"unknown" : db.InitializationErrorString().c_str());
249 sql_perror(schema_file_tmp);
251 if (unlink(schema_file_tmp))
252 sql_perror(schema_file_tmp);
259 sql_perror(schema_file_tmp);
261 if (unlink(schema_file_tmp))
262 sql_perror(schema_file_tmp);
267 if (rename(schema_file_tmp, schema_file.c_str()) == -1)
269 if (unlink(schema_file_tmp))
270 sql_perror(schema_file_tmp);
281 return readSchemaFile(schema_identifier.getPath(), schema);
290 db_opt_path.append(1, FN_LIBCHAR);
291 db_opt_path.append(MY_DB_OPT_FILE);
293 fstream input(db_opt_path.c_str(), ios::in | ios::binary);
302 if (schema.ParseFromIstream(&input))
307 my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
308 schema.InitializationErrorString().empty() ?
"unknown" : schema.InitializationErrorString().c_str());
312 sql_perror(db_opt_path.c_str());
320 drizzled::identifier::table::vector&)
326 return g_schema_exts;