container-statements.hxx | container-statements.hxx | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#ifndef ODB_PGSQL_CONTAINER_STATEMENTS_HXX | #ifndef ODB_PGSQL_CONTAINER_STATEMENTS_HXX | |||
#define ODB_PGSQL_CONTAINER_STATEMENTS_HXX | #define ODB_PGSQL_CONTAINER_STATEMENTS_HXX | |||
#include <odb/pre.hxx> | #include <odb/pre.hxx> | |||
#include <cstddef> // std::size_t | #include <cstddef> // std::size_t | |||
#include <odb/forward.hxx> | #include <odb/forward.hxx> | |||
#include <odb/schema-version.hxx> | ||||
#include <odb/traits.hxx> | #include <odb/traits.hxx> | |||
#include <odb/pgsql/version.hxx> | #include <odb/pgsql/version.hxx> | |||
#include <odb/pgsql/binding.hxx> | #include <odb/pgsql/binding.hxx> | |||
#include <odb/pgsql/statement.hxx> | #include <odb/pgsql/statement.hxx> | |||
#include <odb/pgsql/pgsql-fwd.hxx> // Oid | #include <odb/pgsql/pgsql-fwd.hxx> // Oid | |||
#include <odb/pgsql/details/export.hxx> | #include <odb/pgsql/details/export.hxx> | |||
namespace odb | namespace odb | |||
{ | { | |||
skipping to change at line 64 | skipping to change at line 65 | |||
} | } | |||
// Functions. | // Functions. | |||
// | // | |||
functions_type& | functions_type& | |||
functions () | functions () | |||
{ | { | |||
return functions_; | return functions_; | |||
} | } | |||
// Schema version. | ||||
// | ||||
const schema_version_migration& | ||||
version_migration () const {return *svm_;} | ||||
void | ||||
version_migration (const schema_version_migration& svm) {svm_ = &svm; | ||||
} | ||||
// Id image binding (external). | // Id image binding (external). | |||
// | // | |||
const binding& | const binding& | |||
id_binding () | id_binding () | |||
{ | { | |||
return id_binding_; | return id_binding_; | |||
} | } | |||
// Data image. The image is split into the id (that comes as a | // Data image. The image is split into the id (that comes as a | |||
// binding) and index/key plus value which are in data_image_type. | // binding) and index/key plus value which are in data_image_type. | |||
skipping to change at line 124 | skipping to change at line 133 | |||
insert_statement_type& | insert_statement_type& | |||
insert_statement () | insert_statement () | |||
{ | { | |||
if (insert_ == 0) | if (insert_ == 0) | |||
insert_.reset ( | insert_.reset ( | |||
new (details::shared) insert_statement_type ( | new (details::shared) insert_statement_type ( | |||
conn_, | conn_, | |||
insert_name_, | insert_name_, | |||
insert_text_, | insert_text_, | |||
versioned_, // Process if versioned. | ||||
insert_types_, | insert_types_, | |||
insert_count_, | insert_count_, | |||
insert_image_binding_, | insert_image_binding_, | |||
insert_image_native_binding_, | insert_image_native_binding_, | |||
false, | false, | |||
false)); | false)); | |||
return *insert_; | return *insert_; | |||
} | } | |||
select_statement_type& | select_statement_type& | |||
select_statement () | select_statement () | |||
{ | { | |||
if (select_ == 0) | if (select_ == 0) | |||
select_.reset ( | select_.reset ( | |||
new (details::shared) select_statement_type ( | new (details::shared) select_statement_type ( | |||
conn_, | conn_, | |||
select_name_, | select_name_, | |||
select_text_, | select_text_, | |||
versioned_, // Process if versioned. | ||||
false, // Don't optimize. | ||||
id_types_, | id_types_, | |||
id_binding_.count, | id_binding_.count, | |||
id_binding_, | id_binding_, | |||
id_native_binding_, | id_native_binding_, | |||
select_image_binding_, | select_image_binding_, | |||
false)); | false)); | |||
return *select_; | return *select_; | |||
} | } | |||
skipping to change at line 204 | skipping to change at line 216 | |||
const char* insert_text_; | const char* insert_text_; | |||
const Oid* insert_types_; | const Oid* insert_types_; | |||
std::size_t insert_count_; | std::size_t insert_count_; | |||
const char* select_name_; | const char* select_name_; | |||
const char* select_text_; | const char* select_text_; | |||
const char* delete_name_; | const char* delete_name_; | |||
const char* delete_text_; | const char* delete_text_; | |||
bool versioned_; | ||||
const schema_version_migration* svm_; | ||||
details::shared_ptr<insert_statement_type> insert_; | details::shared_ptr<insert_statement_type> insert_; | |||
details::shared_ptr<select_statement_type> select_; | details::shared_ptr<select_statement_type> select_; | |||
details::shared_ptr<delete_statement_type> delete_; | details::shared_ptr<delete_statement_type> delete_; | |||
}; | }; | |||
template <typename T> | template <typename T> | |||
class smart_container_statements: public container_statements<T> | class smart_container_statements: public container_statements<T> | |||
{ | { | |||
public: | public: | |||
typedef T traits; | typedef T traits; | |||
skipping to change at line 316 | skipping to change at line 331 | |||
update_statement_type& | update_statement_type& | |||
update_statement () | update_statement () | |||
{ | { | |||
if (update_ == 0) | if (update_ == 0) | |||
update_.reset ( | update_.reset ( | |||
new (details::shared) update_statement_type ( | new (details::shared) update_statement_type ( | |||
this->conn_, | this->conn_, | |||
update_name_, | update_name_, | |||
update_text_, | update_text_, | |||
this->versioned_, // Process if versioned. | ||||
update_types_, | update_types_, | |||
update_count_, | update_count_, | |||
update_image_binding_, | update_image_binding_, | |||
update_image_native_binding_, | update_image_native_binding_, | |||
false)); | false)); | |||
return *update_; | return *update_; | |||
} | } | |||
protected: | protected: | |||
End of changes. 6 change blocks. | ||||
0 lines changed or deleted | 17 lines changed or added | |||
container-statements.txx | container-statements.txx | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
binding& id, | binding& id, | |||
native_binding& idn, | native_binding& idn, | |||
const Oid* idt) | const Oid* idt) | |||
: conn_ (conn), | : conn_ (conn), | |||
id_binding_ (id), | id_binding_ (id), | |||
id_native_binding_ (idn), | id_native_binding_ (idn), | |||
id_types_ (idt), | id_types_ (idt), | |||
functions_ (this), | functions_ (this), | |||
insert_image_binding_ (0, 0), // Initialized by impl . | insert_image_binding_ (0, 0), // Initialized by impl . | |||
insert_image_native_binding_ (0, 0, 0, 0), // Initialized by impl . | insert_image_native_binding_ (0, 0, 0, 0), // Initialized by impl . | |||
select_image_binding_ (0, 0) // Initialized by impl | select_image_binding_ (0, 0), // Initialized by impl | |||
. | . | |||
svm_ (0) | ||||
{ | { | |||
functions_.insert_ = &traits::insert; | functions_.insert_ = &traits::insert; | |||
functions_.select_ = &traits::select; | functions_.select_ = &traits::select; | |||
functions_.delete__ = &traits::delete_; | functions_.delete__ = &traits::delete_; | |||
data_image_.version = 0; | data_image_.version = 0; | |||
data_image_version_ = 0; | data_image_version_ = 0; | |||
data_id_binding_version_ = 0; | data_id_binding_version_ = 0; | |||
} | } | |||
skipping to change at line 109 | skipping to change at line 110 | |||
this->insert_name_ = traits::insert_name; | this->insert_name_ = traits::insert_name; | |||
this->insert_text_ = traits::insert_statement; | this->insert_text_ = traits::insert_statement; | |||
this->insert_types_ = traits::insert_types; | this->insert_types_ = traits::insert_types; | |||
this->insert_count_ = traits::data_column_count; | this->insert_count_ = traits::data_column_count; | |||
this->select_name_ = traits::select_name; | this->select_name_ = traits::select_name; | |||
this->select_text_ = traits::select_statement; | this->select_text_ = traits::select_statement; | |||
this->delete_name_ = traits::delete_name; | this->delete_name_ = traits::delete_name; | |||
this->delete_text_ = traits::delete_statement; | this->delete_text_ = traits::delete_statement; | |||
this->versioned_ = traits::versioned; | ||||
} | } | |||
// smart_container_statements_impl | // smart_container_statements_impl | |||
// | // | |||
template <typename T> | template <typename T> | |||
smart_container_statements_impl<T>:: | smart_container_statements_impl<T>:: | |||
smart_container_statements_impl (connection_type& conn, | smart_container_statements_impl (connection_type& conn, | |||
binding& id, | binding& id, | |||
native_binding& idn, | native_binding& idn, | |||
const Oid* idt) | const Oid* idt) | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 5 lines changed or added | |||
database.hxx | database.hxx | |||
---|---|---|---|---|
skipping to change at line 128 | skipping to change at line 128 | |||
// Load an object. Throw object_not_persistent if not found. | // Load an object. Throw object_not_persistent if not found. | |||
// | // | |||
template <typename T> | template <typename T> | |||
typename object_traits<T>::pointer_type | typename object_traits<T>::pointer_type | |||
load (const typename object_traits<T>::id_type& id); | load (const typename object_traits<T>::id_type& id); | |||
template <typename T> | template <typename T> | |||
void | void | |||
load (const typename object_traits<T>::id_type& id, T& object); | load (const typename object_traits<T>::id_type& id, T& object); | |||
// Load (or reload, if it is already loaded) a section of an object. | ||||
// | ||||
template <typename T> | ||||
void | ||||
load (T& object, section&); | ||||
// Reload an object. | // Reload an object. | |||
// | // | |||
template <typename T> | template <typename T> | |||
void | void | |||
reload (T& object); | reload (T& object); | |||
template <typename T> | template <typename T> | |||
void | void | |||
reload (T* obj_ptr); | reload (T* obj_ptr); | |||
skipping to change at line 198 | skipping to change at line 204 | |||
update (P<T>& obj_ptr); | update (P<T>& obj_ptr); | |||
template <typename T, typename A1, template <typename, typename> clas s P> | template <typename T, typename A1, template <typename, typename> clas s P> | |||
void | void | |||
update (P<T, A1>& obj_ptr); | update (P<T, A1>& obj_ptr); | |||
template <typename T> | template <typename T> | |||
void | void | |||
update (const typename object_traits<T>::pointer_type& obj_ptr); | update (const typename object_traits<T>::pointer_type& obj_ptr); | |||
// Update a section of an object. Throws the section_not_loaded | ||||
// exception if the section is not loaded. Note also that this | ||||
// function does not clear the changed flag if it is set. | ||||
// | ||||
template <typename T> | ||||
void | ||||
update (const T& object, const section&); | ||||
// Make the object transient. Throw object_not_persistent if not | // Make the object transient. Throw object_not_persistent if not | |||
// found. | // found. | |||
// | // | |||
template <typename T> | template <typename T> | |||
void | void | |||
erase (const typename object_traits<T>::id_type& id); | erase (const typename object_traits<T>::id_type& id); | |||
template <typename T> | template <typename T> | |||
void | void | |||
erase (T& object); | erase (T& object); | |||
skipping to change at line 305 | skipping to change at line 319 | |||
// Transactions. | // Transactions. | |||
// | // | |||
public: | public: | |||
virtual transaction_impl* | virtual transaction_impl* | |||
begin (); | begin (); | |||
public: | public: | |||
connection_ptr | connection_ptr | |||
connection (); | connection (); | |||
// Database schema version. | ||||
// | ||||
protected: | ||||
virtual const schema_version_info& | ||||
load_schema_version (const std::string& schema_name) const; | ||||
public: | public: | |||
// Database id constant (useful for meta-programming). | // Database id constant (useful for meta-programming). | |||
// | // | |||
static const odb::database_id database_id = id_pgsql; | static const odb::database_id database_id = id_pgsql; | |||
public: | public: | |||
virtual | virtual | |||
~database (); | ~database (); | |||
protected: | protected: | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 20 lines changed or added | |||
database.ixx | database.ixx | |||
---|---|---|---|---|
skipping to change at line 111 | skipping to change at line 111 | |||
} | } | |||
template <typename T> | template <typename T> | |||
inline void database:: | inline void database:: | |||
load (const typename object_traits<T>::id_type& id, T& obj) | load (const typename object_traits<T>::id_type& id, T& obj) | |||
{ | { | |||
return load_<T, id_pgsql> (id, obj); | return load_<T, id_pgsql> (id, obj); | |||
} | } | |||
template <typename T> | template <typename T> | |||
inline void database:: | ||||
load (T& obj, section& s) | ||||
{ | ||||
return load_<T, id_pgsql> (obj, s); | ||||
} | ||||
template <typename T> | ||||
inline typename object_traits<T>::pointer_type database:: | inline typename object_traits<T>::pointer_type database:: | |||
find (const typename object_traits<T>::id_type& id) | find (const typename object_traits<T>::id_type& id) | |||
{ | { | |||
return find_<T, id_pgsql> (id); | return find_<T, id_pgsql> (id); | |||
} | } | |||
template <typename T> | template <typename T> | |||
inline bool database:: | inline bool database:: | |||
find (const typename object_traits<T>::id_type& id, T& obj) | find (const typename object_traits<T>::id_type& id, T& obj) | |||
{ | { | |||
skipping to change at line 252 | skipping to change at line 259 | |||
template <typename T> | template <typename T> | |||
inline void database:: | inline void database:: | |||
update (const typename object_traits<T>::pointer_type& pobj) | update (const typename object_traits<T>::pointer_type& pobj) | |||
{ | { | |||
update_<T, id_pgsql> (pobj); | update_<T, id_pgsql> (pobj); | |||
} | } | |||
template <typename T> | template <typename T> | |||
inline void database:: | inline void database:: | |||
update (const T& obj, const section& s) | ||||
{ | ||||
update_<T, id_pgsql> (obj, s); | ||||
} | ||||
template <typename T> | ||||
inline void database:: | ||||
erase (const typename object_traits<T>::id_type& id) | erase (const typename object_traits<T>::id_type& id) | |||
{ | { | |||
return erase_<T, id_pgsql> (id); | return erase_<T, id_pgsql> (id); | |||
} | } | |||
template <typename T> | template <typename T> | |||
inline void database:: | inline void database:: | |||
erase (T& obj) | erase (T& obj) | |||
{ | { | |||
return erase_<T, id_pgsql> (obj); | return erase_<T, id_pgsql> (obj); | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 14 lines changed or added | |||
forward.hxx | forward.hxx | |||
---|---|---|---|---|
skipping to change at line 46 | skipping to change at line 46 | |||
using pgsql::transaction; | using pgsql::transaction; | |||
using pgsql::statement; | using pgsql::statement; | |||
} | } | |||
// Implementation details. | // Implementation details. | |||
// | // | |||
enum statement_kind | enum statement_kind | |||
{ | { | |||
statement_select, | statement_select, | |||
statement_insert, | statement_insert, | |||
statement_update | statement_update, | |||
statement_delete | ||||
}; | }; | |||
class binding; | class binding; | |||
class select_statement; | class select_statement; | |||
template <typename T> | template <typename T> | |||
class object_statements; | class object_statements; | |||
template <typename T> | template <typename T> | |||
class polymorphic_root_object_statements; | class polymorphic_root_object_statements; | |||
skipping to change at line 73 | skipping to change at line 74 | |||
template <typename T> | template <typename T> | |||
class view_statements; | class view_statements; | |||
template <typename T> | template <typename T> | |||
class container_statements; | class container_statements; | |||
template <typename T> | template <typename T> | |||
class smart_container_statements; | class smart_container_statements; | |||
template <typename T, typename ST> | ||||
class section_statements; | ||||
class query_base; | class query_base; | |||
} | } | |||
namespace details | namespace details | |||
{ | { | |||
template <> | template <> | |||
struct counter_type<pgsql::connection> | struct counter_type<pgsql::connection> | |||
{ | { | |||
typedef shared_base counter; | typedef shared_base counter; | |||
}; | }; | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 5 lines changed or added | |||
no-id-object-result.hxx | no-id-object-result.hxx | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#ifndef ODB_PGSQL_NO_ID_OBJECT_RESULT_HXX | #ifndef ODB_PGSQL_NO_ID_OBJECT_RESULT_HXX | |||
#define ODB_PGSQL_NO_ID_OBJECT_RESULT_HXX | #define ODB_PGSQL_NO_ID_OBJECT_RESULT_HXX | |||
#include <odb/pre.hxx> | #include <odb/pre.hxx> | |||
#include <cstddef> // std::size_t | #include <cstddef> // std::size_t | |||
#include <odb/schema-version.hxx> | ||||
#include <odb/no-id-object-result.hxx> | #include <odb/no-id-object-result.hxx> | |||
#include <odb/details/shared-ptr.hxx> | #include <odb/details/shared-ptr.hxx> | |||
#include <odb/pgsql/version.hxx> | #include <odb/pgsql/version.hxx> | |||
#include <odb/pgsql/forward.hxx> // query_base | #include <odb/pgsql/forward.hxx> // query_base | |||
#include <odb/pgsql/statement.hxx> | #include <odb/pgsql/statement.hxx> | |||
#include <odb/pgsql/traits-calls.hxx> | ||||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
template <typename T> | template <typename T> | |||
class no_id_object_result_impl: public odb::no_id_object_result_impl<T> | class no_id_object_result_impl: public odb::no_id_object_result_impl<T> | |||
{ | { | |||
public: | public: | |||
typedef odb::no_id_object_result_impl<T> base_type; | typedef odb::no_id_object_result_impl<T> base_type; | |||
skipping to change at line 43 | skipping to change at line 45 | |||
typedef object_traits_impl<object_type, id_pgsql> object_traits; | typedef object_traits_impl<object_type, id_pgsql> object_traits; | |||
typedef typename base_type::pointer_traits pointer_traits; | typedef typename base_type::pointer_traits pointer_traits; | |||
typedef typename object_traits::statements_type statements_type; | typedef typename object_traits::statements_type statements_type; | |||
virtual | virtual | |||
~no_id_object_result_impl (); | ~no_id_object_result_impl (); | |||
no_id_object_result_impl (const query_base&, | no_id_object_result_impl (const query_base&, | |||
details::shared_ptr<select_statement>, | details::shared_ptr<select_statement>, | |||
statements_type&); | statements_type&, | |||
const schema_version_migration*); | ||||
virtual void | virtual void | |||
load (object_type&); | load (object_type&); | |||
virtual void | virtual void | |||
next (); | next (); | |||
virtual void | virtual void | |||
cache (); | cache (); | |||
skipping to change at line 65 | skipping to change at line 68 | |||
size (); | size (); | |||
virtual void | virtual void | |||
invalidate (); | invalidate (); | |||
using base_type::current; | using base_type::current; | |||
private: | private: | |||
details::shared_ptr<select_statement> statement_; | details::shared_ptr<select_statement> statement_; | |||
statements_type& statements_; | statements_type& statements_; | |||
object_traits_calls<object_type> tc_; | ||||
std::size_t count_; | std::size_t count_; | |||
}; | }; | |||
} | } | |||
} | } | |||
#include <odb/pgsql/no-id-object-result.txx> | #include <odb/pgsql/no-id-object-result.txx> | |||
#include <odb/post.hxx> | #include <odb/post.hxx> | |||
#endif // ODB_PGSQL_NO_ID_OBJECT_RESULT_HXX | #endif // ODB_PGSQL_NO_ID_OBJECT_RESULT_HXX | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 5 lines changed or added | |||
no-id-object-result.txx | no-id-object-result.txx | |||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
this->end_ = true; | this->end_ = true; | |||
} | } | |||
statement_.reset (); | statement_.reset (); | |||
} | } | |||
template <typename T> | template <typename T> | |||
no_id_object_result_impl<T>:: | no_id_object_result_impl<T>:: | |||
no_id_object_result_impl (const query_base&, | no_id_object_result_impl (const query_base&, | |||
details::shared_ptr<select_statement> stateme nt, | details::shared_ptr<select_statement> stateme nt, | |||
statements_type& statements) | statements_type& statements, | |||
const schema_version_migration* svm) | ||||
: base_type (statements.connection ()), | : base_type (statements.connection ()), | |||
statement_ (statement), | statement_ (statement), | |||
statements_ (statements), | statements_ (statements), | |||
tc_ (svm), | ||||
count_ (0) | count_ (0) | |||
{ | { | |||
} | } | |||
template <typename T> | template <typename T> | |||
void no_id_object_result_impl<T>:: | void no_id_object_result_impl<T>:: | |||
load (object_type& obj) | load (object_type& obj) | |||
{ | { | |||
// The image can grow between calls to load() as a result of other | // The image can grow between calls to load() as a result of other | |||
// statements execution. | // statements execution. | |||
// | // | |||
typename object_traits::image_type& im (statements_.image ()); | typename object_traits::image_type& im (statements_.image ()); | |||
if (im.version != statements_.select_image_version ()) | if (im.version != statements_.select_image_version ()) | |||
{ | { | |||
binding& b (statements_.select_image_binding ()); | binding& b (statements_.select_image_binding ()); | |||
object_traits::bind (b.bind, im, statement_select); | tc_.bind (b.bind, im, statement_select); | |||
statements_.select_image_version (im.version); | statements_.select_image_version (im.version); | |||
b.version++; | b.version++; | |||
} | } | |||
select_statement::result r (statement_->load ()); | select_statement::result r (statement_->load ()); | |||
if (r == select_statement::truncated) | if (r == select_statement::truncated) | |||
{ | { | |||
if (object_traits::grow (im, statements_.select_image_truncated ()) ) | if (tc_.grow (im, statements_.select_image_truncated ())) | |||
im.version++; | im.version++; | |||
if (im.version != statements_.select_image_version ()) | if (im.version != statements_.select_image_version ()) | |||
{ | { | |||
binding& b (statements_.select_image_binding ()); | binding& b (statements_.select_image_binding ()); | |||
object_traits::bind (b.bind, im, statement_select); | tc_.bind (b.bind, im, statement_select); | |||
statements_.select_image_version (im.version); | statements_.select_image_version (im.version); | |||
b.version++; | b.version++; | |||
statement_->reload (); | statement_->reload (); | |||
} | } | |||
} | } | |||
object_traits::callback (this->db_, obj, callback_event::pre_load); | object_traits::callback (this->db_, obj, callback_event::pre_load); | |||
object_traits::init (obj, im, &this->db_); | tc_.init (obj, im, &this->db_); | |||
object_traits::callback (this->db_, obj, callback_event::post_load); | object_traits::callback (this->db_, obj, callback_event::post_load); | |||
} | } | |||
template <typename T> | template <typename T> | |||
void no_id_object_result_impl<T>:: | void no_id_object_result_impl<T>:: | |||
next () | next () | |||
{ | { | |||
this->current (pointer_type ()); | this->current (pointer_type ()); | |||
if (statement_->next ()) | if (statement_->next ()) | |||
End of changes. 6 change blocks. | ||||
5 lines changed or deleted | 7 lines changed or added | |||
no-id-object-statements.hxx | no-id-object-statements.hxx | |||
---|---|---|---|---|
skipping to change at line 90 | skipping to change at line 90 | |||
// | // | |||
insert_statement_type& | insert_statement_type& | |||
persist_statement () | persist_statement () | |||
{ | { | |||
if (persist_ == 0) | if (persist_ == 0) | |||
persist_.reset ( | persist_.reset ( | |||
new (details::shared) insert_statement_type ( | new (details::shared) insert_statement_type ( | |||
conn_, | conn_, | |||
object_traits::persist_statement_name, | object_traits::persist_statement_name, | |||
object_traits::persist_statement, | object_traits::persist_statement, | |||
object_traits::versioned, // Process if versioned. | ||||
object_traits::persist_statement_types, | object_traits::persist_statement_types, | |||
insert_column_count, | insert_column_count, | |||
insert_image_binding_, | insert_image_binding_, | |||
insert_image_native_binding_, | insert_image_native_binding_, | |||
false, | false, | |||
false)); | false)); | |||
return *persist_; | return *persist_; | |||
} | } | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
polymorphic-object-result.hxx | polymorphic-object-result.hxx | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#ifndef ODB_PGSQL_POLYMORPHIC_OBJECT_RESULT_HXX | #ifndef ODB_PGSQL_POLYMORPHIC_OBJECT_RESULT_HXX | |||
#define ODB_PGSQL_POLYMORPHIC_OBJECT_RESULT_HXX | #define ODB_PGSQL_POLYMORPHIC_OBJECT_RESULT_HXX | |||
#include <odb/pre.hxx> | #include <odb/pre.hxx> | |||
#include <cstddef> // std::size_t | #include <cstddef> // std::size_t | |||
#include <odb/schema-version.hxx> | ||||
#include <odb/polymorphic-object-result.hxx> | #include <odb/polymorphic-object-result.hxx> | |||
#include <odb/details/shared-ptr.hxx> | #include <odb/details/shared-ptr.hxx> | |||
#include <odb/pgsql/version.hxx> | #include <odb/pgsql/version.hxx> | |||
#include <odb/pgsql/forward.hxx> // query_base | #include <odb/pgsql/forward.hxx> // query_base | |||
#include <odb/pgsql/statement.hxx> | #include <odb/pgsql/statement.hxx> | |||
#include <odb/pgsql/traits-calls.hxx> | ||||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
template <typename T> | template <typename T> | |||
class polymorphic_object_result_impl: | class polymorphic_object_result_impl: | |||
public odb::polymorphic_object_result_impl<T> | public odb::polymorphic_object_result_impl<T> | |||
{ | { | |||
public: | public: | |||
skipping to change at line 50 | skipping to change at line 52 | |||
typedef object_traits_impl<root_type, id_pgsql> root_traits; | typedef object_traits_impl<root_type, id_pgsql> root_traits; | |||
typedef typename object_traits::statements_type statements_type; | typedef typename object_traits::statements_type statements_type; | |||
virtual | virtual | |||
~polymorphic_object_result_impl (); | ~polymorphic_object_result_impl (); | |||
polymorphic_object_result_impl (const query_base&, | polymorphic_object_result_impl (const query_base&, | |||
details::shared_ptr<select_statement> , | details::shared_ptr<select_statement> , | |||
statements_type&); | statements_type&, | |||
const schema_version_migration*); | ||||
virtual void | virtual void | |||
load (object_type*, bool fetch); | load (object_type*, bool fetch); | |||
virtual id_type | virtual id_type | |||
load_id (); | load_id (); | |||
virtual discriminator_type | virtual discriminator_type | |||
load_discriminator (); | load_discriminator (); | |||
skipping to change at line 82 | skipping to change at line 85 | |||
using base_type::current; | using base_type::current; | |||
private: | private: | |||
void | void | |||
load_image (); | load_image (); | |||
private: | private: | |||
details::shared_ptr<select_statement> statement_; | details::shared_ptr<select_statement> statement_; | |||
statements_type& statements_; | statements_type& statements_; | |||
object_traits_calls<object_type> tc_; | ||||
std::size_t count_; | std::size_t count_; | |||
}; | }; | |||
} | } | |||
} | } | |||
#include <odb/pgsql/polymorphic-object-result.txx> | #include <odb/pgsql/polymorphic-object-result.txx> | |||
#include <odb/post.hxx> | #include <odb/post.hxx> | |||
#endif // ODB_PGSQL_POLYMORPHIC_OBJECT_RESULT_HXX | #endif // ODB_PGSQL_POLYMORPHIC_OBJECT_RESULT_HXX | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 5 lines changed or added | |||
polymorphic-object-result.txx | polymorphic-object-result.txx | |||
---|---|---|---|---|
skipping to change at line 41 | skipping to change at line 41 | |||
this->end_ = true; | this->end_ = true; | |||
} | } | |||
statement_.reset (); | statement_.reset (); | |||
} | } | |||
template <typename T> | template <typename T> | |||
polymorphic_object_result_impl<T>:: | polymorphic_object_result_impl<T>:: | |||
polymorphic_object_result_impl (const query_base&, | polymorphic_object_result_impl (const query_base&, | |||
details::shared_ptr<select_statement> s t, | details::shared_ptr<select_statement> s t, | |||
statements_type& sts) | statements_type& sts, | |||
const schema_version_migration* svm) | ||||
: base_type (sts.connection ()), | : base_type (sts.connection ()), | |||
statement_ (st), | statement_ (st), | |||
statements_ (sts), | statements_ (sts), | |||
tc_ (svm), | ||||
count_ (0) | count_ (0) | |||
{ | { | |||
} | } | |||
template <typename T> | template <typename T> | |||
void polymorphic_object_result_impl<T>:: | void polymorphic_object_result_impl<T>:: | |||
load (object_type* pobj, bool fetch) | load (object_type* pobj, bool fetch) | |||
{ | { | |||
if (fetch) | if (fetch) | |||
load_image (); | load_image (); | |||
skipping to change at line 124 | skipping to change at line 126 | |||
const info_type& dpi (root_traits::map->find (typeid (*pobj))); | const info_type& dpi (root_traits::map->find (typeid (*pobj))); | |||
if (&dpi != &pi && dpi.derived (pi)) | if (&dpi != &pi && dpi.derived (pi)) | |||
throw object_not_persistent (); // @@ type_mismatch ? | throw object_not_persistent (); // @@ type_mismatch ? | |||
} | } | |||
} | } | |||
callback_event ce (callback_event::pre_load); | callback_event ce (callback_event::pre_load); | |||
pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | |||
object_traits::init (*pobj, i, &this->db_); | tc_.init (*pobj, i, &this->db_); | |||
// Initialize the id image and binding and load the rest of the objec t | // Initialize the id image and binding and load the rest of the objec t | |||
// (containers, dynamic part, etc). | // (containers, dynamic part, etc). | |||
// | // | |||
typename object_traits::id_image_type& idi (statements_.id_image ()); | typename object_traits::id_image_type& idi (statements_.id_image ()); | |||
root_traits::init (idi, id); | root_traits::init (idi, id); | |||
binding& idb (statements_.id_image_binding ()); | binding& idb (statements_.id_image_binding ()); | |||
if (idi.version != statements_.id_image_version () || idb.version == 0) | if (idi.version != statements_.id_image_version () || idb.version == 0) | |||
{ | { | |||
object_traits::bind (idb.bind, idi); | object_traits::bind (idb.bind, idi); | |||
statements_.id_image_version (idi.version); | statements_.id_image_version (idi.version); | |||
idb.version++; | idb.version++; | |||
} | } | |||
object_traits::load_ (statements_, *pobj); | tc_.load_ (statements_, *pobj, false); | |||
// Load the dynamic part of the object unless static and dynamic | // Load the dynamic part of the object unless static and dynamic | |||
// types are the same. | // types are the same. | |||
// | // | |||
if (&pi != &object_traits::info) | if (&pi != &object_traits::info) | |||
{ | { | |||
std::size_t d (object_traits::depth); | std::size_t d (object_traits::depth); | |||
pi.dispatch (info_type::call_load, this->db_, pobj, &d); | pi.dispatch (info_type::call_load, this->db_, pobj, &d); | |||
}; | }; | |||
rsts.load_delayed (); | rsts.load_delayed (tc_.version ()); | |||
l.unlock (); | l.unlock (); | |||
ce = callback_event::post_load; | ce = callback_event::post_load; | |||
pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | pi.dispatch (info_type::call_callback, this->db_, pobj, &ce); | |||
object_traits::pointer_cache_traits::load (ig.position ()); | object_traits::pointer_cache_traits::load (ig.position ()); | |||
ig.release (); | ig.release (); | |||
} | } | |||
template <typename T> | template <typename T> | |||
typename polymorphic_object_result_impl<T>::id_type | typename polymorphic_object_result_impl<T>::id_type | |||
skipping to change at line 202 | skipping to change at line 204 | |||
} | } | |||
template <typename T, typename R> | template <typename T, typename R> | |||
struct polymorphic_image_rebind | struct polymorphic_image_rebind | |||
{ | { | |||
// Derived type version. | // Derived type version. | |||
// | // | |||
typedef object_traits_impl<T, id_pgsql> traits; | typedef object_traits_impl<T, id_pgsql> traits; | |||
static bool | static bool | |||
rebind (typename traits::statements_type& sts) | rebind (typename traits::statements_type& sts, | |||
const schema_version_migration* svm) | ||||
{ | { | |||
typename traits::image_type& im (sts.image ()); | typename traits::image_type& im (sts.image ()); | |||
if (traits::check_version (sts.select_image_versions (), im)) | if (traits::check_version (sts.select_image_versions (), im)) | |||
{ | { | |||
binding& b (sts.select_image_binding (traits::depth)); | binding& b (sts.select_image_binding (traits::depth)); | |||
traits::bind (b.bind, 0, 0, im, statement_select); | object_traits_calls<T> tc (svm); | |||
tc.bind (b.bind, 0, 0, im, statement_select); | ||||
traits::update_version ( | traits::update_version ( | |||
sts.select_image_versions (), im, sts.select_image_bindings ()) ; | sts.select_image_versions (), im, sts.select_image_bindings ()) ; | |||
return true; | return true; | |||
} | } | |||
return false; | return false; | |||
} | } | |||
}; | }; | |||
template <typename R> | template <typename R> | |||
struct polymorphic_image_rebind<R, R> | struct polymorphic_image_rebind<R, R> | |||
{ | { | |||
// Root type version. | // Root type version. | |||
// | // | |||
typedef object_traits_impl<R, id_pgsql> traits; | typedef object_traits_impl<R, id_pgsql> traits; | |||
static bool | static bool | |||
rebind (typename traits::statements_type& sts) | rebind (typename traits::statements_type& sts, | |||
const schema_version_migration* svm) | ||||
{ | { | |||
typename traits::image_type& im (sts.image ()); | typename traits::image_type& im (sts.image ()); | |||
if (im.version != sts.select_image_version ()) | if (im.version != sts.select_image_version ()) | |||
{ | { | |||
binding& b (sts.select_image_binding ()); | binding& b (sts.select_image_binding ()); | |||
traits::bind (b.bind, im, statement_select); | object_traits_calls<R> tc (svm); | |||
tc.bind (b.bind, im, statement_select); | ||||
sts.select_image_version (im.version); | sts.select_image_version (im.version); | |||
b.version++; | b.version++; | |||
return true; | return true; | |||
} | } | |||
return false; | return false; | |||
} | } | |||
}; | }; | |||
template <typename T> | template <typename T> | |||
void polymorphic_object_result_impl<T>:: | void polymorphic_object_result_impl<T>:: | |||
load_image () | load_image () | |||
{ | { | |||
typedef polymorphic_image_rebind<object_type, root_type> image_rebind ; | typedef polymorphic_image_rebind<object_type, root_type> image_rebind ; | |||
// The image can grow between calls to load() as a result of other | // The image can grow between calls to load() as a result of other | |||
// statements execution. | // statements execution. | |||
// | // | |||
image_rebind::rebind (statements_); | image_rebind::rebind (statements_, tc_.version ()); | |||
select_statement::result r (statement_->load ()); | select_statement::result r (statement_->load ()); | |||
if (r == select_statement::truncated) | if (r == select_statement::truncated) | |||
{ | { | |||
typename object_traits::image_type& im (statements_.image ()); | typename object_traits::image_type& im (statements_.image ()); | |||
if (object_traits::grow (im, statements_.select_image_truncated ()) ) | if (tc_.grow (im, statements_.select_image_truncated ())) | |||
im.version++; | im.version++; | |||
if (image_rebind::rebind (statements_)) | if (image_rebind::rebind (statements_, tc_.version ())) | |||
statement_->reload (); | statement_->reload (); | |||
} | } | |||
} | } | |||
template <typename T> | template <typename T> | |||
void polymorphic_object_result_impl<T>:: | void polymorphic_object_result_impl<T>:: | |||
cache () | cache () | |||
{ | { | |||
} | } | |||
End of changes. 12 change blocks. | ||||
11 lines changed or deleted | 17 lines changed or added | |||
polymorphic-object-statements.hxx | polymorphic-object-statements.hxx | |||
---|---|---|---|---|
skipping to change at line 113 | skipping to change at line 113 | |||
// | // | |||
select_statement_type& | select_statement_type& | |||
find_discriminator_statement () | find_discriminator_statement () | |||
{ | { | |||
if (find_discriminator_ == 0) | if (find_discriminator_ == 0) | |||
find_discriminator_.reset ( | find_discriminator_.reset ( | |||
new (details::shared) select_statement_type ( | new (details::shared) select_statement_type ( | |||
this->conn_, | this->conn_, | |||
object_traits::find_discriminator_statement_name, | object_traits::find_discriminator_statement_name, | |||
object_traits::find_discriminator_statement, | object_traits::find_discriminator_statement, | |||
false, // Doesn't need to be processed. | ||||
false, // Don't optimize. | ||||
object_traits::find_statement_types, // The same as find (id) . | object_traits::find_statement_types, // The same as find (id) . | |||
id_column_count, | id_column_count, | |||
discriminator_id_image_binding_, | discriminator_id_image_binding_, | |||
discriminator_id_image_native_binding_, | discriminator_id_image_native_binding_, | |||
discriminator_image_binding_, | discriminator_image_binding_, | |||
false)); | false)); | |||
return *find_discriminator_; | return *find_discriminator_; | |||
} | } | |||
public: | public: | |||
polymorphic_root_object_statements (connection_type&); | polymorphic_root_object_statements (connection_type&); | |||
virtual | virtual | |||
~polymorphic_root_object_statements (); | ~polymorphic_root_object_statements (); | |||
// Static "override" (statements type). | ||||
// | ||||
void | ||||
load_delayed (const schema_version_migration* svm) | ||||
{ | ||||
assert (this->locked ()); | ||||
if (!this->delayed_.empty ()) | ||||
this->template load_delayed_<polymorphic_root_object_statements> | ||||
( | ||||
svm); | ||||
} | ||||
public: | public: | |||
static const std::size_t id_column_count = | static const std::size_t id_column_count = | |||
object_statements<T>::id_column_count; | object_statements<T>::id_column_count; | |||
static const std::size_t discriminator_column_count = | static const std::size_t discriminator_column_count = | |||
object_traits::discriminator_column_count; | object_traits::discriminator_column_count; | |||
static const std::size_t managed_optimistic_column_count = | static const std::size_t managed_optimistic_column_count = | |||
object_traits::managed_optimistic_column_count; | object_traits::managed_optimistic_column_count; | |||
skipping to change at line 186 | skipping to change at line 200 | |||
typedef | typedef | |||
polymorphic_root_object_statements<root_type> | polymorphic_root_object_statements<root_type> | |||
root_statements_type; | root_statements_type; | |||
typedef typename object_traits::base_type base_type; | typedef typename object_traits::base_type base_type; | |||
typedef | typedef | |||
typename object_traits::base_traits::statements_type | typename object_traits::base_traits::statements_type | |||
base_statements_type; | base_statements_type; | |||
typedef | typedef | |||
typename object_traits::container_statement_cache_type | typename object_traits::extra_statement_cache_type | |||
container_statement_cache_type; | extra_statement_cache_type; | |||
typedef pgsql::insert_statement insert_statement_type; | typedef pgsql::insert_statement insert_statement_type; | |||
typedef pgsql::select_statement select_statement_type; | typedef pgsql::select_statement select_statement_type; | |||
typedef pgsql::update_statement update_statement_type; | typedef pgsql::update_statement update_statement_type; | |||
typedef pgsql::delete_statement delete_statement_type; | typedef pgsql::delete_statement delete_statement_type; | |||
typedef typename root_statements_type::auto_lock auto_lock; | typedef typename root_statements_type::auto_lock auto_lock; | |||
public: | public: | |||
polymorphic_derived_object_statements (connection_type&); | polymorphic_derived_object_statements (connection_type&); | |||
virtual | virtual | |||
~polymorphic_derived_object_statements (); | ~polymorphic_derived_object_statements (); | |||
public: | public: | |||
// Delayed loading. | // Delayed loading. | |||
// | // | |||
static void | static void | |||
delayed_loader (odb::database&, const id_type&, root_type&); | delayed_loader (odb::database&, | |||
const id_type&, | ||||
root_type&, | ||||
const schema_version_migration*); | ||||
public: | public: | |||
// Root and immediate base statements. | // Root and immediate base statements. | |||
// | // | |||
root_statements_type& | root_statements_type& | |||
root_statements () | root_statements () | |||
{ | { | |||
return root_statements_; | return root_statements_; | |||
} | } | |||
base_statements_type& | base_statements_type& | |||
skipping to change at line 297 | skipping to change at line 313 | |||
std::size_t | std::size_t | |||
id_image_version () const {return root_statements_.id_image_version ( );} | id_image_version () const {return root_statements_.id_image_version ( );} | |||
void | void | |||
id_image_version (std::size_t v) {root_statements_.id_image_version ( v);} | id_image_version (std::size_t v) {root_statements_.id_image_version ( v);} | |||
binding& | binding& | |||
id_image_binding () {return root_statements_.id_image_binding ();} | id_image_binding () {return root_statements_.id_image_binding ();} | |||
binding& | ||||
optimistic_id_image_binding () { | ||||
return root_statements_.optimistic_id_image_binding ();} | ||||
// Statements. | // Statements. | |||
// | // | |||
insert_statement_type& | insert_statement_type& | |||
persist_statement () | persist_statement () | |||
{ | { | |||
if (persist_ == 0) | if (persist_ == 0) | |||
persist_.reset ( | persist_.reset ( | |||
new (details::shared) insert_statement_type ( | new (details::shared) insert_statement_type ( | |||
conn_, | conn_, | |||
object_traits::persist_statement_name, | object_traits::persist_statement_name, | |||
object_traits::persist_statement, | object_traits::persist_statement, | |||
object_traits::versioned, // Process if versioned. | ||||
object_traits::persist_statement_types, | object_traits::persist_statement_types, | |||
insert_column_count, | insert_column_count, | |||
insert_image_binding_, | insert_image_binding_, | |||
insert_image_native_binding_, | insert_image_native_binding_, | |||
object_traits::auto_id, | object_traits::auto_id, | |||
false)); | false)); | |||
return *persist_; | return *persist_; | |||
} | } | |||
skipping to change at line 330 | skipping to change at line 351 | |||
{ | { | |||
std::size_t i (object_traits::depth - d); | std::size_t i (object_traits::depth - d); | |||
details::shared_ptr<select_statement_type>& p (find_[i]); | details::shared_ptr<select_statement_type>& p (find_[i]); | |||
if (p == 0) | if (p == 0) | |||
p.reset ( | p.reset ( | |||
new (details::shared) select_statement_type ( | new (details::shared) select_statement_type ( | |||
conn_, | conn_, | |||
object_traits::find_statement_names[i], | object_traits::find_statement_names[i], | |||
object_traits::find_statements[i], | object_traits::find_statements[i], | |||
object_traits::versioned, // Process if versioned. | ||||
false, // Don't optimize. | ||||
object_traits::find_statement_types, | object_traits::find_statement_types, | |||
id_column_count, | id_column_count, | |||
root_statements_.id_image_binding (), | root_statements_.id_image_binding (), | |||
root_statements_.id_image_native_binding (), | root_statements_.id_image_native_binding (), | |||
select_image_bindings_[i], | select_image_bindings_[i], | |||
false)); | false)); | |||
return *p; | return *p; | |||
} | } | |||
update_statement_type& | update_statement_type& | |||
update_statement () | update_statement () | |||
{ | { | |||
if (update_ == 0) | if (update_ == 0) | |||
update_.reset ( | update_.reset ( | |||
new (details::shared) update_statement_type ( | new (details::shared) update_statement_type ( | |||
conn_, | conn_, | |||
object_traits::update_statement_name, | object_traits::update_statement_name, | |||
object_traits::update_statement, | object_traits::update_statement, | |||
object_traits::versioned, // Process if versioned. | ||||
object_traits::update_statement_types, | object_traits::update_statement_types, | |||
update_column_count + id_column_count, | update_column_count + id_column_count, | |||
update_image_binding_, | update_image_binding_, | |||
update_image_native_binding_, | update_image_native_binding_, | |||
false)); | false)); | |||
return *update_; | return *update_; | |||
} | } | |||
delete_statement_type& | delete_statement_type& | |||
skipping to change at line 376 | skipping to change at line 400 | |||
object_traits::erase_statement, | object_traits::erase_statement, | |||
object_traits::find_statement_types, // The same as find (id) . | object_traits::find_statement_types, // The same as find (id) . | |||
id_column_count, | id_column_count, | |||
root_statements_.id_image_binding (), | root_statements_.id_image_binding (), | |||
root_statements_.id_image_native_binding (), | root_statements_.id_image_native_binding (), | |||
false)); | false)); | |||
return *erase_; | return *erase_; | |||
} | } | |||
// Container statement cache. | // Extra (container, section) statement cache. | |||
// | // | |||
container_statement_cache_type& | extra_statement_cache_type& | |||
container_statment_cache () | extra_statement_cache () | |||
{ | { | |||
return container_statement_cache_.get ( | return extra_statement_cache_.get ( | |||
conn_, | conn_, | |||
root_statements_.id_image_binding (), | image_, | |||
id_image_binding (), | ||||
&id_image_binding (), // Note, not id+version. | ||||
root_statements_.id_image_native_binding (), | root_statements_.id_image_native_binding (), | |||
object_traits::find_statement_types); | object_traits::find_statement_types); | |||
} | } | |||
public: | public: | |||
// select = total - id + base::select | // select = total - id - separate_load + base::select | |||
// insert = total - inverse | // insert = total - inverse | |||
// update = total - inverse - id - readonly | // update = total - inverse - id - readonly - separate_update | |||
// | // | |||
static const std::size_t id_column_count = | static const std::size_t id_column_count = | |||
object_traits::id_column_count; | object_traits::id_column_count; | |||
static const std::size_t select_column_count = | static const std::size_t select_column_count = | |||
object_traits::column_count - id_column_count + | object_traits::column_count - | |||
id_column_count - | ||||
object_traits::separate_load_column_count + | ||||
base_statements_type::select_column_count; | base_statements_type::select_column_count; | |||
static const std::size_t insert_column_count = | static const std::size_t insert_column_count = | |||
object_traits::column_count - object_traits::inverse_column_count; | object_traits::column_count - | |||
object_traits::inverse_column_count; | ||||
static const std::size_t update_column_count = insert_column_count - | static const std::size_t update_column_count = | |||
object_traits::id_column_count - object_traits::readonly_column_cou | insert_column_count - | |||
nt; | object_traits::id_column_count - | |||
object_traits::readonly_column_count - | ||||
object_traits::separate_update_column_count; | ||||
private: | private: | |||
polymorphic_derived_object_statements ( | polymorphic_derived_object_statements ( | |||
const polymorphic_derived_object_statements&); | const polymorphic_derived_object_statements&); | |||
polymorphic_derived_object_statements& | polymorphic_derived_object_statements& | |||
operator= (const polymorphic_derived_object_statements&); | operator= (const polymorphic_derived_object_statements&); | |||
private: | private: | |||
root_statements_type& root_statements_; | root_statements_type& root_statements_; | |||
base_statements_type& base_statements_; | base_statements_type& base_statements_; | |||
container_statement_cache_ptr<container_statement_cache_type> | extra_statement_cache_ptr<extra_statement_cache_type, image_type> | |||
container_statement_cache_; | extra_statement_cache_; | |||
image_type image_; | image_type image_; | |||
// Select binding. Here we are have an array of statements/bindings | // Select binding. Here we are have an array of statements/bindings | |||
// one for each depth. In other words, if we have classes root, base, | // one for each depth. In other words, if we have classes root, base, | |||
// and derived, then we have the following array of statements: | // and derived, then we have the following array of statements: | |||
// | // | |||
// [0] d + b + r | // [0] d + b + r | |||
// [1] d + b | // [1] d + b | |||
// [2] d | // [2] d | |||
End of changes. 18 change blocks. | ||||
18 lines changed or deleted | 50 lines changed or added | |||
polymorphic-object-statements.txx | polymorphic-object-statements.txx | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#include <cstring> // std::memset | #include <cstring> // std::memset | |||
#include <odb/callback.hxx> | #include <odb/callback.hxx> | |||
#include <odb/exceptions.hxx> | #include <odb/exceptions.hxx> | |||
#include <odb/pgsql/connection.hxx> | #include <odb/pgsql/connection.hxx> | |||
#include <odb/pgsql/transaction.hxx> | #include <odb/pgsql/transaction.hxx> | |||
#include <odb/pgsql/statement-cache.hxx> | #include <odb/pgsql/statement-cache.hxx> | |||
#include <odb/pgsql/traits-calls.hxx> | ||||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
// | // | |||
// polymorphic_root_object_statements | // polymorphic_root_object_statements | |||
// | // | |||
template <typename T> | template <typename T> | |||
skipping to change at line 127 | skipping to change at line 128 | |||
std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | |||
std::memset ( | std::memset ( | |||
select_image_truncated_, 0, sizeof (select_image_truncated_)); | select_image_truncated_, 0, sizeof (select_image_truncated_)); | |||
for (std::size_t i (0); i < select_column_count; ++i) | for (std::size_t i (0); i < select_column_count; ++i) | |||
select_image_bind_[i].truncated = select_image_truncated_ + i; | select_image_bind_[i].truncated = select_image_truncated_ + i; | |||
} | } | |||
template <typename T> | template <typename T> | |||
void polymorphic_derived_object_statements<T>:: | void polymorphic_derived_object_statements<T>:: | |||
delayed_loader (odb::database& db, const id_type& id, root_type& robj) | delayed_loader (odb::database& db, | |||
const id_type& id, | ||||
root_type& robj, | ||||
const schema_version_migration* svm) | ||||
{ | { | |||
connection_type& conn (transaction::current ().connection ()); | connection_type& conn (transaction::current ().connection ()); | |||
polymorphic_derived_object_statements& sts ( | polymorphic_derived_object_statements& sts ( | |||
conn.statement_cache ().find_object<object_type> ()); | conn.statement_cache ().find_object<object_type> ()); | |||
root_statements_type& rsts (sts.root_statements ()); | root_statements_type& rsts (sts.root_statements ()); | |||
object_type& obj (static_cast<object_type&> (robj)); | object_type& obj (static_cast<object_type&> (robj)); | |||
// The same code as in object_statements::load_delayed_(). | // The same code as in object_statements::load_delayed_(). | |||
// | // | |||
if (!object_traits::find_ (sts, &id)) | object_traits_calls<T> tc (svm); | |||
if (!tc.find_ (sts, &id)) | ||||
throw object_not_persistent (); | throw object_not_persistent (); | |||
object_traits::callback (db, obj, callback_event::pre_load); | object_traits::callback (db, obj, callback_event::pre_load); | |||
object_traits::init (obj, sts.image (), &db); | tc.init (obj, sts.image (), &db); | |||
object_traits::load_ (sts, obj); // Load containers, etc. | tc.load_ (sts, obj, false); // Load containers, etc. | |||
rsts.load_delayed (); | rsts.load_delayed (svm); | |||
{ | { | |||
typename root_statements_type::auto_unlock u (rsts); | typename root_statements_type::auto_unlock u (rsts); | |||
object_traits::callback (db, obj, callback_event::post_load); | object_traits::callback (db, obj, callback_event::post_load); | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
End of changes. 5 change blocks. | ||||
5 lines changed or deleted | 11 lines changed or added | |||
query.hxx | query.hxx | |||
---|---|---|---|---|
skipping to change at line 733 | skipping to change at line 733 | |||
in (decayed_type, decayed_type, decayed_type, decayed_type) const; | in (decayed_type, decayed_type, decayed_type, decayed_type) const; | |||
query_base | query_base | |||
in (decayed_type, decayed_type, decayed_type, decayed_type, | in (decayed_type, decayed_type, decayed_type, decayed_type, | |||
decayed_type) const; | decayed_type) const; | |||
template <typename I> | template <typename I> | |||
query_base | query_base | |||
in_range (I begin, I end) const; | in_range (I begin, I end) const; | |||
// like | ||||
// | ||||
public: | ||||
query_base | ||||
like (decayed_type pattern) const | ||||
{ | ||||
return like (val_bind<T> (pattern)); | ||||
} | ||||
query_base | ||||
like (val_bind<T> pattern) const; | ||||
template <typename T2> | ||||
query_base | ||||
like (val_bind<T2> pattern) const | ||||
{ | ||||
return like (val_bind<T> (decayed_type (pattern.val))); | ||||
} | ||||
query_base | ||||
like (ref_bind<T> pattern) const; | ||||
query_base | ||||
like (decayed_type pattern, decayed_type escape) const | ||||
{ | ||||
return like (val_bind<T> (pattern), escape); | ||||
} | ||||
query_base | ||||
like (val_bind<T> pattern, decayed_type escape) const; | ||||
template <typename T2> | ||||
query_base | ||||
like (val_bind<T2> pattern, decayed_type escape) const | ||||
{ | ||||
return like (val_bind<T> (decayed_type (pattern.val)), escape); | ||||
} | ||||
query_base | ||||
like (ref_bind<T> pattern, decayed_type escape) const; | ||||
// = | // = | |||
// | // | |||
public: | public: | |||
query_base | query_base | |||
equal (decayed_type v) const | equal (decayed_type v) const | |||
{ | { | |||
return equal (val_bind<T> (v)); | return equal (val_bind<T> (v)); | |||
} | } | |||
query_base | query_base | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 41 lines changed or added | |||
query.txx | query.txx | |||
---|---|---|---|---|
// file : odb/pgsql/query.txx | // file : odb/pgsql/query.txx | |||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
// | ||||
// query_base | // query_base | |||
// | // | |||
template <database_type_id ID> | template <database_type_id ID> | |||
query_base:: | query_base:: | |||
query_base (const query_column<bool, ID>& c) | query_base (const query_column<bool, ID>& c) | |||
: binding_ (0, 0), native_binding_ (0, 0, 0, 0) | : binding_ (0, 0), native_binding_ (0, 0, 0, 0) | |||
{ | { | |||
// Cannot use IS TRUE here since database type can be a non- | // Cannot use IS TRUE here since database type can be a non- | |||
// integral type. | // integral type. | |||
// | // | |||
append (c.table (), c.column ()); | append (c.table (), c.column ()); | |||
append ("="); | append ("="); | |||
append<bool, ID> (val_bind<bool> (true), c.conversion ()); | append<bool, ID> (val_bind<bool> (true), c.conversion ()); | |||
} | } | |||
// | ||||
// query_column | // query_column | |||
// | // | |||
// in | ||||
// | ||||
template <typename T, database_type_id ID> | template <typename T, database_type_id ID> | |||
query_base query_column<T, ID>:: | query_base query_column<T, ID>:: | |||
in (decayed_type v1, decayed_type v2) const | in (decayed_type v1, decayed_type v2) const | |||
{ | { | |||
query_base q (table_, column_); | query_base q (table_, column_); | |||
q += "IN ("; | q += "IN ("; | |||
q.append<T, ID> (val_bind<T> (v1), conversion_); | q.append<T, ID> (val_bind<T> (v1), conversion_); | |||
q += ","; | q += ","; | |||
q.append<T, ID> (val_bind<T> (v2), conversion_); | q.append<T, ID> (val_bind<T> (v2), conversion_); | |||
q += ")"; | q += ")"; | |||
skipping to change at line 112 | skipping to change at line 117 | |||
{ | { | |||
if (i != begin) | if (i != begin) | |||
q += ","; | q += ","; | |||
q.append<T, ID> (val_bind<T> (*i), conversion_); | q.append<T, ID> (val_bind<T> (*i), conversion_); | |||
} | } | |||
q += ")"; | q += ")"; | |||
return q; | return q; | |||
} | } | |||
// like | ||||
// | ||||
template <typename T, database_type_id ID> | ||||
query_base query_column<T, ID>:: | ||||
like (val_bind<T> p) const | ||||
{ | ||||
query_base q (table_, column_); | ||||
q += "LIKE"; | ||||
q.append<T, ID> (p, conversion_); | ||||
return q; | ||||
} | ||||
template <typename T, database_type_id ID> | ||||
query_base query_column<T, ID>:: | ||||
like (ref_bind<T> p) const | ||||
{ | ||||
query_base q (table_, column_); | ||||
q += "LIKE"; | ||||
q.append<T, ID> (p, conversion_); | ||||
return q; | ||||
} | ||||
template <typename T, database_type_id ID> | ||||
query_base query_column<T, ID>:: | ||||
like (val_bind<T> p, decayed_type e) const | ||||
{ | ||||
query_base q (table_, column_); | ||||
q += "LIKE"; | ||||
q.append<T, ID> (p, conversion_); | ||||
q += "ESCAPE"; | ||||
q.append<T, ID> (val_bind<T> (e), conversion_); | ||||
return q; | ||||
} | ||||
template <typename T, database_type_id ID> | ||||
query_base query_column<T, ID>:: | ||||
like (ref_bind<T> p, decayed_type e) const | ||||
{ | ||||
query_base q (table_, column_); | ||||
q += "LIKE"; | ||||
q.append<T, ID> (p, conversion_); | ||||
q += "ESCAPE"; | ||||
q.append<T, ID> (val_bind<T> (e), conversion_); | ||||
return q; | ||||
} | ||||
} | } | |||
} | } | |||
End of changes. 4 change blocks. | ||||
0 lines changed or deleted | 51 lines changed or added | |||
simple-object-result.hxx | simple-object-result.hxx | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#ifndef ODB_PGSQL_SIMPLE_OBJECT_RESULT_HXX | #ifndef ODB_PGSQL_SIMPLE_OBJECT_RESULT_HXX | |||
#define ODB_PGSQL_SIMPLE_OBJECT_RESULT_HXX | #define ODB_PGSQL_SIMPLE_OBJECT_RESULT_HXX | |||
#include <odb/pre.hxx> | #include <odb/pre.hxx> | |||
#include <cstddef> // std::size_t | #include <cstddef> // std::size_t | |||
#include <odb/schema-version.hxx> | ||||
#include <odb/simple-object-result.hxx> | #include <odb/simple-object-result.hxx> | |||
#include <odb/details/shared-ptr.hxx> | #include <odb/details/shared-ptr.hxx> | |||
#include <odb/pgsql/version.hxx> | #include <odb/pgsql/version.hxx> | |||
#include <odb/pgsql/forward.hxx> // query_base | #include <odb/pgsql/forward.hxx> // query_base | |||
#include <odb/pgsql/statement.hxx> | #include <odb/pgsql/statement.hxx> | |||
#include <odb/pgsql/traits-calls.hxx> | ||||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
template <typename T> | template <typename T> | |||
class object_result_impl: public odb::object_result_impl<T> | class object_result_impl: public odb::object_result_impl<T> | |||
{ | { | |||
public: | public: | |||
typedef odb::object_result_impl<T> base_type; | typedef odb::object_result_impl<T> base_type; | |||
skipping to change at line 44 | skipping to change at line 46 | |||
typedef object_traits_impl<object_type, id_pgsql> object_traits; | typedef object_traits_impl<object_type, id_pgsql> object_traits; | |||
typedef typename base_type::pointer_traits pointer_traits; | typedef typename base_type::pointer_traits pointer_traits; | |||
typedef typename object_traits::statements_type statements_type; | typedef typename object_traits::statements_type statements_type; | |||
virtual | virtual | |||
~object_result_impl (); | ~object_result_impl (); | |||
object_result_impl (const query_base&, | object_result_impl (const query_base&, | |||
details::shared_ptr<select_statement>, | details::shared_ptr<select_statement>, | |||
statements_type&); | statements_type&, | |||
const schema_version_migration*); | ||||
virtual void | virtual void | |||
load (object_type&, bool fetch); | load (object_type&, bool fetch); | |||
virtual id_type | virtual id_type | |||
load_id (); | load_id (); | |||
virtual void | virtual void | |||
next (); | next (); | |||
skipping to change at line 73 | skipping to change at line 76 | |||
using base_type::current; | using base_type::current; | |||
private: | private: | |||
void | void | |||
load_image (); | load_image (); | |||
private: | private: | |||
details::shared_ptr<select_statement> statement_; | details::shared_ptr<select_statement> statement_; | |||
statements_type& statements_; | statements_type& statements_; | |||
object_traits_calls<object_type> tc_; | ||||
std::size_t count_; | std::size_t count_; | |||
}; | }; | |||
} | } | |||
} | } | |||
#include <odb/pgsql/simple-object-result.txx> | #include <odb/pgsql/simple-object-result.txx> | |||
#include <odb/post.hxx> | #include <odb/post.hxx> | |||
#endif // ODB_PGSQL_SIMPLE_OBJECT_RESULT_HXX | #endif // ODB_PGSQL_SIMPLE_OBJECT_RESULT_HXX | |||
End of changes. 4 change blocks. | ||||
1 lines changed or deleted | 5 lines changed or added | |||
simple-object-result.txx | simple-object-result.txx | |||
---|---|---|---|---|
skipping to change at line 40 | skipping to change at line 40 | |||
this->end_ = true; | this->end_ = true; | |||
} | } | |||
statement_.reset (); | statement_.reset (); | |||
} | } | |||
template <typename T> | template <typename T> | |||
object_result_impl<T>:: | object_result_impl<T>:: | |||
object_result_impl (const query_base&, | object_result_impl (const query_base&, | |||
details::shared_ptr<select_statement> statement, | details::shared_ptr<select_statement> statement, | |||
statements_type& statements) | statements_type& statements, | |||
const schema_version_migration* svm) | ||||
: base_type (statements.connection ()), | : base_type (statements.connection ()), | |||
statement_ (statement), | statement_ (statement), | |||
statements_ (statements), | statements_ (statements), | |||
tc_ (svm), | ||||
count_ (0) | count_ (0) | |||
{ | { | |||
} | } | |||
template <typename T> | template <typename T> | |||
void object_result_impl<T>:: | void object_result_impl<T>:: | |||
load (object_type& obj, bool fetch) | load (object_type& obj, bool fetch) | |||
{ | { | |||
if (fetch) | if (fetch) | |||
load_image (); | load_image (); | |||
// This is a top-level call so the statements cannot be locked. | // This is a top-level call so the statements cannot be locked. | |||
// | // | |||
assert (!statements_.locked ()); | assert (!statements_.locked ()); | |||
typename statements_type::auto_lock l (statements_); | typename statements_type::auto_lock l (statements_); | |||
object_traits::callback (this->db_, obj, callback_event::pre_load); | object_traits::callback (this->db_, obj, callback_event::pre_load); | |||
typename object_traits::image_type& i (statements_.image ()); | typename object_traits::image_type& i (statements_.image ()); | |||
object_traits::init (obj, i, &this->db_); | tc_.init (obj, i, &this->db_); | |||
// Initialize the id image and binding and load the rest of the objec t | // Initialize the id image and binding and load the rest of the objec t | |||
// (containers, etc). | // (containers, etc). | |||
// | // | |||
typename object_traits::id_image_type& idi (statements_.id_image ()); | typename object_traits::id_image_type& idi (statements_.id_image ()); | |||
object_traits::init (idi, object_traits::id (i)); | object_traits::init (idi, object_traits::id (i)); | |||
binding& idb (statements_.id_image_binding ()); | binding& idb (statements_.id_image_binding ()); | |||
if (idi.version != statements_.id_image_version () || idb.version == 0) | if (idi.version != statements_.id_image_version () || idb.version == 0) | |||
{ | { | |||
object_traits::bind (idb.bind, idi); | object_traits::bind (idb.bind, idi); | |||
statements_.id_image_version (idi.version); | statements_.id_image_version (idi.version); | |||
idb.version++; | idb.version++; | |||
} | } | |||
object_traits::load_ (statements_, obj); | tc_.load_ (statements_, obj, false); | |||
statements_.load_delayed (); | statements_.load_delayed (tc_.version ()); | |||
l.unlock (); | l.unlock (); | |||
object_traits::callback (this->db_, obj, callback_event::post_load); | object_traits::callback (this->db_, obj, callback_event::post_load); | |||
} | } | |||
template <typename T> | template <typename T> | |||
typename object_result_impl<T>::id_type | typename object_result_impl<T>::id_type | |||
object_result_impl<T>:: | object_result_impl<T>:: | |||
load_id () | load_id () | |||
{ | { | |||
load_image (); | load_image (); | |||
skipping to change at line 121 | skipping to change at line 123 | |||
load_image () | load_image () | |||
{ | { | |||
// The image can grow between calls to load() as a result of other | // The image can grow between calls to load() as a result of other | |||
// statements execution. | // statements execution. | |||
// | // | |||
typename object_traits::image_type& im (statements_.image ()); | typename object_traits::image_type& im (statements_.image ()); | |||
if (im.version != statements_.select_image_version ()) | if (im.version != statements_.select_image_version ()) | |||
{ | { | |||
binding& b (statements_.select_image_binding ()); | binding& b (statements_.select_image_binding ()); | |||
object_traits::bind (b.bind, im, statement_select); | tc_.bind (b.bind, im, statement_select); | |||
statements_.select_image_version (im.version); | statements_.select_image_version (im.version); | |||
b.version++; | b.version++; | |||
} | } | |||
select_statement::result r (statement_->load ()); | select_statement::result r (statement_->load ()); | |||
if (r == select_statement::truncated) | if (r == select_statement::truncated) | |||
{ | { | |||
if (object_traits::grow (im, statements_.select_image_truncated ()) ) | if (tc_.grow (im, statements_.select_image_truncated ())) | |||
im.version++; | im.version++; | |||
if (im.version != statements_.select_image_version ()) | if (im.version != statements_.select_image_version ()) | |||
{ | { | |||
binding& b (statements_.select_image_binding ()); | binding& b (statements_.select_image_binding ()); | |||
object_traits::bind (b.bind, im, statement_select); | tc_.bind (b.bind, im, statement_select); | |||
statements_.select_image_version (im.version); | statements_.select_image_version (im.version); | |||
b.version++; | b.version++; | |||
statement_->reload (); | statement_->reload (); | |||
} | } | |||
} | } | |||
} | } | |||
template <typename T> | template <typename T> | |||
void object_result_impl<T>:: | void object_result_impl<T>:: | |||
cache () | cache () | |||
End of changes. 7 change blocks. | ||||
7 lines changed or deleted | 9 lines changed or added | |||
simple-object-statements.hxx | simple-object-statements.hxx | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
#include <odb/pgsql/binding.hxx> | #include <odb/pgsql/binding.hxx> | |||
#include <odb/pgsql/statement.hxx> | #include <odb/pgsql/statement.hxx> | |||
#include <odb/pgsql/statements-base.hxx> | #include <odb/pgsql/statements-base.hxx> | |||
#include <odb/pgsql/details/export.hxx> | #include <odb/pgsql/details/export.hxx> | |||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
// The container_statement_cache class is only defined (and used) in | // The extra_statement_cache class is only defined (and used) in | |||
// the generated source file. However, object_statements may be | // the generated source file. However, object_statements may be | |||
// referenced from another source file in the case of a polymorphic | // referenced from another source file in the case of a polymorphic | |||
// hierarchy (though in this case the container statement cache is | // hierarchy (though in this case the extra statement cache is | |||
// not used). As a result, we cannot have a by-value member and | // not used). As a result, we cannot have a by-value member and | |||
// instead will store a pointer and lazily allocate the cache if | // instead will store a pointer and lazily allocate the cache if | |||
// and when needed. We will also need to store a pointer to the | // and when needed. We will also need to store a pointer to the | |||
// deleter function which will be initialized during allocation | // deleter function which will be initialized during allocation | |||
// (at that point we know that the cache class is defined). | // (at that point we know that the cache class is defined). | |||
// | // | |||
template <typename T> | template <typename T, typename I> | |||
struct container_statement_cache_ptr | struct extra_statement_cache_ptr | |||
{ | { | |||
typedef I image_type; | ||||
typedef pgsql::connection connection_type; | typedef pgsql::connection connection_type; | |||
container_statement_cache_ptr (): p_ (0) {} | extra_statement_cache_ptr (): p_ (0) {} | |||
~container_statement_cache_ptr () | ~extra_statement_cache_ptr () | |||
{ | { | |||
if (p_ != 0) | if (p_ != 0) | |||
(this->*deleter_) (0, 0, 0, 0); | (this->*deleter_) (0, 0, 0, 0, 0, 0); | |||
} | } | |||
T& | T& | |||
get (connection_type& c, | get (connection_type& c, | |||
binding& id, native_binding& idn, const Oid* idt) | image_type& im, | |||
binding& id, | ||||
binding* idv, | ||||
native_binding& idn, | ||||
const Oid* idt) | ||||
{ | { | |||
if (p_ == 0) | if (p_ == 0) | |||
allocate (&c, &id, &idn, idt); | allocate (&c, &im, &id, (idv != 0 ? idv : &id), &idn, idt); | |||
return *p_; | return *p_; | |||
} | } | |||
private: | private: | |||
void | void | |||
allocate (connection_type*, binding*, native_binding*, const Oid*); | allocate (connection_type*, | |||
image_type*, | ||||
binding*, binding*, native_binding*, const Oid*); | ||||
private: | private: | |||
T* p_; | T* p_; | |||
void (container_statement_cache_ptr::*deleter_) ( | void (extra_statement_cache_ptr::*deleter_) ( | |||
connection_type*, binding*, native_binding*, const Oid*); | connection_type*, | |||
image_type*, | ||||
binding*, binding*, native_binding*, const Oid*); | ||||
}; | }; | |||
template <typename T> | template <typename T, typename I> | |||
void container_statement_cache_ptr<T>:: | void extra_statement_cache_ptr<T, I>:: | |||
allocate (connection_type* c, | allocate (connection_type* c, | |||
binding* id, native_binding* idn, const Oid* idt) | image_type* im, | |||
binding* id, binding* idv, native_binding* idn, const Oid* id | ||||
t) | ||||
{ | { | |||
// To reduce object code size, this function acts as both allocator | // To reduce object code size, this function acts as both allocator | |||
// and deleter. | // and deleter. | |||
// | // | |||
if (p_ == 0) | if (p_ == 0) | |||
{ | { | |||
p_ = new T (*c, *id, *idn, idt); | p_ = new T (*c, *im, *id, *idv, *idn, idt); | |||
deleter_ = &container_statement_cache_ptr<T>::allocate; | deleter_ = &extra_statement_cache_ptr<T, I>::allocate; | |||
} | } | |||
else | else | |||
delete p_; | delete p_; | |||
} | } | |||
// | // | |||
// Implementation for objects with object id. | // Implementation for objects with object id. | |||
// | // | |||
class LIBODB_PGSQL_EXPORT object_statements_base: public statements_bas e | class LIBODB_PGSQL_EXPORT object_statements_base: public statements_bas e | |||
skipping to change at line 161 | skipping to change at line 171 | |||
struct optimistic_data; | struct optimistic_data; | |||
template <typename T> | template <typename T> | |||
struct optimistic_data<T, true> | struct optimistic_data<T, true> | |||
{ | { | |||
typedef T object_type; | typedef T object_type; | |||
typedef object_traits_impl<object_type, id_pgsql> object_traits; | typedef object_traits_impl<object_type, id_pgsql> object_traits; | |||
optimistic_data (bind*, char** nv, int* nl, int* nf); | optimistic_data (bind*, char** nv, int* nl, int* nf); | |||
binding* | ||||
id_image_binding () {return &id_image_binding_;} | ||||
native_binding* | ||||
id_image_native_binding () {return &id_image_native_binding_;} | ||||
const Oid* | ||||
id_image_types () | ||||
{return object_traits::optimistic_erase_statement_types;} | ||||
// The id + optimistic column binding. | // The id + optimistic column binding. | |||
// | // | |||
std::size_t id_image_version_; | ||||
binding id_image_binding_; | binding id_image_binding_; | |||
native_binding id_image_native_binding_; | native_binding id_image_native_binding_; | |||
details::shared_ptr<delete_statement> erase_; | details::shared_ptr<delete_statement> erase_; | |||
}; | }; | |||
template <typename T> | template <typename T> | |||
struct optimistic_data<T, false> | struct optimistic_data<T, false> | |||
{ | { | |||
optimistic_data (bind*, char**, int*, int*) {} | optimistic_data (bind*, char**, int*, int*) {} | |||
binding* | ||||
id_image_binding () {return 0;} | ||||
native_binding* | ||||
id_image_native_binding () {return 0;} | ||||
const Oid* | ||||
id_image_types () {return 0;} | ||||
}; | }; | |||
template <typename T> | template <typename T> | |||
class object_statements: public object_statements_base | class object_statements: public object_statements_base | |||
{ | { | |||
public: | public: | |||
typedef T object_type; | typedef T object_type; | |||
typedef object_traits_impl<object_type, id_pgsql> object_traits; | typedef object_traits_impl<object_type, id_pgsql> object_traits; | |||
typedef typename object_traits::id_type id_type; | typedef typename object_traits::id_type id_type; | |||
typedef typename object_traits::pointer_type pointer_type; | typedef typename object_traits::pointer_type pointer_type; | |||
typedef typename object_traits::image_type image_type; | typedef typename object_traits::image_type image_type; | |||
typedef typename object_traits::id_image_type id_image_type; | typedef typename object_traits::id_image_type id_image_type; | |||
typedef | typedef | |||
typename object_traits::pointer_cache_traits | typename object_traits::pointer_cache_traits | |||
pointer_cache_traits; | pointer_cache_traits; | |||
typedef | typedef | |||
typename object_traits::container_statement_cache_type | typename object_traits::extra_statement_cache_type | |||
container_statement_cache_type; | extra_statement_cache_type; | |||
typedef pgsql::insert_statement insert_statement_type; | typedef pgsql::insert_statement insert_statement_type; | |||
typedef pgsql::select_statement select_statement_type; | typedef pgsql::select_statement select_statement_type; | |||
typedef pgsql::update_statement update_statement_type; | typedef pgsql::update_statement update_statement_type; | |||
typedef pgsql::delete_statement delete_statement_type; | typedef pgsql::delete_statement delete_statement_type; | |||
// Automatic lock. | // Automatic lock. | |||
// | // | |||
struct auto_lock | struct auto_lock | |||
{ | { | |||
skipping to change at line 243 | skipping to change at line 271 | |||
}; | }; | |||
public: | public: | |||
object_statements (connection_type&); | object_statements (connection_type&); | |||
virtual | virtual | |||
~object_statements (); | ~object_statements (); | |||
// Delayed loading. | // Delayed loading. | |||
// | // | |||
typedef void (*loader_function) ( | typedef void (*loader_function) (odb::database&, | |||
odb::database&, const id_type&, object_type&); | const id_type&, | |||
object_type&, | ||||
const schema_version_migration*); | ||||
void | void | |||
delay_load (const id_type& id, | delay_load (const id_type& id, | |||
object_type& obj, | object_type& obj, | |||
const typename pointer_cache_traits::position_type& p, | const typename pointer_cache_traits::position_type& p, | |||
loader_function l = 0) | loader_function l = 0) | |||
{ | { | |||
delayed_.push_back (delayed_load (id, obj, p, l)); | delayed_.push_back (delayed_load (id, obj, p, l)); | |||
} | } | |||
void | void | |||
load_delayed () | load_delayed (const schema_version_migration* svm) | |||
{ | { | |||
assert (locked ()); | assert (locked ()); | |||
if (!delayed_.empty ()) | if (!delayed_.empty ()) | |||
load_delayed_ (); | load_delayed_<object_statements> (svm); | |||
} | } | |||
void | void | |||
clear_delayed () | clear_delayed () | |||
{ | { | |||
if (!delayed_.empty ()) | if (!delayed_.empty ()) | |||
clear_delayed_ (); | clear_delayed_ (); | |||
} | } | |||
// Object image. | // Object image. | |||
skipping to change at line 332 | skipping to change at line 361 | |||
std::size_t | std::size_t | |||
id_image_version () const {return id_image_version_;} | id_image_version () const {return id_image_version_;} | |||
void | void | |||
id_image_version (std::size_t v) {id_image_version_ = v;} | id_image_version (std::size_t v) {id_image_version_ = v;} | |||
binding& | binding& | |||
id_image_binding () {return id_image_binding_;} | id_image_binding () {return id_image_binding_;} | |||
// Optimistic id + managed column image binding. | // Optimistic id + managed column image binding. It points to | |||
// the same suffix as id binding and they are always updated | ||||
// at the same time. | ||||
// | // | |||
std::size_t | ||||
optimistic_id_image_version () const {return od_.id_image_version_;} | ||||
void | ||||
optimistic_id_image_version (std::size_t v) {od_.id_image_version_ = | ||||
v;} | ||||
binding& | binding& | |||
optimistic_id_image_binding () {return od_.id_image_binding_;} | optimistic_id_image_binding () {return od_.id_image_binding_;} | |||
// Statements. | // Statements. | |||
// | // | |||
insert_statement_type& | insert_statement_type& | |||
persist_statement () | persist_statement () | |||
{ | { | |||
if (persist_ == 0) | if (persist_ == 0) | |||
persist_.reset ( | persist_.reset ( | |||
new (details::shared) insert_statement_type ( | new (details::shared) insert_statement_type ( | |||
conn_, | conn_, | |||
object_traits::persist_statement_name, | object_traits::persist_statement_name, | |||
object_traits::persist_statement, | object_traits::persist_statement, | |||
object_traits::versioned, // Process if versioned. | ||||
object_traits::persist_statement_types, | object_traits::persist_statement_types, | |||
insert_column_count, | insert_column_count, | |||
insert_image_binding_, | insert_image_binding_, | |||
insert_image_native_binding_, | insert_image_native_binding_, | |||
object_traits::auto_id, | object_traits::auto_id, | |||
false)); | false)); | |||
return *persist_; | return *persist_; | |||
} | } | |||
select_statement_type& | select_statement_type& | |||
find_statement () | find_statement () | |||
{ | { | |||
if (find_ == 0) | if (find_ == 0) | |||
find_.reset ( | find_.reset ( | |||
new (details::shared) select_statement_type ( | new (details::shared) select_statement_type ( | |||
conn_, | conn_, | |||
object_traits::find_statement_name, | object_traits::find_statement_name, | |||
object_traits::find_statement, | object_traits::find_statement, | |||
object_traits::versioned, // Process if versioned. | ||||
false, // Don't optimize. | ||||
object_traits::find_statement_types, | object_traits::find_statement_types, | |||
id_column_count, | id_column_count, | |||
id_image_binding_, | id_image_binding_, | |||
id_image_native_binding_, | id_image_native_binding_, | |||
select_image_binding_, | select_image_binding_, | |||
false)); | false)); | |||
return *find_; | return *find_; | |||
} | } | |||
update_statement_type& | update_statement_type& | |||
update_statement () | update_statement () | |||
{ | { | |||
if (update_ == 0) | if (update_ == 0) | |||
update_.reset ( | update_.reset ( | |||
new (details::shared) update_statement_type ( | new (details::shared) update_statement_type ( | |||
conn_, | conn_, | |||
object_traits::update_statement_name, | object_traits::update_statement_name, | |||
object_traits::update_statement, | object_traits::update_statement, | |||
object_traits::versioned, // Process if versioned. | ||||
object_traits::update_statement_types, | object_traits::update_statement_types, | |||
update_column_count + id_column_count, | update_column_count + id_column_count, | |||
update_image_binding_, | update_image_binding_, | |||
update_image_native_binding_, | update_image_native_binding_, | |||
false)); | false)); | |||
return *update_; | return *update_; | |||
} | } | |||
delete_statement_type& | delete_statement_type& | |||
skipping to change at line 437 | skipping to change at line 466 | |||
object_traits::optimistic_erase_statement, | object_traits::optimistic_erase_statement, | |||
object_traits::optimistic_erase_statement_types, | object_traits::optimistic_erase_statement_types, | |||
id_column_count + managed_optimistic_column_count, | id_column_count + managed_optimistic_column_count, | |||
od_.id_image_binding_, | od_.id_image_binding_, | |||
od_.id_image_native_binding_, | od_.id_image_native_binding_, | |||
false)); | false)); | |||
return *od_.erase_; | return *od_.erase_; | |||
} | } | |||
// Container statement cache. | // Extra (container, section) statement cache. | |||
// | // | |||
container_statement_cache_type& | extra_statement_cache_type& | |||
container_statment_cache () | extra_statement_cache () | |||
{ | { | |||
return container_statement_cache_.get ( | return extra_statement_cache_.get ( | |||
conn_, | conn_, | |||
image_, | ||||
id_image_binding_, | id_image_binding_, | |||
od_.id_image_binding (), | ||||
id_image_native_binding_, | id_image_native_binding_, | |||
object_traits::find_statement_types); | object_traits::find_statement_types); | |||
} | } | |||
public: | public: | |||
// select = total | // select = total - separate_load | |||
// insert = total - inverse - managed_optimistic - auto_id | // insert = total - inverse - managed_optimistic - auto_id | |||
// update = total - inverse - managed_optimistic - id - readonly | // update = total - inverse - managed_optimistic - id - readonly - | |||
// separate_update | ||||
// | // | |||
static const std::size_t select_column_count = | static const std::size_t select_column_count = | |||
object_traits::column_count; | object_traits::column_count - | |||
object_traits::separate_load_column_count; | ||||
static const std::size_t id_column_count = | static const std::size_t id_column_count = | |||
object_traits::id_column_count; | object_traits::id_column_count; | |||
static const std::size_t insert_column_count = | static const std::size_t insert_column_count = | |||
object_traits::column_count - object_traits::inverse_column_count - | object_traits::column_count - | |||
object_traits::inverse_column_count - | ||||
object_traits::managed_optimistic_column_count - | object_traits::managed_optimistic_column_count - | |||
(object_traits::auto_id ? id_column_count : 0); | (object_traits::auto_id ? id_column_count : 0); | |||
static const std::size_t update_column_count = insert_column_count - | static const std::size_t update_column_count = | |||
insert_column_count - | ||||
(object_traits::auto_id ? 0 : id_column_count) - | (object_traits::auto_id ? 0 : id_column_count) - | |||
object_traits::readonly_column_count; | object_traits::readonly_column_count - | |||
object_traits::separate_update_column_count; | ||||
static const std::size_t managed_optimistic_column_count = | static const std::size_t managed_optimistic_column_count = | |||
object_traits::managed_optimistic_column_count; | object_traits::managed_optimistic_column_count; | |||
private: | private: | |||
object_statements (const object_statements&); | object_statements (const object_statements&); | |||
object_statements& operator= (const object_statements&); | object_statements& operator= (const object_statements&); | |||
private: | protected: | |||
template <typename STS> | ||||
void | void | |||
load_delayed_ (); | load_delayed_ (const schema_version_migration*); | |||
void | void | |||
clear_delayed_ (); | clear_delayed_ (); | |||
protected: | protected: | |||
container_statement_cache_ptr<container_statement_cache_type> | template <typename T1> | |||
container_statement_cache_; | friend class polymorphic_derived_object_statements; | |||
extra_statement_cache_ptr<extra_statement_cache_type, image_type> | ||||
extra_statement_cache_; | ||||
image_type image_; | image_type image_; | |||
// Select binding. | // Select binding. | |||
// | // | |||
std::size_t select_image_version_; | std::size_t select_image_version_; | |||
binding select_image_binding_; | binding select_image_binding_; | |||
bind select_image_bind_[select_column_count]; | bind select_image_bind_[select_column_count]; | |||
bool select_image_truncated_[select_column_count]; | bool select_image_truncated_[select_column_count]; | |||
End of changes. 39 change blocks. | ||||
47 lines changed or deleted | 87 lines changed or added | |||
simple-object-statements.txx | simple-object-statements.txx | |||
---|---|---|---|---|
// file : odb/pgsql/simple-object-statements.txx | // file : odb/pgsql/simple-object-statements.txx | |||
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#include <cstring> // std::memset | #include <cstring> // std::memset | |||
#include <odb/callback.hxx> | #include <odb/callback.hxx> | |||
#include <odb/exceptions.hxx> | #include <odb/exceptions.hxx> | |||
#include <odb/pgsql/connection.hxx> | #include <odb/pgsql/connection.hxx> | |||
#include <odb/pgsql/traits-calls.hxx> | ||||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
// | // | |||
// optimistic_data | // optimistic_data | |||
// | // | |||
template <typename T> | template <typename T> | |||
skipping to change at line 32 | skipping to change at line 33 | |||
optimistic_data (bind* b, char** nv, int* nl, int* nf) | optimistic_data (bind* b, char** nv, int* nl, int* nf) | |||
: id_image_binding_ ( | : id_image_binding_ ( | |||
b, | b, | |||
object_traits::id_column_count + | object_traits::id_column_count + | |||
object_traits::managed_optimistic_column_count), | object_traits::managed_optimistic_column_count), | |||
id_image_native_binding_ ( | id_image_native_binding_ ( | |||
nv, nl, nf, | nv, nl, nf, | |||
object_traits::id_column_count + | object_traits::id_column_count + | |||
object_traits::managed_optimistic_column_count) | object_traits::managed_optimistic_column_count) | |||
{ | { | |||
id_image_version_ = 0; | ||||
} | } | |||
// | // | |||
// object_statements | // object_statements | |||
// | // | |||
template <typename T> | template <typename T> | |||
object_statements<T>:: | object_statements<T>:: | |||
~object_statements () | ~object_statements () | |||
{ | { | |||
skipping to change at line 100 | skipping to change at line 100 | |||
std::memset (update_image_bind_, 0, sizeof (update_image_bind_)); | std::memset (update_image_bind_, 0, sizeof (update_image_bind_)); | |||
std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | std::memset (select_image_bind_, 0, sizeof (select_image_bind_)); | |||
std::memset ( | std::memset ( | |||
select_image_truncated_, 0, sizeof (select_image_truncated_)); | select_image_truncated_, 0, sizeof (select_image_truncated_)); | |||
for (std::size_t i (0); i < select_column_count; ++i) | for (std::size_t i (0); i < select_column_count; ++i) | |||
select_image_bind_[i].truncated = select_image_truncated_ + i; | select_image_bind_[i].truncated = select_image_truncated_ + i; | |||
} | } | |||
template <typename T> | template <typename T> | |||
template <typename STS> | ||||
void object_statements<T>:: | void object_statements<T>:: | |||
load_delayed_ () | load_delayed_ (const schema_version_migration* svm) | |||
{ | { | |||
database& db (connection ().database ()); | database& db (connection ().database ()); | |||
delayed_loads dls; | delayed_loads dls; | |||
swap_guard sg (*this, dls); | swap_guard sg (*this, dls); | |||
while (!dls.empty ()) | while (!dls.empty ()) | |||
{ | { | |||
delayed_load l (dls.back ()); | delayed_load l (dls.back ()); | |||
typename pointer_cache_traits::insert_guard ig (l.pos); | typename pointer_cache_traits::insert_guard ig (l.pos); | |||
dls.pop_back (); | dls.pop_back (); | |||
if (l.loader == 0) | if (l.loader == 0) | |||
{ | { | |||
if (!object_traits::find_ (*this, &l.id)) | object_traits_calls<T> tc (svm); | |||
if (!tc.find_ (static_cast<STS&> (*this), &l.id)) | ||||
throw object_not_persistent (); | throw object_not_persistent (); | |||
object_traits::callback (db, *l.obj, callback_event::pre_load); | object_traits::callback (db, *l.obj, callback_event::pre_load); | |||
// Our calls to init/load below can result in additional delayed | // Our calls to init/load below can result in additional delayed | |||
// loads being added to the delayed_ vector. We need to process | // loads being added to the delayed_ vector. We need to process | |||
// those before we call the post callback. | // those before we call the post callback. | |||
// | // | |||
object_traits::init (*l.obj, image (), &db); | tc.init (*l.obj, image (), &db); | |||
object_traits::load_ (*this, *l.obj); // Load containers, etc. | ||||
// Load containers, etc. | ||||
// | ||||
tc.load_ (static_cast<STS&> (*this), *l.obj, false); | ||||
if (!delayed_.empty ()) | if (!delayed_.empty ()) | |||
load_delayed_ (); | load_delayed_<STS> (svm); | |||
// Temporarily unlock the statement for the post_load call so tha t | // Temporarily unlock the statement for the post_load call so tha t | |||
// it can load objects of this type recursively. This is safe to do | // it can load objects of this type recursively. This is safe to do | |||
// because we have completely loaded the current object. Also the | // because we have completely loaded the current object. Also the | |||
// delayed_ list is clear before the unlock and should be clear o n | // delayed_ list is clear before the unlock and should be clear o n | |||
// re-lock (since a callback can only call public API functions | // re-lock (since a callback can only call public API functions | |||
// which will make sure all the delayed loads are processed befor e | // which will make sure all the delayed loads are processed befor e | |||
// returning). | // returning). | |||
// | // | |||
{ | { | |||
auto_unlock u (*this); | auto_unlock u (*this); | |||
object_traits::callback (db, *l.obj, callback_event::post_load) ; | object_traits::callback (db, *l.obj, callback_event::post_load) ; | |||
} | } | |||
} | } | |||
else | else | |||
l.loader (db, l.id, *l.obj); | l.loader (db, l.id, *l.obj, svm); | |||
pointer_cache_traits::load (ig.position ()); | pointer_cache_traits::load (ig.position ()); | |||
ig.release (); | ig.release (); | |||
} | } | |||
} | } | |||
template <typename T> | template <typename T> | |||
void object_statements<T>:: | void object_statements<T>:: | |||
clear_delayed_ () | clear_delayed_ () | |||
{ | { | |||
End of changes. 8 change blocks. | ||||
7 lines changed or deleted | 13 lines changed or added | |||
statement-cache.hxx | statement-cache.hxx | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
#include <odb/pgsql/details/export.hxx> | #include <odb/pgsql/details/export.hxx> | |||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
class LIBODB_PGSQL_EXPORT statement_cache | class LIBODB_PGSQL_EXPORT statement_cache | |||
{ | { | |||
public: | public: | |||
statement_cache (connection& conn): conn_ (conn) {} | statement_cache (connection& conn) | |||
: conn_ (conn), | ||||
version_seq_ (conn.database ().schema_version_sequence ()) {} | ||||
template <typename T> | template <typename T> | |||
typename object_traits_impl<T, id_pgsql>::statements_type& | typename object_traits_impl<T, id_pgsql>::statements_type& | |||
find_object (); | find_object (); | |||
template <typename T> | template <typename T> | |||
view_statements<T>& | view_statements<T>& | |||
find_view (); | find_view (); | |||
private: | private: | |||
typedef std::map<const std::type_info*, | typedef std::map<const std::type_info*, | |||
details::shared_ptr<statements_base>, | details::shared_ptr<statements_base>, | |||
details::type_info_comparator> map; | details::type_info_comparator> map; | |||
connection& conn_; | connection& conn_; | |||
unsigned int version_seq_; | ||||
map map_; | map map_; | |||
}; | }; | |||
} | } | |||
} | } | |||
#include <odb/pgsql/statement-cache.txx> | #include <odb/pgsql/statement-cache.txx> | |||
#include <odb/post.hxx> | #include <odb/post.hxx> | |||
#endif // ODB_PGSQL_STATEMENT_CACHE_HXX | #endif // ODB_PGSQL_STATEMENT_CACHE_HXX | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 4 lines changed or added | |||
statement-cache.txx | statement-cache.txx | |||
---|---|---|---|---|
// file : odb/pgsql/statement-cache.txx | // file : odb/pgsql/statement-cache.txx | |||
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#include <odb/pgsql/database.hxx> | ||||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
template <typename T> | template <typename T> | |||
typename object_traits_impl<T, id_pgsql>::statements_type& | typename object_traits_impl<T, id_pgsql>::statements_type& | |||
statement_cache:: | statement_cache:: | |||
find_object () | find_object () | |||
{ | { | |||
typedef | typedef | |||
typename object_traits_impl<T, id_pgsql>::statements_type | typename object_traits_impl<T, id_pgsql>::statements_type | |||
statements_type; | statements_type; | |||
// Clear the cache if the database version has changed. This | ||||
// makes sure we don't re-use statements that correspond to | ||||
// the old schema. | ||||
// | ||||
if (version_seq_ != conn_.database ().schema_version_sequence ()) | ||||
{ | ||||
map_.clear (); | ||||
version_seq_ = conn_.database ().schema_version_sequence (); | ||||
} | ||||
map::iterator i (map_.find (&typeid (T))); | map::iterator i (map_.find (&typeid (T))); | |||
if (i != map_.end ()) | if (i != map_.end ()) | |||
return static_cast<statements_type&> (*i->second); | return static_cast<statements_type&> (*i->second); | |||
details::shared_ptr<statements_type> p ( | details::shared_ptr<statements_type> p ( | |||
new (details::shared) statements_type (conn_)); | new (details::shared) statements_type (conn_)); | |||
map_.insert (map::value_type (&typeid (T), p)); | map_.insert (map::value_type (&typeid (T), p)); | |||
return *p; | return *p; | |||
} | } | |||
template <typename T> | template <typename T> | |||
view_statements<T>& statement_cache:: | view_statements<T>& statement_cache:: | |||
find_view () | find_view () | |||
{ | { | |||
// We don't cache any statements for views so no need to clear | ||||
// the cache. | ||||
map::iterator i (map_.find (&typeid (T))); | map::iterator i (map_.find (&typeid (T))); | |||
if (i != map_.end ()) | if (i != map_.end ()) | |||
return static_cast<view_statements<T>&> (*i->second); | return static_cast<view_statements<T>&> (*i->second); | |||
details::shared_ptr<view_statements<T> > p ( | details::shared_ptr<view_statements<T> > p ( | |||
new (details::shared) view_statements<T> (conn_)); | new (details::shared) view_statements<T> (conn_)); | |||
map_.insert (map::value_type (&typeid (T), p)); | map_.insert (map::value_type (&typeid (T), p)); | |||
return *p; | return *p; | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 15 lines changed or added | |||
statement.hxx | statement.hxx | |||
---|---|---|---|---|
skipping to change at line 53 | skipping to change at line 53 | |||
virtual const char* | virtual const char* | |||
text () const; | text () const; | |||
virtual connection_type& | virtual connection_type& | |||
connection () | connection () | |||
{ | { | |||
return conn_; | return conn_; | |||
} | } | |||
// A statement can be empty. This is used to handle situations | ||||
// where a SELECT or UPDATE statement ends up not having any | ||||
// columns after processing. An empty statement cannot be | ||||
// executed. | ||||
// | ||||
bool | ||||
empty () const | ||||
{ | ||||
return *text_ == '\0'; | ||||
} | ||||
void | void | |||
deallocate (); | deallocate (); | |||
// Adapt an ODB binding to a native PostgreSQL parameter binding. | // Adapt an ODB binding to a native PostgreSQL parameter binding. | |||
// | // | |||
static void | static void | |||
bind_param (native_binding&, const binding&); | bind_param (native_binding&, const binding&); | |||
// Populate an ODB binding given a PostgreSQL result. If the truncate d | // Populate an ODB binding given a PostgreSQL result. If the truncate d | |||
// argument is true, then only truncated columns are extracted. Retur n | // argument is true, then only truncated columns are extracted. Retur n | |||
skipping to change at line 74 | skipping to change at line 85 | |||
// more columns were truncated. | // more columns were truncated. | |||
// | // | |||
static bool | static bool | |||
bind_result (bind*, | bind_result (bind*, | |||
std::size_t count, | std::size_t count, | |||
PGresult*, | PGresult*, | |||
std::size_t row, | std::size_t row, | |||
bool truncated = false); | bool truncated = false); | |||
protected: | protected: | |||
// We keep two versions to take advantage of std::string COW. | ||||
// | ||||
statement (connection_type&, | statement (connection_type&, | |||
const std::string& name, | const std::string& name, | |||
const std::string& text, | const std::string& text, | |||
statement_kind, | ||||
const binding* process, | ||||
bool optimize, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count); | std::size_t types_count); | |||
statement (connection_type&, | statement (connection_type&, | |||
const char* name, | const char* name, | |||
const char* text, | const char* text, | |||
statement_kind, | ||||
const binding* process, | ||||
bool optimize, | ||||
bool copy_name_text, | bool copy_name_text, | |||
const Oid* types, | const Oid* types, | |||
std::size_t types_count); | std::size_t types_count); | |||
private: | private: | |||
void | void | |||
init (const Oid* types, std::size_t types_count); | init (statement_kind, | |||
const binding* process, | ||||
bool optimize, | ||||
const Oid* types, | ||||
std::size_t types_count); | ||||
protected: | protected: | |||
connection_type& conn_; | connection_type& conn_; | |||
std::string name_copy_; | std::string name_copy_; | |||
const char* name_; | const char* name_; | |||
std::string text_copy_; | std::string text_copy_; | |||
const char* text_; | const char* text_; | |||
skipping to change at line 113 | skipping to change at line 136 | |||
class LIBODB_PGSQL_EXPORT select_statement: public statement | class LIBODB_PGSQL_EXPORT select_statement: public statement | |||
{ | { | |||
public: | public: | |||
virtual | virtual | |||
~select_statement (); | ~select_statement (); | |||
select_statement (connection_type& conn, | select_statement (connection_type& conn, | |||
const std::string& name, | const std::string& name, | |||
const std::string& text, | const std::string& text, | |||
bool process_text, | ||||
bool optimize_text, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count, | std::size_t types_count, | |||
binding& param, | binding& param, | |||
native_binding& native_param, | native_binding& native_param, | |||
binding& result); | binding& result); | |||
select_statement (connection_type& conn, | select_statement (connection_type& conn, | |||
const char* name, | const char* name, | |||
const char* stmt, | const char* stmt, | |||
bool process_text, | ||||
bool optimize_text, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count, | std::size_t types_count, | |||
binding& param, | binding& param, | |||
native_binding& native_param, | native_binding& native_param, | |||
binding& result, | binding& result, | |||
bool copy_name_text = true); | bool copy_name_text = true); | |||
select_statement (connection_type& conn, | select_statement (connection_type& conn, | |||
const std::string& name, | const std::string& name, | |||
const std::string& text, | const std::string& text, | |||
bool process_text, | ||||
bool optimize_text, | ||||
binding& result); | binding& result); | |||
select_statement (connection_type& conn, | select_statement (connection_type& conn, | |||
const char* name, | const char* name, | |||
const char* text, | const char* text, | |||
bool process_text, | ||||
bool optimize_text, | ||||
binding& result, | binding& result, | |||
bool copy_name_text = true); | bool copy_name_text = true); | |||
select_statement (connection_type& conn, | select_statement (connection_type& conn, | |||
const std::string& name, | const std::string& name, | |||
const std::string& text, | const std::string& text, | |||
bool process_text, | ||||
bool optimize_text, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count, | std::size_t types_count, | |||
native_binding& native_param, | native_binding& native_param, | |||
binding& result); | binding& result); | |||
// Common select interface expected by the generated code. | // Common select interface expected by the generated code. | |||
// | // | |||
public: | public: | |||
enum result | enum result | |||
{ | { | |||
skipping to change at line 243 | skipping to change at line 276 | |||
class LIBODB_PGSQL_EXPORT insert_statement: public statement | class LIBODB_PGSQL_EXPORT insert_statement: public statement | |||
{ | { | |||
public: | public: | |||
virtual | virtual | |||
~insert_statement (); | ~insert_statement (); | |||
insert_statement (connection_type& conn, | insert_statement (connection_type& conn, | |||
const std::string& name, | const std::string& name, | |||
const std::string& text, | const std::string& text, | |||
bool process_text, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count, | std::size_t types_count, | |||
binding& param, | binding& param, | |||
native_binding& native_param, | native_binding& native_param, | |||
bool returning); | bool returning); | |||
insert_statement (connection_type& conn, | insert_statement (connection_type& conn, | |||
const char* name, | const char* name, | |||
const char* text, | const char* text, | |||
bool process_text, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count, | std::size_t types_count, | |||
binding& param, | binding& param, | |||
native_binding& native_param, | native_binding& native_param, | |||
bool returning, | bool returning, | |||
bool copy_name_text = true); | bool copy_name_text = true); | |||
// Return true if successful and false if the row is a duplicate. | // Return true if successful and false if the row is a duplicate. | |||
// All other errors are reported by throwing exceptions. | // All other errors are reported by throwing exceptions. | |||
// | // | |||
skipping to change at line 292 | skipping to change at line 327 | |||
class LIBODB_PGSQL_EXPORT update_statement: public statement | class LIBODB_PGSQL_EXPORT update_statement: public statement | |||
{ | { | |||
public: | public: | |||
virtual | virtual | |||
~update_statement (); | ~update_statement (); | |||
update_statement (connection_type& conn, | update_statement (connection_type& conn, | |||
const std::string& name, | const std::string& name, | |||
const std::string& text, | const std::string& text, | |||
bool process_text, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count, | std::size_t types_count, | |||
binding& param, | binding& param, | |||
native_binding& native_param); | native_binding& native_param); | |||
update_statement (connection_type& conn, | update_statement (connection_type& conn, | |||
const char* name, | const char* name, | |||
const char* text, | const char* text, | |||
bool process_text, | ||||
const Oid* types, | const Oid* types, | |||
std::size_t types_count, | std::size_t types_count, | |||
binding& param, | binding& param, | |||
native_binding& native_param, | native_binding& native_param, | |||
bool copy_name_text = true); | bool copy_name_text = true); | |||
unsigned long long | unsigned long long | |||
execute (); | execute (); | |||
private: | private: | |||
End of changes. 14 change blocks. | ||||
1 lines changed or deleted | 38 lines changed or added | |||
statements-base.hxx | statements-base.hxx | |||
---|---|---|---|---|
// file : odb/pgsql/statements-base.hxx | // file : odb/pgsql/statements-base.hxx | |||
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#ifndef ODB_PGSQL_STATEMENTS_BASE_HXX | #ifndef ODB_PGSQL_STATEMENTS_BASE_HXX | |||
#define ODB_PGSQL_STATEMENTS_BASE_HXX | #define ODB_PGSQL_STATEMENTS_BASE_HXX | |||
#include <odb/pre.hxx> | #include <odb/pre.hxx> | |||
#include <odb/schema-version.hxx> | ||||
#include <odb/details/shared-ptr.hxx> | #include <odb/details/shared-ptr.hxx> | |||
#include <odb/pgsql/version.hxx> | #include <odb/pgsql/version.hxx> | |||
#include <odb/pgsql/forward.hxx> // connection | #include <odb/pgsql/connection.hxx> | |||
#include <odb/pgsql/database.hxx> | ||||
#include <odb/pgsql/details/export.hxx> | #include <odb/pgsql/details/export.hxx> | |||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
class LIBODB_PGSQL_EXPORT statements_base: public details::shared_base | class LIBODB_PGSQL_EXPORT statements_base: public details::shared_base | |||
{ | { | |||
public: | public: | |||
typedef pgsql::connection connection_type; | typedef pgsql::connection connection_type; | |||
connection_type& | connection_type& | |||
connection () | connection () | |||
{ | { | |||
return conn_; | return conn_; | |||
} | } | |||
// Schema version. database::schema_version_migration() is thread- | ||||
// safe which means it is also slow. Cache the result in statements | ||||
// so we can avoid the mutex lock. This is thread-safe since if the | ||||
// version is updated, then the statements cache will be expired. | ||||
// | ||||
const schema_version_migration& | ||||
version_migration (const char* name = "") const | ||||
{ | ||||
if (svm_ == 0) | ||||
svm_ = &conn_.database ().schema_version_migration (name); | ||||
return *svm_; | ||||
} | ||||
public: | public: | |||
virtual | virtual | |||
~statements_base (); | ~statements_base (); | |||
protected: | protected: | |||
statements_base (connection_type& conn) | statements_base (connection_type& conn): conn_ (conn), svm_ (0) {} | |||
: conn_ (conn) | ||||
{ | ||||
} | ||||
protected: | protected: | |||
connection_type& conn_; | connection_type& conn_; | |||
mutable const schema_version_migration* svm_; | ||||
}; | }; | |||
} | } | |||
} | } | |||
#include <odb/post.hxx> | #include <odb/post.hxx> | |||
#endif // ODB_PGSQL_STATEMENTS_BASE_HXX | #endif // ODB_PGSQL_STATEMENTS_BASE_HXX | |||
End of changes. 5 change blocks. | ||||
5 lines changed or deleted | 19 lines changed or added | |||
transaction.hxx | transaction.hxx | |||
---|---|---|---|---|
skipping to change at line 31 | skipping to change at line 31 | |||
{ | { | |||
class transaction_impl; | class transaction_impl; | |||
class LIBODB_PGSQL_EXPORT transaction: public odb::transaction | class LIBODB_PGSQL_EXPORT transaction: public odb::transaction | |||
{ | { | |||
public: | public: | |||
typedef pgsql::database database_type; | typedef pgsql::database database_type; | |||
typedef pgsql::connection connection_type; | typedef pgsql::connection connection_type; | |||
explicit | explicit | |||
transaction (transaction_impl*); | transaction (transaction_impl*, bool make_current = true); | |||
transaction (); | ||||
// Return the database this transaction is on. | // Return the database this transaction is on. | |||
// | // | |||
database_type& | database_type& | |||
database (); | database (); | |||
// Return the underlying database connection for this transaction. | // Return the underlying database connection for this transaction. | |||
// | // | |||
connection_type& | connection_type& | |||
connection (); | connection (); | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 3 lines changed or added | |||
transaction.ixx | transaction.ixx | |||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#include <odb/pgsql/database.hxx> | #include <odb/pgsql/database.hxx> | |||
#include <odb/pgsql/transaction-impl.hxx> | #include <odb/pgsql/transaction-impl.hxx> | |||
namespace odb | namespace odb | |||
{ | { | |||
namespace pgsql | namespace pgsql | |||
{ | { | |||
inline transaction:: | inline transaction:: | |||
transaction (transaction_impl* impl) | transaction (transaction_impl* impl, bool make_current) | |||
: odb::transaction (impl) | : odb::transaction (impl, make_current) | |||
{ | ||||
} | ||||
inline transaction:: | ||||
transaction () | ||||
: odb::transaction () | ||||
{ | { | |||
} | } | |||
inline transaction_impl& transaction:: | inline transaction_impl& transaction:: | |||
implementation () | implementation () | |||
{ | { | |||
// We can use static_cast here since we have an instance of | // We can use static_cast here since we have an instance of | |||
// pgsql::transaction. | // pgsql::transaction. | |||
// | // | |||
return static_cast<transaction_impl&> ( | return static_cast<transaction_impl&> ( | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 8 lines changed or added | |||
version.hxx | version.hxx | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
// Version AABBCCDD | // Version AABBCCDD | |||
// 2.0.0 02000000 | // 2.0.0 02000000 | |||
// 2.1.0 02010000 | // 2.1.0 02010000 | |||
// 2.1.1 02010100 | // 2.1.1 02010100 | |||
// 2.2.0.a1 02019901 | // 2.2.0.a1 02019901 | |||
// 3.0.0.b2 02999952 | // 3.0.0.b2 02999952 | |||
// | // | |||
// Check that we have compatible ODB version. | // Check that we have compatible ODB version. | |||
// | // | |||
#if ODB_VERSION != 20200 | #if ODB_VERSION != 20300 | |||
# error incompatible odb interface version detected | # error incompatible odb interface version detected | |||
#endif | #endif | |||
// libodb-pgsql version: odb interface version plus the bugfix | // libodb-pgsql version: odb interface version plus the bugfix | |||
// version. | // version. | |||
// | // | |||
#define LIBODB_PGSQL_VERSION 2020000 | #define LIBODB_PGSQL_VERSION 2030000 | |||
#define LIBODB_PGSQL_VERSION_STR "2.2.0" | #define LIBODB_PGSQL_VERSION_STR "2.3.0" | |||
#include <odb/post.hxx> | #include <odb/post.hxx> | |||
#endif // ODB_PGSQL_VERSION_HXX | #endif // ODB_PGSQL_VERSION_HXX | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 3 lines changed or added | |||
view-result.hxx | view-result.hxx | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC | |||
// license : GNU GPL v2; see accompanying LICENSE file | // license : GNU GPL v2; see accompanying LICENSE file | |||
#ifndef ODB_PGSQL_VIEW_RESULT_HXX | #ifndef ODB_PGSQL_VIEW_RESULT_HXX | |||
#define ODB_PGSQL_VIEW_RESULT_HXX | #define ODB_PGSQL_VIEW_RESULT_HXX | |||
#include <odb/pre.hxx> | #include <odb/pre.hxx> | |||
#include <cstddef> // std::size_t | #include <cstddef> // std::size_t | |||
#include <odb/schema-version.hxx> | ||||
#include <odb/view-result.hxx> | #include <odb/view-result.hxx> | |||
#include <odb/details/shared-ptr.hxx> | #include <odb/details/shared-ptr.hxx> | |||
#include <odb/pgsql/version.hxx> | #include <odb/pgsql/version.hxx> | |||
#include <odb/pgsql/forward.hxx> // query_base, view_statements | #include <odb/pgsql/forward.hxx> // query_base, view_statements | |||
#include <odb/pgsql/statement.hxx> | #include <odb/pgsql/statement.hxx> | |||
namespace odb | namespace odb | |||
{ | { | |||
skipping to change at line 43 | skipping to change at line 44 | |||
typedef view_traits_impl<view_type, id_pgsql> view_traits; | typedef view_traits_impl<view_type, id_pgsql> view_traits; | |||
typedef typename base_type::pointer_traits pointer_traits; | typedef typename base_type::pointer_traits pointer_traits; | |||
typedef view_statements<view_type> statements_type; | typedef view_statements<view_type> statements_type; | |||
virtual | virtual | |||
~view_result_impl (); | ~view_result_impl (); | |||
view_result_impl (const query_base&, | view_result_impl (const query_base&, | |||
details::shared_ptr<select_statement>, | details::shared_ptr<select_statement>, | |||
statements_type&); | statements_type&, | |||
const schema_version_migration*); | ||||
virtual void | virtual void | |||
load (view_type&); | load (view_type&); | |||
virtual void | virtual void | |||
next (); | next (); | |||
virtual void | virtual void | |||
cache (); | cache (); | |||
skipping to change at line 65 | skipping to change at line 67 | |||
size (); | size (); | |||
virtual void | virtual void | |||
invalidate (); | invalidate (); | |||
using base_type::current; | using base_type::current; | |||
private: | private: | |||
details::shared_ptr<select_statement> statement_; | details::shared_ptr<select_statement> statement_; | |||
statements_type& statements_; | statements_type& statements_; | |||
view_traits_calls<view_type> tc_; | ||||
std::size_t count_; | std::size_t count_; | |||
}; | }; | |||
} | } | |||
} | } | |||
#include <odb/pgsql/view-result.txx> | #include <odb/pgsql/view-result.txx> | |||
#include <odb/post.hxx> | #include <odb/post.hxx> | |||
#endif // ODB_PGSQL_VIEW_RESULT_HXX | #endif // ODB_PGSQL_VIEW_RESULT_HXX | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 4 lines changed or added | |||
view-result.txx | view-result.txx | |||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
this->end_ = true; | this->end_ = true; | |||
} | } | |||
statement_.reset (); | statement_.reset (); | |||
} | } | |||
template <typename T> | template <typename T> | |||
view_result_impl<T>:: | view_result_impl<T>:: | |||
view_result_impl (const query_base&, | view_result_impl (const query_base&, | |||
details::shared_ptr<select_statement> statement, | details::shared_ptr<select_statement> statement, | |||
statements_type& statements) | statements_type& statements, | |||
const schema_version_migration* svm) | ||||
: base_type (statements.connection ()), | : base_type (statements.connection ()), | |||
statement_ (statement), | statement_ (statement), | |||
statements_ (statements), | statements_ (statements), | |||
tc_ (svm), | ||||
count_ (0) | count_ (0) | |||
{ | { | |||
} | } | |||
template <typename T> | template <typename T> | |||
void view_result_impl<T>:: | void view_result_impl<T>:: | |||
load (view_type& view) | load (view_type& view) | |||
{ | { | |||
// The image can grow between calls to load() as a result of other | // The image can grow between calls to load() as a result of other | |||
// statements execution. | // statements execution. | |||
// | // | |||
typename view_traits::image_type& im (statements_.image ()); | typename view_traits::image_type& im (statements_.image ()); | |||
if (im.version != statements_.image_version ()) | if (im.version != statements_.image_version ()) | |||
{ | { | |||
binding& b (statements_.image_binding ()); | binding& b (statements_.image_binding ()); | |||
view_traits::bind (b.bind, im); | tc_.bind (b.bind, im); | |||
statements_.image_version (im.version); | statements_.image_version (im.version); | |||
b.version++; | b.version++; | |||
} | } | |||
select_statement::result r (statement_->load ()); | select_statement::result r (statement_->load ()); | |||
if (r == select_statement::truncated) | if (r == select_statement::truncated) | |||
{ | { | |||
if (view_traits::grow (im, statements_.image_truncated ())) | if (tc_.grow (im, statements_.image_truncated ())) | |||
im.version++; | im.version++; | |||
if (im.version != statements_.image_version ()) | if (im.version != statements_.image_version ()) | |||
{ | { | |||
binding& b (statements_.image_binding ()); | binding& b (statements_.image_binding ()); | |||
view_traits::bind (b.bind, im); | tc_.bind (b.bind, im); | |||
statements_.image_version (im.version); | statements_.image_version (im.version); | |||
b.version++; | b.version++; | |||
statement_->reload (); | statement_->reload (); | |||
} | } | |||
} | } | |||
view_traits::callback (this->db_, view, callback_event::pre_load); | view_traits::callback (this->db_, view, callback_event::pre_load); | |||
view_traits::init (view, im, &this->db_); | tc_.init (view, im, &this->db_); | |||
view_traits::callback (this->db_, view, callback_event::post_load); | view_traits::callback (this->db_, view, callback_event::post_load); | |||
} | } | |||
template <typename T> | template <typename T> | |||
void view_result_impl<T>:: | void view_result_impl<T>:: | |||
next () | next () | |||
{ | { | |||
this->current (pointer_type ()); | this->current (pointer_type ()); | |||
if (statement_->next ()) | if (statement_->next ()) | |||
End of changes. 6 change blocks. | ||||
5 lines changed or deleted | 7 lines changed or added | |||