20 #include "soci_backends_config.h" 32 #define LOCK(x) EnterCriticalSection(x) 33 #define UNLOCK(x) LeaveCriticalSection(x) 34 #define MUTEX_INIT(x) InitializeCriticalSection(x) 35 #define MUTEX_DEST(x) DeleteCriticalSection(x) 37 #define DLOPEN(x) LoadLibraryA(x) 39 #define DLOPEN(x) LoadLibrary(x) 41 #define DLCLOSE(x) FreeLibrary(x) 42 #define DLSYM(x, y) GetProcAddress(x, y) 44 #ifdef SOCI_ABI_VERSION 45 #define LIBNAME(x) (SOCI_LIB_PREFIX + x + "_" SOCI_ABI_VERSION SOCI_LIB_SUFFIX) 47 #define LIBNAME(x) (SOCI_LIB_PREFIX + x + SOCI_LIB_SUFFIX) 48 #endif // SOCI_ABI_VERSION 58 #define LOCK(x) pthread_mutex_lock(x) 59 #define UNLOCK(x) pthread_mutex_unlock(x) 60 #define MUTEX_INIT(x) pthread_mutex_init(x, NULL) 61 #define MUTEX_DEST(x) pthread_mutex_destroy(x) 62 #define DLOPEN(x) dlopen(x, RTLD_LAZY) 63 #define DLCLOSE(x) dlclose(x) 64 #define DLSYM(x, y) dlsym(x, y) 66 #ifdef SOCI_ABI_VERSION 69 #define LIBNAME(x) (SOCI_LIB_PREFIX + x + "." SOCI_ABI_VERSION SOCI_LIB_SUFFIX) 71 #define LIBNAME(x) (SOCI_LIB_PREFIX + x + SOCI_LIB_SUFFIX "." SOCI_ABI_VERSION) 75 #define LIBNAME(x) (SOCI_LIB_PREFIX + x + SOCI_LIB_SUFFIX) 76 #endif // SOCI_ABI_VERSION 88 info() : handler_(0), factory_(0) {}
91 typedef std::map<std::string, info> factory_map;
92 factory_map factories_;
94 std::vector<std::string> search_paths_;
98 std::vector<std::string> get_default_paths()
100 std::vector<std::string> paths;
103 char const*
const penv = std::getenv(
"SOCI_BACKENDS_PATH");
106 paths.push_back(
".");
107 paths.push_back(DEFAULT_BACKENDS_PATH);
111 std::string
const env = penv;
114 paths.push_back(
".");
115 paths.push_back(DEFAULT_BACKENDS_PATH);
119 std::string::size_type searchFrom = 0;
120 while (searchFrom != env.size())
122 std::string::size_type
const found = env.find(
":", searchFrom);
123 if (found == searchFrom)
127 else if (std::string::npos != found)
129 std::string
const path(env.substr(searchFrom, found - searchFrom));
130 paths.push_back(path);
132 searchFrom = found + 1;
136 std::string
const path = env.substr(searchFrom);
137 paths.push_back(path);
139 searchFrom = env.size();
147 struct static_state_mgr
153 search_paths_ = get_default_paths();
168 ~scoped_lock() {
UNLOCK(mptr); };
174 void do_unload(std::string
const & name)
176 factory_map::iterator i = factories_.find(name);
178 if (i != factories_.end())
191 void do_register_backend(std::string
const & name, std::string
const & shared_object)
200 if (shared_object.empty() ==
false)
202 h =
DLOPEN(shared_object.c_str());
211 for (std::size_t i = 0; i != search_paths_.size(); ++i)
213 std::string
const fullFileName(search_paths_[i] +
"/" +
LIBNAME(name));
214 h =
DLOPEN(fullFileName.c_str());
226 throw soci_error(
"Failed to find shared library for backend " + name);
229 std::string symbol =
"factory_" + name;
232 typedef bfc_ptr (*get_t)(void);
234 entry =
reinterpret_cast<get_t
>(
235 reinterpret_cast<uintptr_t
>(
DLSYM(h, symbol.c_str())));
240 throw soci_error(
"Failed to resolve dynamic symbol: " + symbol);
250 new_entry.factory_ = f;
251 new_entry.handler_ = h;
253 factories_[name] = new_entry;
260 scoped_lock lock(&mutex_);
262 factory_map::iterator i = factories_.find(name);
264 if (i != factories_.end())
266 return *(i->second.factory_);
271 do_register_backend(name, std::string());
275 i = factories_.find(name);
277 assert(i != factories_.end());
279 return *(i->second.factory_);
284 return search_paths_;
288 std::string
const& name, std::string
const& shared_object)
290 scoped_lock lock(&mutex_);
292 do_register_backend(name, shared_object);
298 scoped_lock lock(&mutex_);
305 new_entry.factory_ = &factory;
307 factories_[name] = new_entry;
312 scoped_lock lock(&mutex_);
314 std::vector<std::string> ret;
315 ret.reserve(factories_.size());
317 for (factory_map::iterator i = factories_.begin(); i != factories_.end(); ++i)
319 std::string
const& name = i->first;
328 scoped_lock lock(&mutex_);
335 scoped_lock lock(&mutex_);
337 for (factory_map::iterator i = factories_.begin(); i != factories_.end(); ++i)
SOCI_DECL std::vector< std::string > list_all()
SOCI_DECL std::vector< std::string > & search_paths()
pthread_mutex_t soci_mutex_t
SOCI_DECL void register_backend(std::string const &name, std::string const &shared_object=std::string())
backend_factory const & get(std::string const &name)
SOCI_DECL void unload(std::string const &name)
SOCI_DECL void unload_all()