diff options
author | randomdan <randomdan@localhost> | 2011-06-11 03:00:47 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-06-11 03:00:47 +0000 |
commit | a1269f80d17fd09705a61dee39451fea392e0f56 (patch) | |
tree | 2ceac3ab89da2a7dbb74b37f95ee135969cdb467 | |
parent | Propagate features (diff) | |
download | project2-a1269f80d17fd09705a61dee39451fea392e0f56.tar.bz2 project2-a1269f80d17fd09705a61dee39451fea392e0f56.tar.xz project2-a1269f80d17fd09705a61dee39451fea392e0f56.zip |
Make named types code totally generic
Convert RDBMS DB types to new named types system and remove all the hacky mess previous used
-rw-r--r-- | project2/Jamfile.jam | 31 | ||||
-rw-r--r-- | project2/rdbmsDataSource.cpp | 42 | ||||
-rw-r--r-- | project2/rdbmsDataSource.h | 19 | ||||
-rw-r--r-- | project2/sql-modODBC.cpp | 4 | ||||
-rw-r--r-- | project2/sql-modPQ.cpp | 4 | ||||
-rw-r--r-- | project2/xmlObjectLoader.cpp | 78 | ||||
-rw-r--r-- | project2/xmlObjectLoader.h | 68 |
7 files changed, 127 insertions, 119 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index caf94fd..5b9799a 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -126,28 +126,35 @@ lib p2xmlSession : <library>p2common ; -obj rdbmsDataSource : - rdbmsDataSource.cpp : - <odbc>yes:<define>WITH_ODBC - <pq>yes:<define>WITH_PQ - <odbc>yes:<library>../libodbcpp//odbcpp - <pq>yes:<library>../libpqpp//pqpp +explicit object sql-modODBC ; +obj sql-modODBC : + sql-modODBC.cpp : + <library>../libodbcpp//odbcpp <library>libxmlpp <include>../libmisc + : : + <library>../libodbcpp//odbcpp + ; + +explicit object sql-modPQ ; +obj sql-modPQ : + sql-modPQ.cpp : + <library>../libpqpp//pqpp + <library>libxmlpp + <include>../libmisc + : : + <library>../libpqpp//pqpp ; lib p2sql : - [ glob sql*.cpp ] tablepatch.cpp rdbmsDataSource + sqlCheck.cpp sqlTask.cpp sqlMergeTask.cpp sqlRows.cpp sqlVariableBinder.cpp tablepatch.cpp rdbmsDataSource.cpp ../libdbpp//dbpp : - <odbc>yes:<library>../libodbcpp//odbcpp - <pq>yes:<library>../libpqpp//pqpp + <odbc>yes:<library>sql-modODBC + <pq>yes:<library>sql-modPQ <library>libxmlpp <library>p2common <include>../libmisc - : : - <odbc>yes:<library>../libodbcpp//odbcpp - <pq>yes:<library>../libpqpp//pqpp ; lib p2url : diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp index 1b0ab3c..f21c737 100644 --- a/project2/rdbmsDataSource.cpp +++ b/project2/rdbmsDataSource.cpp @@ -1,5 +1,4 @@ #include "rdbmsDataSource.h" -#include "xmlObjectLoader.h" #include <libxml++/nodes/textnode.h> #include <sys/utsname.h> #include "logger.h" @@ -7,16 +6,6 @@ #include <sqlext.h> #include <boost/foreach.hpp> -static const int NOTSET = 0; -#ifdef WITH_PQ -#include "../libpqpp/connection.h" -static const int PQ_TYPEID = 1; -#endif -#ifdef WITH_ODBC -#include "../libodbcpp/connection.h" -static const int ODBC_TYPEID = 2; -#endif - SimpleMessageException(UnknownConnectionProvider); /// Specialized ElementLoader for instances of RdbmsDataSource; handles persistent DB connections @@ -209,41 +198,18 @@ RdbmsDataSource::RdbmsConnection::isExpired() const return (time(NULL) > lastUsedTime + keepAliveTime); } -RdbmsDataSource::ConnectionInfo::ConnectionInfo(const xmlpp::Element * n) : - typeId(NOTSET) +RdbmsDataSource::ConnectionInfo::ConnectionInfo(const xmlpp::Element * n) { -#if WITH_ODBC - BOOST_FOREACH(const xmlpp::Node * node, n->find("odbc")) { - typeId = ODBC_TYPEID; - dsn = dynamic_cast<const xmlpp::Element *>(node)->get_child_text()->get_content(); - } -#endif -#if WITH_PQ - BOOST_FOREACH(const xmlpp::Node * node, n->find("postgresql")) { - typeId = PQ_TYPEID; + BOOST_FOREACH(const xmlpp::Node * node, n->get_children()) { + typeId = LoaderBase::getLoader<ConnectionLoader, UnknownConnectionProvider>(node->get_name()); dsn = dynamic_cast<const xmlpp::Element *>(node)->get_child_text()->get_content(); } -#endif - if (typeId == NOTSET || dsn.empty()) { - throw UnknownConnectionProvider(n->get_path()); - } } DB::Connection * RdbmsDataSource::ConnectionInfo::connect() const { -#if WITH_ODBC - if (typeId == ODBC_TYPEID) { - return new ODBC::Connection(dsn); - } -#endif -#if WITH_PQ - if (typeId == PQ_TYPEID) { - return new PQ::Connection(dsn); - } -#endif - // This should never happen if the object was constructed correctly - throw UnknownConnectionProvider(__PRETTY_FUNCTION__); + return typeId->connect(dsn); } bool diff --git a/project2/rdbmsDataSource.h b/project2/rdbmsDataSource.h index 857173b..0e175e7 100644 --- a/project2/rdbmsDataSource.h +++ b/project2/rdbmsDataSource.h @@ -8,6 +8,23 @@ #include "dataSource.h" #include "../libdbpp/connection.h" #include "../libdbpp/error.h" +#include "xmlObjectLoader.h" + +/// Base class to implement DB connection type modules +class ConnectionLoader : public ComponentLoader { + public: + virtual DB::Connection * connect(const std::string & dsn) const = 0; +}; + +/// Helper implemention for specific DB types +template <class DBType> +class ConnectionLoaderImpl : public ConnectionLoader { + public: + virtual DB::Connection * connect(const std::string & dsn) const + { + return new DBType(dsn); + } +}; /// Project2 component to provide access to transactional RDBMS data sources class RdbmsDataSource : public DataSource { @@ -37,7 +54,7 @@ class RdbmsDataSource : public DataSource { private: std::string dsn; - int typeId; + boost::shared_ptr<ConnectionLoader> typeId; }; typedef boost::shared_ptr<RdbmsConnection> ConnectionPtr; diff --git a/project2/sql-modODBC.cpp b/project2/sql-modODBC.cpp new file mode 100644 index 0000000..ca57731 --- /dev/null +++ b/project2/sql-modODBC.cpp @@ -0,0 +1,4 @@ +#include "rdbmsDataSource.h" +#include "../libodbcpp/connection.h" +typedef ODBC::Connection ODBCConnection; +DECLARE_COMPONENT_LOADER("odbc", ODBCConnection, ConnectionLoader) diff --git a/project2/sql-modPQ.cpp b/project2/sql-modPQ.cpp new file mode 100644 index 0000000..499d8e7 --- /dev/null +++ b/project2/sql-modPQ.cpp @@ -0,0 +1,4 @@ +#include "rdbmsDataSource.h" +#include "../libpqpp/connection.h" +typedef PQ::Connection PQConnection; +DECLARE_COMPONENT_LOADER("postgresql", PQConnection, ConnectionLoader) diff --git a/project2/xmlObjectLoader.cpp b/project2/xmlObjectLoader.cpp index 9187c82..372081b 100644 --- a/project2/xmlObjectLoader.cpp +++ b/project2/xmlObjectLoader.cpp @@ -11,15 +11,6 @@ unsigned int LoaderBase::depth = 0; std::set<SourceObjectPtr> LoaderBase::loadedObjects; typedef std::map<std::string, boost::shared_ptr<ElementLoader> > ElementLoaderMap; -ElementLoaderMap * & -objLoaders() -{ - static ElementLoaderMap * _objLoaders = NULL; - if (!_objLoaders) { - _objLoaders = new ElementLoaderMap(); - } - return _objLoaders; -} LoaderBase::LoaderBase(bool r) : recursive(r), @@ -50,27 +41,21 @@ LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly, Unsupport if (!childrenOnly && node->get_namespace_uri() == ns) { Glib::ustring name = node->get_name(); unsigned int stored = 0; - ElementLoaderMap::const_iterator i = objLoaders()->find(name); - if (i != objLoaders()->end()) { - SourceObjectPtr o = i->second->go(node); - created += 1; - loadedObjects.insert(o); - BOOST_FOREACH(std::set<boost::intrusive_ptr<Storer> >::value_type s, supportedStorers) { - if (s->save(o, node)) { - stored += 1; - } - } - if (stored < 1) { - if (uh == ErrorOnUnsupported) { - throw NotSupported(name); - } - else if (uh == WarnOnUnsupported) { - Logger()->messagef(LOG_WARNING, "'%s' unsupported in this location", name.c_str()); - } + SourceObjectPtr o = getLoader<ElementLoader, NotSupported>(name)->go(node); + created += 1; + loadedObjects.insert(o); + BOOST_FOREACH(std::set<boost::intrusive_ptr<Storer> >::value_type s, supportedStorers) { + if (s->save(o, node)) { + stored += 1; } } - else { - throw NotSupported(name); + if (stored < 1) { + if (uh == ErrorOnUnsupported) { + throw NotSupported(name); + } + else if (uh == WarnOnUnsupported) { + Logger()->messagef(LOG_WARNING, "'%s' unsupported in this location", name.c_str()); + } } } if (created == 0 && (recursive || childrenOnly)) { @@ -95,26 +80,9 @@ LoaderBase::collectAll(const CommonObjects * co, const xmlpp::Element * node, bo } void -LoaderBase::newLoader(const std::string & n, ElementLoader * l) -{ - objLoaders()->insert(ElementLoaderMap::value_type(n, boost::shared_ptr<ElementLoader>(l))); -} - -void -LoaderBase::removeLoader(const std::string & n) -{ - ElementLoaderMap * & o = objLoaders(); - o->erase(n); - if (o->empty()) { - delete o; - o = NULL; - } -} - -void LoaderBase::onIdle() { - BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders<ElementLoader>()) { l.second->onIdle(); } } @@ -126,7 +94,7 @@ LoaderBase::onIteration() depth = 0; loadedObjects.clear(); - BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders<ElementLoader>()) { l.second->onIteration(); } } @@ -134,16 +102,11 @@ LoaderBase::onIteration() void LoaderBase::onPeriodic() { - BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders<ElementLoader>()) { l.second->onPeriodic(); } } -void -ElementLoader::onIdle() -{ -} - Glib::ustring xmlChildText(const xmlpp::Node * p, const Glib::ustring & t) { @@ -161,12 +124,17 @@ xmlChildText(const xmlpp::Node * p, const Glib::ustring & t) } void -ElementLoader::onIteration() +ComponentLoader::onIdle() +{ +} + +void +ComponentLoader::onIteration() { } void -ElementLoader::onPeriodic() +ComponentLoader::onPeriodic() { } diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h index fb0ac16..e68a390 100644 --- a/project2/xmlObjectLoader.h +++ b/project2/xmlObjectLoader.h @@ -4,6 +4,7 @@ #include <set> #include <string> #include <boost/intrusive_ptr.hpp> +#include <boost/shared_ptr.hpp> #include "intrusivePtrBase.h" #include "sourceObject.h" #include "exceptions.h" @@ -34,8 +35,44 @@ class LoaderBase { static void onIteration(); static void onPeriodic(); - static void newLoader(const std::string & N, ElementLoader * L); - static void removeLoader(const std::string & N); + template <class T> + static std::map<std::string, boost::shared_ptr<T> > * & objLoaders() + { + static std::map<std::string, boost::shared_ptr<T> > * _objLoaders = NULL; + if (!_objLoaders) { + _objLoaders = new std::map<std::string, boost::shared_ptr<T> >(); + } + return _objLoaders; + } + + template <class T> + static void newLoader(const std::string & n, T * l) + { + objLoaders<T>()->insert(std::pair<std::string, boost::shared_ptr<T> >(n, boost::shared_ptr<T>(l))); + } + + template <class T> + static void removeLoader(const std::string & n) + { + std::map<std::string, boost::shared_ptr<T> > * & o = objLoaders<T>(); + o->erase(n); + if (o->empty()) { + delete o; + o = NULL; + } + } + + template <class L, class E> + static boost::shared_ptr<L> getLoader(const std::string & n) + { + typename std::map<std::string, boost::shared_ptr<L> >::const_iterator i = objLoaders<L>()->find(n); + if (i != objLoaders<L>()->end()) { + return i->second; + } + else { + throw E(n); + } + } private: static unsigned int depth; @@ -47,25 +84,30 @@ class LoaderBase { const Glib::ustring ns; }; +#define DECLARE_CUSTOM_COMPONENT_LOADER(N, I, T, B) \ + static void init_loader_##I() __attribute__ ((constructor(201))); \ + static void init_loader_##I() { LoaderBase::newLoader<B>(N, new T()); } \ + static void kill_loader_##I() __attribute__ ((destructor(201))); \ + static void kill_loader_##I() { LoaderBase::removeLoader<B>(N); } #define DECLARE_CUSTOM_LOADER(N, T) \ - static void init_loader_##T() __attribute__ ((constructor(201))); \ - static void init_loader_##T() { LoaderBase::newLoader(N, new T()); } \ - static void kill_loader_##T() __attribute__ ((destructor(201))); \ - static void kill_loader_##T() { LoaderBase::removeLoader(N); } + DECLARE_CUSTOM_COMPONENT_LOADER(N, T, T, ElementLoader) +#define DECLARE_COMPONENT_LOADER(N, T, B) \ + DECLARE_CUSTOM_COMPONENT_LOADER(N, T, B##Impl<T>, B) #define DECLARE_LOADER(N, T) \ - static void init_loader_##T() __attribute__ ((constructor(201))); \ - static void init_loader_##T() { LoaderBase::newLoader(N, new ElementLoaderImpl<T>()); } \ - static void kill_loader_##T() __attribute__ ((destructor(201))); \ - static void kill_loader_##T() { LoaderBase::removeLoader(N); } + DECLARE_COMPONENT_LOADER(N, T, ElementLoader) -/// Helper for loading and maintaining Project2 script components -class ElementLoader { +/// Helper for loading and maintaining Project2 components +class ComponentLoader { public: - virtual SourceObjectPtr go(const xmlpp::Element * xml) const = 0; virtual void onIdle(); // When the app engine goes idle virtual void onIteration(); // When the app engine has completed an iteration virtual void onPeriodic(); // When the app engine feels like it }; +/// Helper for loading and maintaining Project2 script components +class ElementLoader : public ComponentLoader { + public: + virtual SourceObjectPtr go(const xmlpp::Element * xml) const = 0; +}; /// Helper for loading and maintaining Project2 script components (typed implementation) template <class X> |