00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <fcntl.h>
00024 #include <sys/stat.h>
00025 #include <sys/types.h>
00026
00027 #include <drizzled/display.h>
00028 #include <google/protobuf/io/zero_copy_stream.h>
00029 #include <google/protobuf/io/zero_copy_stream_impl.h>
00030
00031 #include <iostream>
00032 #include <fstream>
00033 #include <string>
00034
00035 #include <drizzled/data_home.h>
00036 #include <drizzled/cached_directory.h>
00037 #include <drizzled/catalog/local.h>
00038 #include <plugin/catalog/module.h>
00039
00040 namespace plugin {
00041 namespace catalog {
00042
00043 static std::string CATALOG_OPT_EXT(".cat");
00044
00045 bool Engine::create(const drizzled::identifier::Catalog &identifier, drizzled::message::catalog::shared_ptr &message)
00046 {
00047 if (mkdir(identifier.getPath().c_str(), 0777) == -1)
00048 return false;
00049
00050 if (not writeFile(identifier, message))
00051 {
00052 rmdir(identifier.getPath().c_str());
00053
00054 return false;
00055 }
00056
00057 return true;
00058 }
00059
00060 bool Engine::drop(const drizzled::identifier::Catalog &identifier)
00061 {
00062 std::string file(identifier.getPath());
00063 file.append(1, FN_LIBCHAR);
00064 file.append(CATALOG_OPT_EXT);
00065
00066
00067 if (access(file.c_str(), F_OK))
00068 {
00069 perror(file.c_str());
00070 return false;
00071 }
00072
00073 if (unlink(file.c_str()))
00074 {
00075 perror(file.c_str());
00076 return false;
00077 }
00078
00079 if (rmdir(identifier.getPath().c_str()))
00080 {
00081 perror(identifier.getPath().c_str());
00082
00083
00084 drizzled::CachedDirectory dir(identifier.getPath());
00085 }
00086
00087 return true;
00088 }
00089
00090 void Engine::getMessages(drizzled::message::catalog::vector &messages)
00091 {
00092 prime(messages);
00093 }
00094
00095 drizzled::message::catalog::shared_ptr Engine::getMessage(drizzled::identifier::Catalog::const_reference identifier)
00096 {
00097 if (drizzled::catalog::local_identifier() == identifier)
00098 {
00099 return drizzled::message::catalog::make_shared(identifier);
00100 }
00101
00102 drizzled::message::catalog::shared_ptr message;
00103 if ((message= readFile(identifier)))
00104 {
00105 assert(message);
00106 return message;
00107 }
00108
00109 return drizzled::message::catalog::shared_ptr();
00110 }
00111
00112 void Engine::prime(drizzled::message::catalog::vector &messages)
00113 {
00114 bool found_local= false;
00115 drizzled::CachedDirectory directory(drizzled::getFullDataHome().file_string(), drizzled::CachedDirectory::DIRECTORY, true);
00116 drizzled::CachedDirectory::Entries files= directory.getEntries();
00117
00118
00119 for (drizzled::CachedDirectory::Entries::iterator fileIter= files.begin();
00120 fileIter != files.end(); fileIter++)
00121 {
00122 drizzled::CachedDirectory::Entry *entry= *fileIter;
00123 drizzled::message::catalog::shared_ptr message;
00124
00125 if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
00126 continue;
00127
00128 drizzled::identifier::Catalog identifier(entry->filename);
00129
00130 if (message= readFile(identifier))
00131 {
00132 messages.push_back(message);
00133
00134 if (drizzled::catalog::local_identifier() == identifier)
00135 found_local= true;
00136 }
00137 }
00138
00139 if (not found_local)
00140 {
00141 messages.push_back(drizzled::catalog::local()->message());
00142 }
00143 }
00144
00145 bool Engine::writeFile(const drizzled::identifier::Catalog &identifier, drizzled::message::catalog::shared_ptr &message)
00146 {
00147 char file_tmp[FN_REFLEN];
00148 std::string file(identifier.getPath());
00149
00150
00151 file.append(1, FN_LIBCHAR);
00152 file.append(CATALOG_OPT_EXT);
00153
00154 snprintf(file_tmp, FN_REFLEN, "%sXXXXXX", file.c_str());
00155
00156 int fd= mkstemp(file_tmp);
00157
00158 if (fd == -1)
00159 {
00160 perror(file_tmp);
00161
00162 return false;
00163 }
00164
00165 bool success;
00166
00167 try {
00168 success= message->SerializeToFileDescriptor(fd);
00169 }
00170 catch (...)
00171 {
00172 success= false;
00173 }
00174
00175 if (not success)
00176 {
00177 drizzled::my_error(drizzled::ER_CORRUPT_CATALOG_DEFINITION, MYF(0), file.c_str(),
00178 message->InitializationErrorString().empty() ? "unknown" : message->InitializationErrorString().c_str());
00179
00180 if (close(fd) == -1)
00181 perror(file_tmp);
00182
00183 if (unlink(file_tmp))
00184 perror(file_tmp);
00185
00186 return false;
00187 }
00188
00189 if (close(fd) == -1)
00190 {
00191 perror(file_tmp);
00192
00193 if (unlink(file_tmp))
00194 perror(file_tmp);
00195
00196 return false;
00197 }
00198
00199 if (rename(file_tmp, file.c_str()) == -1)
00200 {
00201 if (unlink(file_tmp))
00202 perror(file_tmp);
00203
00204 return false;
00205 }
00206
00207 return true;
00208 }
00209
00210
00211 drizzled::message::catalog::shared_ptr Engine::readFile(drizzled::identifier::Catalog::const_reference identifier)
00212 {
00213 std::string path(identifier.getPath());
00214
00215
00216
00217
00218
00219 path.append(1, FN_LIBCHAR);
00220 path.append(CATALOG_OPT_EXT);
00221
00222 std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
00223
00224 if (input.good())
00225 {
00226 drizzled::message::catalog::shared_ptr message= drizzled::message::catalog::make_shared(identifier);
00227
00228 if (not message)
00229 return drizzled::message::catalog::shared_ptr();
00230
00231
00232 if (message->ParseFromIstream(&input))
00233 {
00234 return message;
00235 }
00236
00237 drizzled::my_error(drizzled::ER_CORRUPT_CATALOG_DEFINITION, MYF(0), path.c_str(),
00238 message->InitializationErrorString().empty() ? "unknown" : message->InitializationErrorString().c_str());
00239 }
00240 else
00241 {
00242 perror(path.c_str());
00243 }
00244
00245 return drizzled::message::catalog::shared_ptr();
00246 }
00247
00248 }
00249 }