diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-08 16:09:07 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-08 16:09:07 +0200 |
commit | be97326d67365e16175cc599e23348feaf80e0fe (patch) | |
tree | b38678104546ebd549824096683bd00f3f2be299 | |
parent | 0b583b575ec00c544759cbf8d6481d35c34c5f63 (diff) |
Ground work for multi-database support
All generated code now includes database id. The database-specific
database class interface has been updated to include all the database
operations. The database-specific tests now use this interface.
-rw-r--r-- | odb/database.hxx | 61 | ||||
-rw-r--r-- | odb/database.ixx | 228 | ||||
-rw-r--r-- | odb/database.txx | 99 | ||||
-rw-r--r-- | odb/forward.hxx | 35 | ||||
-rw-r--r-- | odb/polymorphic-info.hxx | 6 | ||||
-rw-r--r-- | odb/polymorphic-map.hxx | 33 | ||||
-rw-r--r-- | odb/polymorphic-map.ixx | 12 | ||||
-rw-r--r-- | odb/polymorphic-map.txx | 8 | ||||
-rw-r--r-- | odb/query.hxx | 37 | ||||
-rw-r--r-- | odb/schema-catalog-impl.hxx | 3 | ||||
-rw-r--r-- | odb/schema-catalog.cxx | 11 | ||||
-rw-r--r-- | odb/traits.hxx | 77 |
12 files changed, 398 insertions, 212 deletions
diff --git a/odb/database.hxx b/odb/database.hxx index 64f9d44..99205e7 100644 --- a/odb/database.hxx +++ b/odb/database.hxx @@ -63,7 +63,7 @@ namespace odb typename object_traits<T>::id_type persist (const typename object_traits<T>::pointer_type& obj_ptr); - // Throw object_not_persistent if not found. + // Load an object. Throw object_not_persistent if not found. // template <typename T> typename object_traits<T>::pointer_type @@ -73,6 +73,8 @@ namespace odb void load (const typename object_traits<T>::id_type& id, T& object); + // Reload an object. + // template <typename T> void reload (T& object); @@ -101,7 +103,7 @@ namespace odb void reload (const typename object_traits<T>::pointer_type& obj_ptr); - // Return NULL/false if not found. + // Loan an object if found. Return NULL/false if not found. // template <typename T> typename object_traits<T>::pointer_type @@ -250,8 +252,14 @@ namespace odb tracer_type* tracer () const; + // Database id. + // + public: + database_id + id () const; + protected: - database (); + database (database_id); private: database (const database&); @@ -264,22 +272,61 @@ namespace odb connection_ () = 0; protected: - template <typename T> + template <typename T, database_id DB> + typename object_traits<T>::id_type + persist_ (T&); + + template <typename T, database_id DB> typename object_traits<T>::id_type persist_ (const typename object_traits<T>::pointer_type&); - template <typename T> + template <typename T, database_id DB> + typename object_traits<T>::pointer_type + load_ (const typename object_traits<T>::id_type&); + + template <typename T, database_id DB> + void + load_ (const typename object_traits<T>::id_type&, T&); + + template <typename T, database_id DB> + void + reload_ (T&); + + template <typename T, database_id DB> + typename object_traits<T>::pointer_type + find_ (const typename object_traits<T>::id_type&); + + template <typename T, database_id DB> + bool + find_ (const typename object_traits<T>::id_type&, T&); + + template <typename T, database_id DB> + void + update_ (T&); + + template <typename T, database_id DB> void update_ (const typename object_traits<T>::pointer_type&); - template <typename T> + template <typename T, database_id DB> + void + erase_ (const typename object_traits<T>::id_type&); + + template <typename T, database_id DB> + void + erase_ (T&); + + template <typename T, database_id DB> void erase_ (const typename object_traits<T>::pointer_type&); - template <typename T, class_kind kind> + template <typename T, + database_id DB, + class_kind kind = class_traits<T>::kind> struct query_; protected: + database_id id_; tracer_type* tracer_; }; } diff --git a/odb/database.ixx b/odb/database.ixx index 4a00a74..aeffdec 100644 --- a/odb/database.ixx +++ b/odb/database.ixx @@ -7,11 +7,17 @@ namespace odb { inline database:: - database () - : tracer_ (0) + database (database_id id) + : id_ (id), tracer_ (0) { } + inline database_id database:: + id () const + { + return id_; + } + inline connection_ptr database:: connection () { @@ -38,6 +44,13 @@ namespace odb template <typename T> inline typename object_traits<T>::id_type database:: + persist (T& obj) + { + return persist_<T, id_default> (obj); + } + + template <typename T> + inline typename object_traits<T>::id_type database:: persist (T* p) { typedef typename object_traits<T>::pointer_type object_pointer; @@ -48,7 +61,7 @@ namespace odb // const object_pointer& pobj (p); - return persist_<T> (pobj); + return persist_<T, id_default> (pobj); } template <typename T, template <typename> class P> @@ -63,7 +76,7 @@ namespace odb // const object_pointer& pobj (p); - return persist_<T> (pobj); + return persist_<T, id_default> (pobj); } template <typename T, typename A1, template <typename, typename> class P> @@ -78,7 +91,7 @@ namespace odb // const object_pointer& pobj (p); - return persist_<T> (pobj); + return persist_<T, id_default> (pobj); } template <typename T, template <typename> class P> @@ -101,29 +114,42 @@ namespace odb inline typename object_traits<T>::id_type database:: persist (const typename object_traits<T>::pointer_type& pobj) { - return persist_<T> (pobj); + return persist_<T, id_default> (pobj); } template <typename T> inline typename object_traits<T>::pointer_type database:: - find (const typename object_traits<T>::id_type& id) + load (const typename object_traits<T>::id_type& id) { - // T is always object_type. - // + return load_<T, id_default> (id); + } - // Compiler error pointing here? Perhaps the object doesn't have the - // default constructor? - // - return object_traits<T>::find (*this, id); + template <typename T> + inline void database:: + load (const typename object_traits<T>::id_type& id, T& obj) + { + return load_<T, id_default> (id, obj); + } + + template <typename T> + inline typename object_traits<T>::pointer_type database:: + find (const typename object_traits<T>::id_type& id) + { + return find_<T, id_default> (id); } template <typename T> inline bool database:: find (const typename object_traits<T>::id_type& id, T& obj) { - // T is always object_type. - // - return object_traits<T>::find (*this, id, obj); + return find_<T, id_default> (id, obj); + } + + template <typename T> + inline void database:: + reload (T& obj) + { + reload_<T, id_default> (obj); } template <typename T> @@ -172,6 +198,13 @@ namespace odb template <typename T> inline void database:: + update (T& obj) + { + update_<T, id_default> (obj); + } + + template <typename T> + inline void database:: update (T* p) { typedef typename object_traits<T>::pointer_type object_pointer; @@ -182,7 +215,7 @@ namespace odb // const object_pointer& pobj (p); - update_<T> (pobj); + update_<T, id_default> (pobj); } template <typename T, template <typename> class P> @@ -197,7 +230,7 @@ namespace odb // const object_pointer& pobj (p); - update_<T> (pobj); + update_<T, id_default> (pobj); } template <typename T, typename A1, template <typename, typename> class P> @@ -212,7 +245,7 @@ namespace odb // const object_pointer& pobj (p); - update_<T> (pobj); + update_<T, id_default> (pobj); } template <typename T, template <typename> class P> @@ -235,42 +268,21 @@ namespace odb inline void database:: update (const typename object_traits<T>::pointer_type& pobj) { - update_<T> (pobj); + update_<T, id_default> (pobj); } template <typename T> inline void database:: - update (T& obj) + erase (const typename object_traits<T>::id_type& id) { - // T can be const T while object_type will always be T. - // - typedef typename odb::object_traits<T>::object_type object_type; - typedef odb::object_traits<object_type> object_traits; - - // Compiler error pointing here? Perhaps the object is readonly or - // doesn't have an object id? Such objects cannot be updated. - // - object_traits::update (*this, obj); + return erase_<T, id_default> (id); } template <typename T> inline void database:: - update_ (const typename object_traits<T>::pointer_type& pobj) + erase (T& obj) { - // T can be const T while object_type will always be T. - // - typedef typename odb::object_traits<T>::object_type object_type; - typedef odb::object_traits<object_type> object_traits; - - typedef typename odb::object_traits<T>::pointer_type pointer_type; - typedef odb::pointer_traits<pointer_type> pointer_traits; - - T& obj (pointer_traits::get_ref (pobj)); - - // Compiler error pointing here? Perhaps the object is readonly or - // doesn't have an object id? Such objects cannot be updated. - // - object_traits::update (*this, obj); + return erase_<T, id_default> (obj); } template <typename T> @@ -285,7 +297,7 @@ namespace odb // const object_pointer& pobj (p); - erase_<T> (pobj); + erase_<T, id_default> (pobj); } template <typename T, template <typename> class P> @@ -300,7 +312,7 @@ namespace odb // const object_pointer& pobj (p); - erase_<T> (pobj); + erase_<T, id_default> (pobj); } template <typename T, typename A1, template <typename, typename> class P> @@ -315,7 +327,7 @@ namespace odb // const object_pointer& pobj (p); - erase_<T> (pobj); + erase_<T, id_default> (pobj); } template <typename T, template <typename> class P> @@ -338,37 +350,7 @@ namespace odb inline void database:: erase (const typename object_traits<T>::pointer_type& pobj) { - erase_<T> (pobj); - } - - template <typename T> - inline void database:: - erase_ (const typename object_traits<T>::pointer_type& pobj) - { - typedef typename object_traits<T>::pointer_type pointer_type; - typedef pointer_traits<pointer_type> pointer_traits; - - erase<T> (pointer_traits::get_ref (pobj)); - } - - template <typename T> - inline void database:: - erase (const typename object_traits<T>::id_type& id) - { - // T is always object_type. - // - object_traits<T>::erase (*this, id); - } - - template <typename T> - inline void database:: - erase (T& obj) - { - // T can be const T while object_type will always be T. - // - typedef typename object_traits<T>::object_type object_type; - - object_traits<object_type>::erase (*this, obj); + erase_<T, id_default> (pobj); } template <typename T> @@ -404,7 +386,7 @@ namespace odb { // T is always object_type. // - return object_traits<T>::erase_query (*this, q); + return object_traits_impl<T, id_default>::erase_query (*this, q); } template <typename T> @@ -428,6 +410,92 @@ namespace odb return query<T> (odb::query<T> (q), cache); } + // Implementations (i.e., the *_() functions). + // + template <typename T, database_id DB> + inline typename object_traits<T>::pointer_type database:: + find_ (const typename object_traits<T>::id_type& id) + { + // T is always object_type. + // + + // Compiler error pointing here? Perhaps the object doesn't have the + // default constructor? + // + return object_traits_impl<T, DB>::find (*this, id); + } + + template <typename T, database_id DB> + inline bool database:: + find_ (const typename object_traits<T>::id_type& id, T& obj) + { + // T is always object_type. + // + return object_traits_impl<T, DB>::find (*this, id, obj); + } + + template <typename T, database_id DB> + inline void database:: + update_ (T& obj) + { + // T can be const T while object_type will always be T. + // + typedef typename object_traits<T>::object_type object_type; + + // Compiler error pointing here? Perhaps the object is readonly or + // doesn't have an object id? Such objects cannot be updated. + // + object_traits_impl<object_type, DB>::update (*this, obj); + } + + template <typename T, database_id DB> + inline void database:: + update_ (const typename object_traits<T>::pointer_type& pobj) + { + // T can be const T while object_type will always be T. + // + typedef typename object_traits<T>::object_type object_type; + typedef typename object_traits<T>::pointer_type pointer_type; + + T& obj (pointer_traits<pointer_type>::get_ref (pobj)); + + // Compiler error pointing here? Perhaps the object is readonly or + // doesn't have an object id? Such objects cannot be updated. + // + object_traits_impl<object_type, DB>::update (*this, obj); + } + + template <typename T, database_id DB> + inline void database:: + erase_ (const typename object_traits<T>::id_type& id) + { + // T is always object_type. + // + object_traits_impl<T, DB>::erase (*this, id); + } + + template <typename T, database_id DB> + inline void database:: + erase_ (T& obj) + { + // T can be const T while object_type will always be T. + // + typedef typename object_traits<T>::object_type object_type; + + object_traits_impl<object_type, DB>::erase (*this, obj); + } + + template <typename T, database_id DB> + inline void database:: + erase_ (const typename object_traits<T>::pointer_type& pobj) + { + typedef typename object_traits<T>::pointer_type pointer_type; + + erase_<T, DB> (pointer_traits<pointer_type>::get_ref (pobj)); + } + + // execute() + // inline unsigned long long database:: execute (const char* statement) { diff --git a/odb/database.txx b/odb/database.txx index 7ac19d7..23ea712 100644 --- a/odb/database.txx +++ b/odb/database.txx @@ -10,13 +10,30 @@ namespace odb { template <typename T> + result<T> database:: + query (const odb::query<T>& q, bool cache) + { + // T is always object_type. We also don't need to check for transaction + // here; object_traits::query () does this. + // + result<T> r (query_<T, id_default>::call (*this, q)); + + if (cache) + r.cache (); + + return r; + } + + // Implementations (i.e., the *_() functions). + // + template <typename T, database_id DB> typename object_traits<T>::id_type database:: - persist (T& obj) + persist_ (T& obj) { // T can be const T while object_type will always be T. // - typedef typename odb::object_traits<T>::object_type object_type; - typedef odb::object_traits<object_type> object_traits; + typedef typename object_traits<T>::object_type object_type; + typedef object_traits_impl<object_type, DB> object_traits; object_traits::persist (*this, obj); @@ -26,19 +43,18 @@ namespace odb return object_traits::id (obj); } - template <typename T> + template <typename T, database_id DB> typename object_traits<T>::id_type database:: persist_ (const typename object_traits<T>::pointer_type& pobj) { // T can be const T while object_type will always be T. // - typedef typename odb::object_traits<T>::object_type object_type; - typedef odb::object_traits<object_type> object_traits; + typedef typename object_traits<T>::object_type object_type; + typedef typename object_traits<T>::pointer_type pointer_type; - typedef typename odb::object_traits<T>::pointer_type pointer_type; - typedef odb::pointer_traits<pointer_type> pointer_traits; + typedef object_traits_impl<object_type, DB> object_traits; - T& obj (pointer_traits::get_ref (pobj)); + T& obj (pointer_traits<pointer_type>::get_ref (pobj)); object_traits::persist (*this, obj); // Get the canonical object pointer and insert it into object cache. @@ -49,81 +65,60 @@ namespace odb return object_traits::id (obj); } - template <typename T> + template <typename T, database_id DB> typename object_traits<T>::pointer_type database:: - load (const typename object_traits<T>::id_type& id) + load_ (const typename object_traits<T>::id_type& id) { // T is always object_type. // typedef typename object_traits<T>::pointer_type pointer_type; - typedef odb::pointer_traits<pointer_type> pointer_traits; - pointer_type r (find<T> (id)); + pointer_type r (find_<T, DB> (id)); - if (pointer_traits::null_ptr (r)) + if (pointer_traits<pointer_type>::null_ptr (r)) throw object_not_persistent (); return r; } - template <typename T> + template <typename T, database_id DB> void database:: - load (const typename object_traits<T>::id_type& id, T& obj) + load_ (const typename object_traits<T>::id_type& id, T& obj) { - if (!find<T> (id, obj)) + if (!find_<T, DB> (id, obj)) throw object_not_persistent (); } - template <typename T> + template <typename T, database_id DB> void database:: - reload (T& obj) + reload_ (T& obj) { - // T should be object_type (cannot be const). + // T should be object_type (cannot be const). We also don't need to + // check for transaction here; object_traits::reload () does this. // - typedef odb::object_traits<T> object_traits; - - // We don't need to check for transaction here; - // object_traits::reload () does this. - - if (!object_traits::reload (*this, obj)) + if (!object_traits_impl<T, DB>::reload (*this, obj)) throw object_not_persistent (); } - template <typename T> - struct database::query_<T, class_object> + template <typename T, database_id DB> + struct database::query_<T, DB, class_object> { + template <typename Q> static result<T> - call (database& db, const odb::query<T>& q) + call (database& db, const Q& q) { - return object_traits<T>::query (db, q); + return object_traits_impl<T, DB>::query (db, q); } }; - template <typename T> - struct database::query_<T, class_view> + template <typename T, database_id DB> + struct database::query_<T, DB, class_view> { + template <typename Q> static result<T> - call (database& db, const odb::query<T>& q) + call (database& db, const Q& q) { - return view_traits<T>::query (db, q); + return view_traits_impl<T, DB>::query (db, q); } }; - - template <typename T> - result<T> database:: - query (const odb::query<T>& q, bool cache) - { - // T is always object_type. - // - - // We don't need to check for transaction here; - // object_traits::query () does this. - - result<T> r (query_<T, class_traits<T>::kind>::call (*this, q)); - - if (cache) - r.cache (); - - return r; - } } diff --git a/odb/forward.hxx b/odb/forward.hxx index 4c5e4b9..ff4a531 100644 --- a/odb/forward.hxx +++ b/odb/forward.hxx @@ -7,6 +7,8 @@ #include <odb/pre.hxx> +#include <cstddef> // std::size_t + #include <odb/details/export.hxx> #include <odb/details/shared-ptr-fwd.hxx> @@ -42,25 +44,50 @@ namespace odb // Implementation details. // + // Keep real databases first since their enumerators are used as array + // indexes + // + enum database_id + { + id_mysql, + id_sqlite, + id_pgsql, + id_oracle, + id_mssql, + id_default + }; + + // Number of real databases in the database_id enum. + // + const std::size_t database_count = id_default; + + // Traits. + // class access { public: template <typename T> class object_traits; + template <typename T, database_id DB> + class object_traits_impl; + template <typename T, typename P> class object_factory; template <typename T> class view_traits; + template <typename T, database_id DB> + class view_traits_impl; + template <typename T, typename P> class view_factory; template <typename T, typename P> class pointer_factory; - template <typename T> + template <typename T, database_id DB> class composite_value_traits; template <typename C> @@ -70,9 +97,15 @@ namespace odb template <typename T> struct object_traits; + template <typename T, database_id DB> + struct object_traits_impl; + template <typename T> struct view_traits; + template <typename T, database_id DB> + struct view_traits_impl; + // Cache traits. // template <typename T> struct no_id_pointer_cache_traits; diff --git a/odb/polymorphic-info.hxx b/odb/polymorphic-info.hxx index abed648..54291ce 100644 --- a/odb/polymorphic-info.hxx +++ b/odb/polymorphic-info.hxx @@ -86,14 +86,12 @@ namespace odb // Register concrete type T in the root's map. // - template <typename T> + template <typename T, database_id DB> struct polymorphic_entry { typedef T object_type; - typedef odb::object_traits<object_type> object_traits; - + typedef object_traits_impl<object_type, DB> object_traits; typedef typename object_traits::root_type root_type; - typedef odb::object_traits<root_type> root_traits; polymorphic_entry (); ~polymorphic_entry (); diff --git a/odb/polymorphic-map.hxx b/odb/polymorphic-map.hxx index c3c1374..5d23e6f 100644 --- a/odb/polymorphic-map.hxx +++ b/odb/polymorphic-map.hxx @@ -66,11 +66,11 @@ namespace odb discriminator_map discriminator_map_; }; - template <typename R> + template <typename R, database_id DB> struct polymorphic_entry_impl { typedef R root_type; - typedef object_traits<root_type> root_traits; + typedef object_traits_impl<root_type, DB> root_traits; typedef polymorphic_concrete_info<root_type> info_type; static void @@ -103,18 +103,18 @@ namespace odb return r; } - template <typename T, typename R> + template <typename T, database_id DB, typename R> struct dispatch_load { static void call (database& db, T& obj, std::size_t d) { - object_traits<T>::load_ (db, obj, d); + object_traits_impl<T, DB>::load_ (db, obj, d); } }; - template <typename R> - struct dispatch_load<R, R> + template <typename R, database_id DB> + struct dispatch_load<R, DB, R> { static void call (database&, R&, std::size_t) @@ -123,7 +123,7 @@ namespace odb } }; - template <typename T, bool auto_id> + template <typename T, database_id DB, bool auto_id> struct dispatch_persist { static void @@ -131,23 +131,24 @@ namespace odb { // Top-level call, no dynamic type checking. // - object_traits<T>::persist (db, obj, true, false); + object_traits_impl<T, DB>::persist (db, obj, true, false); } }; - template <typename T> - struct dispatch_persist<T, true> + template <typename T, database_id DB> + struct dispatch_persist<T, DB, true> { static void call (database& db, const T& obj) { // Top-level call, no dynamic type checking. // - object_traits<T>::persist (db, const_cast<T&> (obj), true, false); + object_traits_impl<T, DB>::persist ( + db, const_cast<T&> (obj), true, false); } }; - template <typename T> + template <typename T, database_id DB> bool dispatch_impl ( typename polymorphic_concrete_info< typename object_traits<T>::root_type>::call_type c, @@ -155,9 +156,9 @@ namespace odb const typename object_traits<T>::root_type* pobj, const void* arg) { - typedef object_traits<T> derived_traits; + typedef object_traits_impl<T, DB> derived_traits; typedef typename derived_traits::root_type root_type; - typedef object_traits<root_type> root_traits; + typedef object_traits_impl<root_type, DB> root_traits; typedef typename root_traits::id_type id_type; typedef polymorphic_concrete_info<root_type> info_type; @@ -175,7 +176,7 @@ namespace odb } case info_type::call_persist: { - dispatch_persist<T, root_traits::auto_id>::call ( + dispatch_persist<T, DB, root_traits::auto_id>::call ( db, *static_cast<const T*> (pobj)); break; @@ -208,7 +209,7 @@ namespace odb } case info_type::call_load: { - dispatch_load<T, root_type>::call ( + dispatch_load<T, DB, root_type>::call ( db, *const_cast<T*> (static_cast<const T*> (pobj)), *static_cast<const std::size_t*> (arg)); diff --git a/odb/polymorphic-map.ixx b/odb/polymorphic-map.ixx index 4dbd174..546d997 100644 --- a/odb/polymorphic-map.ixx +++ b/odb/polymorphic-map.ixx @@ -4,17 +4,17 @@ namespace odb { - template <typename T> - inline polymorphic_entry<T>:: + template <typename T, database_id DB> + inline polymorphic_entry<T, DB>:: polymorphic_entry () { - polymorphic_entry_impl<root_type>::insert (object_traits::info); + polymorphic_entry_impl<root_type, DB>::insert (object_traits::info); } - template <typename T> - inline polymorphic_entry<T>:: + template <typename T, database_id DB> + inline polymorphic_entry<T, DB>:: ~polymorphic_entry () { - polymorphic_entry_impl<root_type>::erase (object_traits::info); + polymorphic_entry_impl<root_type, DB>::erase (object_traits::info); } } diff --git a/odb/polymorphic-map.txx b/odb/polymorphic-map.txx index d7b6e36..26534a6 100644 --- a/odb/polymorphic-map.txx +++ b/odb/polymorphic-map.txx @@ -39,8 +39,8 @@ namespace odb // polymorphic_entry_impl // - template <typename R> - void polymorphic_entry_impl<R>:: + template <typename R, database_id DB> + void polymorphic_entry_impl<R, DB>:: insert (const info_type& i) { // VC10 cannot grok constructor call syntax here. @@ -56,8 +56,8 @@ namespace odb pm->discriminator_map_[&i.discriminator] = &i; } - template <typename R> - void polymorphic_entry_impl<R>:: + template <typename R, database_id DB> + void polymorphic_entry_impl<R, DB>:: erase (const info_type& i) { // VC10 cannot grok constructor call syntax here. diff --git a/odb/query.hxx b/odb/query.hxx index 9f889db..d5d0a19 100644 --- a/odb/query.hxx +++ b/odb/query.hxx @@ -7,6 +7,7 @@ #include <odb/pre.hxx> +#include <odb/forward.hxx> #include <odb/traits.hxx> namespace odb @@ -21,16 +22,16 @@ namespace odb // we need straight tables instead of aliases. // // - template <typename T, typename Tag, bool dummy = true> + template <typename T, database_id DB, typename Tag, bool dummy = true> struct alias_traits; - template <typename T> + template <typename T, database_id DB> struct query_columns_base; - template <typename T, typename Alias> + template <typename T, database_id DB, typename Alias> struct query_columns; - template <typename T, typename Alias> + template <typename T, database_id DB, typename Alias> struct pointer_query_columns; // Object pointer syntax wrapper. @@ -56,29 +57,33 @@ namespace odb // we have to use the impl trick below instead of simply having kind // as a second template argument with a default value. // - template <typename T, class_kind kind> + template <typename T, database_id DB, class_kind kind> struct query_selector_impl; - template <typename T> - struct query_selector_impl<T, class_object> + template <typename T, database_id DB> + struct query_selector_impl<T, DB, class_object> { - typedef typename object_traits<T>::query_base_type base_type; - typedef query_columns<T, access::object_traits<T> > columns_type; + typedef typename object_traits_impl<T, DB>::query_base_type base_type; + + typedef + query_columns<T, DB, access::object_traits_impl<T, DB> > + columns_type; }; - template <typename T> - struct query_selector_impl<T, class_view> + template <typename T, database_id DB> + struct query_selector_impl<T, DB, class_view> { - typedef typename view_traits<T>::query_base_type base_type; - typedef typename view_traits<T>::query_columns columns_type; + typedef typename view_traits_impl<T, DB>::query_base_type base_type; + typedef typename view_traits_impl<T, DB>::query_columns columns_type; }; - template <typename T> - struct query_selector: query_selector_impl<T, class_traits<T>::kind> + template <typename T, database_id DB> + struct query_selector: query_selector_impl<T, DB, class_traits<T>::kind> { }; - template <typename T, typename Q = typename query_selector<T>::base_type> + template <typename T, + typename B = typename query_selector<T, id_default>::base_type> class query; namespace core diff --git a/odb/schema-catalog-impl.hxx b/odb/schema-catalog-impl.hxx index 71d5d89..9b94cf1 100644 --- a/odb/schema-catalog-impl.hxx +++ b/odb/schema-catalog-impl.hxx @@ -35,8 +35,9 @@ namespace odb struct LIBODB_EXPORT schema_catalog_entry { schema_catalog_entry ( + database_id id, const char* name, - bool (*entry) (database&, unsigned short pass, bool drop)); + bool (*create_function) (database&, unsigned short pass, bool drop)); }; } diff --git a/odb/schema-catalog.cxx b/odb/schema-catalog.cxx index 7f00c3c..cd1ded4 100644 --- a/odb/schema-catalog.cxx +++ b/odb/schema-catalog.cxx @@ -5,6 +5,7 @@ #include <map> #include <vector> +#include <odb/database.hxx> #include <odb/exceptions.hxx> #include <odb/schema-catalog.hxx> #include <odb/schema-catalog-impl.hxx> @@ -19,8 +20,9 @@ namespace odb // for example, for foreign key generation. // typedef bool (*create_function) (database&, unsigned short pass, bool drop); + typedef pair<database_id, string> key; typedef vector<create_function> create_functions; - struct schema_catalog_impl: map<string, create_functions> {}; + struct schema_catalog_impl: map<key, create_functions> {}; schema_catalog_impl* schema_catalog_init::catalog = 0; size_t schema_catalog_init::count = 0; @@ -29,8 +31,7 @@ namespace odb create_schema (database& db, const string& name) { const schema_catalog_impl& c (*schema_catalog_init::catalog); - - schema_catalog_impl::const_iterator i (c.find (name)); + schema_catalog_impl::const_iterator i (c.find (key (db.id (), name))); if (i == c.end ()) throw unknown_schema (name); @@ -94,9 +95,9 @@ namespace odb // schema_catalog_entry // schema_catalog_entry:: - schema_catalog_entry (const char* name, create_function entry) + schema_catalog_entry (database_id id, const char* name, create_function cf) { schema_catalog_impl& c (*schema_catalog_init::catalog); - c[name].push_back (entry); + c[key(id, name)].push_back (cf); } } diff --git a/odb/traits.hxx b/odb/traits.hxx index 0743dba..3711601 100644 --- a/odb/traits.hxx +++ b/odb/traits.hxx @@ -99,17 +99,16 @@ namespace odb // template <typename T> + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a persistent + // object. Or you forgot to include the corresponding -odb.hxx file. + // struct object_traits: access::object_traits<T>, access::object_factory<T, typename access::object_traits<T>::pointer_type> { - // - // If a C++ compiler issues an error pointing to this struct and - // saying that it is incomplete, then you are most likely trying to - // perform a database operation on a C++ type that is not a persistent - // object. Or you forgot to include the corresponding -odb.hxx file. - // - typedef odb::pointer_traits<typename access::object_traits<T>::pointer_type> pointer_traits; @@ -160,45 +159,64 @@ namespace odb }; template <typename T, template <typename> class P> - struct object_traits< P<T> > + struct object_traits<P<T> > { struct id_type {}; }; template <typename T, typename A1, template <typename, typename> class P> - struct object_traits< P<T, A1> > + struct object_traits<P<T, A1> > { struct id_type {}; }; template <typename T, template <typename> class P> - struct object_traits< const P<T> > + struct object_traits<const P<T> > { struct id_type {}; }; template <typename T, typename A1, template <typename, typename> class P> - struct object_traits< const P<T, A1> > + struct object_traits<const P<T, A1> > { struct id_type {}; }; + template <typename T, database_id DB> + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a persistent + // object. Or you forgot to include the corresponding -odb.hxx file. + // + struct object_traits_impl: + access::object_traits_impl<T, DB>, + access::object_factory<T, typename access::object_traits<T>::pointer_type> + { + typedef + odb::pointer_traits<typename access::object_traits<T>::pointer_type> + pointer_traits; + + typedef typename access::object_traits<T>::object_type object_type; + typedef typename access::object_traits<T>::pointer_type pointer_type; + typedef typename pointer_traits::const_pointer_type const_pointer_type; + }; + // // view_traits // template <typename T> + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a view + // Or you forgot to include the corresponding -odb.hxx file. + // struct view_traits: access::view_traits<T>, access::view_factory<T, typename access::view_traits<T>::pointer_type> { - // - // If a C++ compiler issues an error pointing to this struct and - // saying that it is incomplete, then you are most likely trying to - // perform a database operation on a C++ type that is not a view - // Or you forgot to include the corresponding -odb.hxx file. - // - typedef odb::pointer_traits<typename access::view_traits<T>::pointer_type> pointer_traits; @@ -227,12 +245,31 @@ namespace odb typedef const_pointer_type pointer_type; }; + template <typename T, database_id DB> + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a view + // Or you forgot to include the corresponding -odb.hxx file. + // + struct view_traits_impl: + access::view_traits_impl<T, DB>, + access::view_factory<T, typename access::view_traits<T>::pointer_type> + { + typedef + odb::pointer_traits<typename access::view_traits<T>::pointer_type> + pointer_traits; + + typedef typename access::view_traits<T>::view_type view_type; + typedef typename access::view_traits<T>::pointer_type pointer_type; + }; + // // composite_value_traits // - template <typename T> - struct composite_value_traits: access::composite_value_traits<T> + template <typename T, database_id DB> + struct composite_value_traits: access::composite_value_traits<T, DB> { }; } |