From boris at codesynthesis.com Thu Mar 1 04:05:02 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Mar 1 03:57:40 2012 Subject: [odb-users] "Dynamic" joins in views In-Reply-To: References: Message-ID: Hi Nicolas, Nicolas ALBEZA writes: > I was wondering if it was possible to do "dynamic" joins in views, for > example, to be able to specify a join condition at runtime, without using > native queries. Hm, you could try providing a native predicate that includes a reference to a global (or class-static, or even a TLS, if your compiler supports this mechanism) variable: extern int param; #pragma db view \ object(t1) \ object(t2: "t1.id = t2.t1_id AND t2.t3_id =" + odb::query::_ref (param)) struct view { ... }; > Result SQL query example: > > select field from t1 left join t2 on (t1.id = t2.t1_id && t2.t3_id = > ); Isn't this equivalent to: select field from t1 left join t2 on t1.id = t2.t1_id where t2.t3_id = ? If you can rewrite the query like this, then you don't need any of the above and can use C++-integrated queries. Boris From n.albeza at gmail.com Thu Mar 1 10:54:14 2012 From: n.albeza at gmail.com (Nicolas ALBEZA) Date: Thu Mar 1 10:54:22 2012 Subject: [odb-users] "Dynamic" joins in views In-Reply-To: References: Message-ID: I managed to rewrite the query using C++-integrated queries, and it's working like a charm. Many thanks ! Le 1 mars 2012 10:05, Boris Kolpackov a ?crit : > Hi Nicolas, > > Nicolas ALBEZA writes: > > > I was wondering if it was possible to do "dynamic" joins in views, for > > example, to be able to specify a join condition at runtime, without using > > native queries. > > Hm, you could try providing a native predicate that includes a reference > to a global (or class-static, or even a TLS, if your compiler supports > this mechanism) variable: > > extern int param; > > #pragma db view \ > object(t1) \ > object(t2: "t1.id = t2.t1_id AND t2.t3_id =" + odb::query::_ref > (param)) > struct view > { > ... > }; > > > Result SQL query example: > > > > select field from t1 left join t2 on (t1.id = t2.t1_id && t2.t3_id = > > ); > > Isn't this equivalent to: > > select field from t1 left join t2 on t1.id = t2.t1_id where t2.t3_id = ? > > If you can rewrite the query like this, then you don't need any of the > above and can use C++-integrated queries. > > Boris > -- ALBEZA "Pause" Nicolas From ashaihullin at gmail.com Fri Mar 2 03:35:05 2012 From: ashaihullin at gmail.com (Artur Shaihullin) Date: Fri Mar 2 03:35:14 2012 Subject: [odb-users] Segmentation fault on persist with bidirect QString foreign key Message-ID: Hello. I have a problem with code (as in attache). On persist operation of second row of the table i have SegFault error in qstring-traits.hxx(39). First persist is going ok. Database: sqlite3 --version 3.7.8 2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177 Qt 4.8.0 for GCC gcc --version gcc (SUSE Linux) 4.6.2 uname -a Linux linux-desktop.kg 3.1.0-1.2-desktop #1 SMP PREEMPT Thu Nov 3 14:45:45 UTC 2011 (187dde0) i686 i686 i386 GNU/Linux /opt/odb/bin/odb --version ODB object-relational mapping (ORM) compiler for C++ 1.8.0 I'm just wonder, do I anything wrong? -- Best Regards, Artur Shain -------------- next part -------------- A non-text attachment was scrubbed... Name: testcaseodb.tar.gz Type: application/x-gzip Size: 2144 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20120302/70911cb5/testcaseodb.tar.bin From ashaihullin at gmail.com Fri Mar 2 04:24:49 2012 From: ashaihullin at gmail.com (Artur Shaihullin) Date: Fri Mar 2 04:24:58 2012 Subject: [odb-users] Re: Segmentation fault on persist with bidirect QString foreign key In-Reply-To: References: Message-ID: Forget about that. My fault, I didn't use session. 2012/3/2 Artur Shaihullin > Hello. > I have a problem with code (as in attache). On persist operation of second > row of the table i have SegFault error in qstring-traits.hxx(39). First > persist is going ok. > > Database: > sqlite3 --version > 3.7.8 2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177 > > Qt 4.8.0 for GCC > > gcc --version > gcc (SUSE Linux) 4.6.2 > > uname -a > Linux linux-desktop.kg 3.1.0-1.2-desktop #1 SMP PREEMPT Thu Nov 3 > 14:45:45 UTC 2011 (187dde0) i686 i686 i386 GNU/Linux > > /opt/odb/bin/odb --version > ODB object-relational mapping (ORM) compiler for C++ 1.8.0 > > I'm just wonder, do I anything wrong? > -- > Best Regards, > Artur Shain > > -- Best Regards, Artur Shain From boris at codesynthesis.com Tue Mar 6 04:53:39 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Mar 6 04:47:40 2012 Subject: [odb-users] Segmentation fault on persist with bidirect QString foreign key In-Reply-To: References: Message-ID: Hi Artur, Thanks for the test. I took a look, and, yes, you are correct, you need to use a session. I also made ODB detect this situation and throw the odb::session_required exception. This will be available in the next release. Boris From boris at codesynthesis.com Wed Mar 7 05:18:32 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Mar 7 05:12:34 2012 Subject: [odb-users] ODB 1.9.0.a1 available Message-ID: Hi, The first alpha version for the upcoming ODB 1.9.0 is now available. The NEWS file entries so far are: * Support for C++11. Some of the newly supported C++11 standard library components include: - std::unique_ptr as object pointer or value wrapper - odb::lazy_unique_ptr lazy counterpart - std::shared_ptr/weak_ptr as object pointer or value wrapper - odb::lazy_shared_ptr/lazy_weak_ptr lazy counterparts - support for array, forward_list, and unordered containers - connection factory can be passed to the database constructor as std::unique_ptr instead of std::auto_ptr The ODB compiler now recognizes the --std option. Valid values for this option are 'c++98' (default) and 'c++11'. In the runtime libraries the C++11 support is header-only which means that the same build of a runtime library can be used in both the C++98 and C++11 modes. On UNIX, the tests and examples can be compiled in the C++11 mode by passing the necessary options to turn the C++ compiler into this mode (e.g., -std=c++0x GCC option). On Windows, the tests and examples are always built in the C++11 mode with VC++ 10 and later. The new 'c++11' example shows ODB support for some of the C++11 features. * Support for composite object ids. Now a composite value type can be used to declare an object id member. For more information, refer to Section 7.2.1, "Composite Object Ids" in the ODB manual as well as the 'composite' example in the odb-examples package. * New schema format (--schema-format), 'separate', allows the generation of the schema creation code into a separate C++ source file (called 'name-schema.cxx' by default). This value is primarily useful if you want to place the schema creation functionality into a separate program or library. * New namespace-level pragmas: table, pointer. The table pragma specifies the table prefix that is added to table names for all the persistent classes inside a namespace. The pointer pragma specifies the default pointer type to be used for persistent classes and views inside a namespace. For more information, refer to Section 12.5.1, "pointer" and Section 12.5.2, "table" in the ODB manual. * New exception, odb::session_required, is thrown when ODB detects that correctly loading a bidirectional object relationship requires a session but one is not used. For more information, refer to Section 6.2, "Bidirectional Relationships" in the ODB manual. This pre-release is available from: http://www.codesynthesis.com/download/odb/pre-release/ The ODB compiler binaries are only provided for Windows, and GNU/Linux x86_64. The SHA1 sums for all the files in this pre-release are provided at the end of the email. Testing and feedback are much appreciated. 5ab1b47d27630a7706a9582d204f657f05206e1c libodb-1.9.0.a1.tar.bz2 5905f7ab38391d31de142114ad4b5511b12e43ff libodb-1.9.0.a1.tar.gz bc52f280ac2e97e394acefeec3bc12c2bd44e61f libodb-1.9.0.a1.zip 10fb5ad6b857a678a06b6438f22c65cc370f6d5e libodb-boost-1.9.0.a1.tar.bz2 67ee52a192f949a1cdd5167ec19c977ac7e23064 libodb-boost-1.9.0.a1.tar.gz 433bbf9ac4947a2a72fba98184f815a6b969ea91 libodb-boost-1.9.0.a1.zip 3a283b60004cb6f88f62f2811e11805b25768a7a libodb-mssql-1.9.0.a1.tar.bz2 dc502f256610f7136cb3f3346ae9f00525211055 libodb-mssql-1.9.0.a1.tar.gz b8b2caad1b38e85f11b9f96d6c9485f6e7d04e01 libodb-mssql-1.9.0.a1.zip 47d2d6c40efa3721f5f408fa080eb219bb8a8537 libodb-mysql-1.9.0.a1.tar.bz2 94ec8033ce7777fe789397cd04f6a68e98a2b51e libodb-mysql-1.9.0.a1.tar.gz 0939cfae49942f36578ff628c90f0adaf964ac62 libodb-mysql-1.9.0.a1.zip 8a8e59dea00d138ad16c674304dab495e6b1f6ad libodb-oracle-1.9.0.a1.tar.bz2 35b872e982d3a53812ed0b660aa87407d0fbec41 libodb-oracle-1.9.0.a1.tar.gz ba731ef4cdaee3ba4468b7be46ab3ba56944028a libodb-oracle-1.9.0.a1.zip 707c4d261f7bbc84cbe7164e02e5d8f78ae1ebcb libodb-pgsql-1.9.0.a1.tar.bz2 bc0349f2608c10a450699d3ea95b715b0bf97631 libodb-pgsql-1.9.0.a1.tar.gz 06308e06145e6cc2142e30358e71a3d4e4cdc2bb libodb-pgsql-1.9.0.a1.zip 6ef12a2e068246420d14ccaa2253f088913f6f0f libodb-qt-1.9.0.a1.tar.bz2 59b78f1c13cafd52272113ea43ce10ee90eb259e libodb-qt-1.9.0.a1.tar.gz ae36cda3ec4a1a189daa1470b694979577c3caef libodb-qt-1.9.0.a1.zip 27851e2283eaff56c8b081b38a5977c601f11464 libodb-sqlite-1.9.0.a1.tar.bz2 d20a7bef796f253b5486218ad200875d075e32b8 libodb-sqlite-1.9.0.a1.tar.gz d2a8d3e71be179ee3e641a08d05387f9c3aa9021 libodb-sqlite-1.9.0.a1.zip afdb91f840b9c83b3f8b07f4f4fb341c3b4225b7 odb-1.9.0.a1-i686-windows.zip 71a8884585dfa168d524bb30f4c9035c07f5e48a odb-1.9.0.a1.tar.bz2 8cab76a79f77cfd8eaffd1fb837d8d168f3ea03c odb-1.9.0.a1.tar.gz a47b2ca7ac6d6977f163692ace96c4bba1b30cb1 odb-1.9.0.a1-x86_64-linux-gnu.tar.bz2 67c11f10871de3919773c39542a040973da8a59a odb-1.9.0.a1.zip 111f1fd877e933940efd15402e278da82fa9cf5c odb-examples-1.9.0.a1.tar.bz2 5cac5364d9f3f0e7c0842edd9b14f6f0d072ab25 odb-examples-1.9.0.a1.tar.gz 988bfc21a5256b8433d24fed783baa808d413e2c odb-examples-1.9.0.a1.zip c732784b7b8fcc4d4fd02beaa1e37e9aeafed6e0 odb-tests-1.9.0.a1.tar.bz2 30c4ee385c46874027f6fa254feb8b2518caf0de odb-tests-1.9.0.a1.tar.gz 49192eb05d4024fe81a0f0bd16a1e05dd7ddce81 odb-tests-1.9.0.a1.zip Enjoys, Boris From hacklew at hotmail.com Tue Mar 13 00:02:53 2012 From: hacklew at hotmail.com (Wayne Hackle) Date: Tue Mar 13 01:45:35 2012 Subject: [odb-users] Problem: odb.exe fails to generate valid hxx/cxx file, not adding shared_ptr in typedef Message-ID: Hi all, Thanks for taking time on reading this post. problem: odb.exe does not correctly implement "inverse" #pragma keyword in generating -odb.hxx/-odb.cxx files, and in turn causes VISUAL STUDIO failure to build. My problem occurs when I was trying out the "inverse" keyword in one-to-many relationships. My own project fails so I resort to the samples that I downloaded from the official website. The "inverse" sample runs correctly without changes. So I dug a bit deeper, ran "odb --database mysql --generate-query employee.hxx", then the project fails to build. error message: error C2679: binary "=": cannot find right operator that accpets "employee *" as a right oprant (this is a translation from the original chinese message: ?? 1 error C2679: ????=?: ???????employee *????????????(?????????) e:\all.files\library\odb\libodb\odb\tr1\lazy-ptr.ixx 540 inverse)So i compared the newly generated employee-odb.cxx/employee-odb.hxx file with the old ones. here are the differencesFile:Position (row number):Valid codeInvalid codeEmployee-odb.hxx743typedef ::std::tr1::shared_ptr< ::employee > pointer_type;typedef ::employee* pointer_type;Employee-odb.hxx469typedef ::std::tr1::shared_ptr< ::project > pointer_type;typedef ::project* pointer_type;Employee-odb.hxx311 typedef ::std::tr1::shared_ptr< ::position > pointer_type; typedef ::position* pointer_type;Employee-odb.hxx85typedef ::std::tr1::shared_ptr< ::employer > pointer_type;typedef ::employer* pointer_type;Employee-odb.cxx43-44"`inverse_employee`.`id`" " FROM `inverse_employee` WHERE `inverse_employee`.`employer`=?";"`inverse_employee`.`id`" " FROM `inverse_employee` WHERE `inverse_employee`.`employer`=?"; Much more likes as above, basically valid file with ?inverse_? prefix but invalid file without. I did not make any changes to the "employee.hxx" file in the "inverse" example, so I think it's either a problem with the "odb.exe" command, or there is a secret parameter that I fail to use. Did anyone run into the same/similar problem? Any information is appreciated. Thanks. Hackle Wayne -------------- next part -------------- // This file was generated by ODB, object-relational mapping (ORM) // compiler for C++. // #include // Begin prologue. // // // End prologue. #include "employee-odb.hxx" #include #include // std::memcpy #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace odb { // employer // // employees_ // const char access::object_traits< ::employer >::employees_traits::select_all_statement[] = "SELECT " "`employee`.`id`" " FROM `employee` WHERE `employee`.`employer`=?"; const char access::object_traits< ::employer >::employees_traits::insert_one_statement[] = ""; const char access::object_traits< ::employer >::employees_traits::delete_all_statement[] = ""; void access::object_traits< ::employer >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, cond_image_type& c) { ODB_POTENTIALLY_UNUSED (c); std::size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; } void access::object_traits< ::employer >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, data_image_type& d) { using namespace mysql; statement_kind sk (statement_select); ODB_POTENTIALLY_UNUSED (sk); size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; // value // b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &d.value_value; b[n].is_null = &d.value_null; } void access::object_traits< ::employer >::employees_traits:: grow (data_image_type& i, my_bool* t) { bool grew (false); // value // t[0UL] = 0; if (grew) i.version++; } void access::object_traits< ::employer >::employees_traits:: init (value_type& v, const data_image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (db); // value // { typedef object_traits< ::employee > obj_traits; typedef pointer_traits< value_type > ptr_traits; if (i.value_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.value_value, i.value_null); v = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::employer >::employees_traits:: insert_one (index_type, const value_type&, void*) { } bool access::object_traits< ::employer >::employees_traits:: load_all (index_type&, value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); data_image_type& di (sts.data_image ()); init (v, di, sts.connection ().database ()); select_statement& st (sts.select_all_statement ()); select_statement::result r (st.fetch ()); if (r == select_statement::no_data) { st.free_result (); return false; } return true; } void access::object_traits< ::employer >::employees_traits:: delete_all (void*) { } void access::object_traits< ::employer >::employees_traits:: load (container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } select_statement& st (sts.select_all_statement ()); st.execute (); select_statement::result r (st.fetch ()); bool more (r != select_statement::no_data); if (!more) st.free_result (); sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::load (c, more, fs); } access::object_traits< ::employer >::id_type access::object_traits< ::employer >:: id (const image_type& i) { id_type id; mysql::value_traits< ::std::string, mysql::id_string >::set_value ( id, i.name_value, i.name_size, i.name_null); return id; } bool access::object_traits< ::employer >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // name_ // if (t[0UL]) { i.name_value.capacity (i.name_size); grew = true; } return grew; } void access::object_traits< ::employer >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // name_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.name_value.data (); b[n].buffer_length = static_cast ( i.name_value.capacity ()); b[n].length = &i.name_size; b[n].is_null = &i.name_null; n++; } } void access::object_traits< ::employer >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.id_value.data (); b[n].buffer_length = static_cast ( i.id_value.capacity ()); b[n].length = &i.id_size; b[n].is_null = &i.id_null; } bool access::object_traits< ::employer >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // name_ // if (sk == statement_insert) { bool is_null; std::size_t size (0); std::size_t cap (i.name_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.name_value, size, is_null, o.name_); i.name_size = static_cast (size); grew = grew || (cap != i.name_value.capacity ()); i.name_null = is_null; } return grew; } void access::object_traits< ::employer >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // name_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.name_, i.name_value, i.name_size, i.name_null); } void access::object_traits< ::employer >:: init (id_image_type& i, const id_type& id) { bool grew (false); { bool is_null; std::size_t size (0); std::size_t cap (i.id_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.id_value, size, is_null, id); i.id_size = static_cast (size); grew = grew || (cap != i.id_value.capacity ()); i.id_null = is_null; } if (grew) i.version++; } struct access::object_traits< ::employer >::container_statement_cache_type { mysql::container_statements_impl< employees_traits > employees_; container_statement_cache_type (mysql::connection& c) : employees_ (c) { } }; const char access::object_traits< ::employer >::persist_statement[] = "INSERT INTO `employer` (" "`name`)" " VALUES (?)"; const char access::object_traits< ::employer >::find_statement[] = "SELECT " "`employer`.`name`" " FROM `employer`" " WHERE `employer`.`name`=?"; const char access::object_traits< ::employer >::erase_statement[] = "DELETE FROM `employer`" " WHERE `name`=?"; const char access::object_traits< ::employer >::query_statement[] = "SELECT " "`employer`.`name`" " FROM `employer`" " "; const char access::object_traits< ::employer >::erase_query_statement[] = "DELETE FROM `employer`" " "; const char access::object_traits< ::employer >::table_name[] = "`employer`"; void access::object_traits< ::employer >:: persist (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); } void access::object_traits< ::employer >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); if (!find_ (sts, obj.name_)) throw object_not_persistent (); } void access::object_traits< ::employer >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::employer >::pointer_type access::object_traits< ::employer >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::employer >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::employer >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.name_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::employer >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } void access::object_traits< ::employer >:: load_ (mysql::object_statements< object_type >& sts, object_type& obj) { mysql::binding& idb (sts.id_image_binding ()); employees_traits::load ( obj.employees_, idb, sts.container_statment_cache ().employees_); } result< access::object_traits< ::employer >::object_type > access::object_traits< ::employer >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::employer >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } // position // const char query_columns_base< ::position >::employee_alias_[] = "`employee`"; const query_columns_base< ::position >::employee_type_ query_columns_base< ::position >::employee; access::object_traits< ::position >::id_type access::object_traits< ::position >:: id (const image_type& i) { id_type id; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( id, i.id_value, i.id_null); return id; } bool access::object_traits< ::position >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // id_ // t[0UL] = 0; // title_ // if (t[1UL]) { i.title_value.capacity (i.title_size); grew = true; } // employee_ // t[2UL] = 0; return grew; } void access::object_traits< ::position >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // id_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; n++; } // title_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.title_value.data (); b[n].buffer_length = static_cast ( i.title_value.capacity ()); b[n].length = &i.title_size; b[n].is_null = &i.title_null; n++; // employee_ // if (sk == statement_select) { b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.employee_value; b[n].is_null = &i.employee_null; n++; } } void access::object_traits< ::position >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; } bool access::object_traits< ::position >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // id_ // if (sk == statement_insert) { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, o.id_); i.id_null = is_null; } // title_ // { bool is_null; std::size_t size (0); std::size_t cap (i.title_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.title_value, size, is_null, o.title_); i.title_size = static_cast (size); grew = grew || (cap != i.title_value.capacity ()); i.title_null = is_null; } return grew; } void access::object_traits< ::position >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // id_ // mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( o.id_, i.id_value, i.id_null); // title_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.title_, i.title_value, i.title_size, i.title_null); // employee_ // { typedef object_traits< ::employee > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_weak_ptr< ::employee > > ptr_traits; if (i.employee_null) o.employee_ = ptr_traits::pointer_type (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.employee_value, i.employee_null); o.employee_ = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::position >:: init (id_image_type& i, const id_type& id) { { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, id); i.id_null = is_null; } } struct access::object_traits< ::position >::container_statement_cache_type { container_statement_cache_type (mysql::connection&) { } }; const char access::object_traits< ::position >::persist_statement[] = "INSERT INTO `position` (" "`id`," "`title`)" " VALUES (?,?)"; const char access::object_traits< ::position >::find_statement[] = "SELECT " "`position`.`id`," "`position`.`title`," "`employee`.`id`" " FROM `position`" " LEFT JOIN `employee` AS `employee` ON `employee`.`position` = `position`.`id`" " WHERE `position`.`id`=?"; const char access::object_traits< ::position >::update_statement[] = "UPDATE `position` SET " "`title`=?" " WHERE `id`=?"; const char access::object_traits< ::position >::erase_statement[] = "DELETE FROM `position`" " WHERE `id`=?"; const char access::object_traits< ::position >::query_statement[] = "SELECT " "`position`.`id`," "`position`.`title`," "`employee`.`id`" " FROM `position`" " LEFT JOIN `employee` AS `employee` ON `employee`.`position` = `position`.`id`" " "; const char access::object_traits< ::position >::erase_query_statement[] = "DELETE FROM `position`" " "; const char access::object_traits< ::position >::table_name[] = "`position`"; void access::object_traits< ::position >:: persist (database&, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; im.id_value = 0; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); obj.id_ = static_cast< id_type > (st.id ()); } void access::object_traits< ::position >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, obj.id_); image_type& im (sts.image ()); if (init (im, obj, statement_update)) im.version++; bool u (false); binding& imb (sts.update_image_binding ()); if (im.version != sts.update_image_version () || imb.version == 0) { bind (imb.bind, im, statement_update); sts.update_image_version (im.version); imb.version++; u = true; } binding& idb (sts.id_image_binding ()); if (i.version != sts.update_id_image_version () || idb.version == 0) { if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } sts.update_id_image_version (i.version); if (!u) imb.version++; } if (sts.update_statement ().execute () == 0) throw object_not_persistent (); } void access::object_traits< ::position >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::position >::pointer_type access::object_traits< ::position >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::position >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::position >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.id_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::position >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } result< access::object_traits< ::position >::object_type > access::object_traits< ::position >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::position >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } // project // // employees_ // const char access::object_traits< ::project >::employees_traits::select_all_statement[] = "SELECT " "`employee_projects`.`object_id`" " FROM `employee_projects` WHERE `employee_projects`.`value`=?"; const char access::object_traits< ::project >::employees_traits::insert_one_statement[] = ""; const char access::object_traits< ::project >::employees_traits::delete_all_statement[] = ""; void access::object_traits< ::project >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, cond_image_type& c) { ODB_POTENTIALLY_UNUSED (c); std::size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; } void access::object_traits< ::project >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, data_image_type& d) { using namespace mysql; statement_kind sk (statement_select); ODB_POTENTIALLY_UNUSED (sk); size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; // value // b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &d.value_value; b[n].is_null = &d.value_null; } void access::object_traits< ::project >::employees_traits:: grow (data_image_type& i, my_bool* t) { bool grew (false); // value // t[0UL] = 0; if (grew) i.version++; } void access::object_traits< ::project >::employees_traits:: init (value_type& v, const data_image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (db); // value // { typedef object_traits< ::employee > obj_traits; typedef pointer_traits< value_type > ptr_traits; if (i.value_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.value_value, i.value_null); v = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::project >::employees_traits:: insert_one (index_type, const value_type&, void*) { } bool access::object_traits< ::project >::employees_traits:: load_all (index_type&, value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); data_image_type& di (sts.data_image ()); init (v, di, sts.connection ().database ()); select_statement& st (sts.select_all_statement ()); select_statement::result r (st.fetch ()); if (r == select_statement::no_data) { st.free_result (); return false; } return true; } void access::object_traits< ::project >::employees_traits:: delete_all (void*) { } void access::object_traits< ::project >::employees_traits:: load (container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } select_statement& st (sts.select_all_statement ()); st.execute (); select_statement::result r (st.fetch ()); bool more (r != select_statement::no_data); if (!more) st.free_result (); sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::load (c, more, fs); } access::object_traits< ::project >::id_type access::object_traits< ::project >:: id (const image_type& i) { id_type id; mysql::value_traits< ::std::string, mysql::id_string >::set_value ( id, i.name_value, i.name_size, i.name_null); return id; } bool access::object_traits< ::project >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // name_ // if (t[0UL]) { i.name_value.capacity (i.name_size); grew = true; } return grew; } void access::object_traits< ::project >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // name_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.name_value.data (); b[n].buffer_length = static_cast ( i.name_value.capacity ()); b[n].length = &i.name_size; b[n].is_null = &i.name_null; n++; } } void access::object_traits< ::project >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.id_value.data (); b[n].buffer_length = static_cast ( i.id_value.capacity ()); b[n].length = &i.id_size; b[n].is_null = &i.id_null; } bool access::object_traits< ::project >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // name_ // if (sk == statement_insert) { bool is_null; std::size_t size (0); std::size_t cap (i.name_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.name_value, size, is_null, o.name_); i.name_size = static_cast (size); grew = grew || (cap != i.name_value.capacity ()); i.name_null = is_null; } return grew; } void access::object_traits< ::project >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // name_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.name_, i.name_value, i.name_size, i.name_null); } void access::object_traits< ::project >:: init (id_image_type& i, const id_type& id) { bool grew (false); { bool is_null; std::size_t size (0); std::size_t cap (i.id_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.id_value, size, is_null, id); i.id_size = static_cast (size); grew = grew || (cap != i.id_value.capacity ()); i.id_null = is_null; } if (grew) i.version++; } struct access::object_traits< ::project >::container_statement_cache_type { mysql::container_statements_impl< employees_traits > employees_; container_statement_cache_type (mysql::connection& c) : employees_ (c) { } }; const char access::object_traits< ::project >::persist_statement[] = "INSERT INTO `project` (" "`name`)" " VALUES (?)"; const char access::object_traits< ::project >::find_statement[] = "SELECT " "`project`.`name`" " FROM `project`" " WHERE `project`.`name`=?"; const char access::object_traits< ::project >::erase_statement[] = "DELETE FROM `project`" " WHERE `name`=?"; const char access::object_traits< ::project >::query_statement[] = "SELECT " "`project`.`name`" " FROM `project`" " "; const char access::object_traits< ::project >::erase_query_statement[] = "DELETE FROM `project`" " "; const char access::object_traits< ::project >::table_name[] = "`project`"; void access::object_traits< ::project >:: persist (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); } void access::object_traits< ::project >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); if (!find_ (sts, obj.name_)) throw object_not_persistent (); } void access::object_traits< ::project >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::project >::pointer_type access::object_traits< ::project >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::project >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::project >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.name_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::project >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } void access::object_traits< ::project >:: load_ (mysql::object_statements< object_type >& sts, object_type& obj) { mysql::binding& idb (sts.id_image_binding ()); employees_traits::load ( obj.employees_, idb, sts.container_statment_cache ().employees_); } result< access::object_traits< ::project >::object_type > access::object_traits< ::project >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::project >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } // employee // const char query_columns_base< ::employee >::employer_alias_[] = "`employer`"; const char query_columns_base< ::employee >::position_alias_[] = "`position`"; // projects_ // const char access::object_traits< ::employee >::projects_traits::select_all_statement[] = "SELECT " "`employee_projects`.`value`" " FROM `employee_projects` WHERE `employee_projects`.`object_id`=?"; const char access::object_traits< ::employee >::projects_traits::insert_one_statement[] = "INSERT INTO `employee_projects` (" "`object_id`," "`value`)" " VALUES (?,?)"; const char access::object_traits< ::employee >::projects_traits::delete_all_statement[] = "DELETE FROM `employee_projects`" " WHERE `object_id`=?"; void access::object_traits< ::employee >::projects_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, cond_image_type& c) { ODB_POTENTIALLY_UNUSED (c); std::size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; } void access::object_traits< ::employee >::projects_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, data_image_type& d) { using namespace mysql; statement_kind sk (statement_select); ODB_POTENTIALLY_UNUSED (sk); size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; // value // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = d.value_value.data (); b[n].buffer_length = static_cast ( d.value_value.capacity ()); b[n].length = &d.value_size; b[n].is_null = &d.value_null; } void access::object_traits< ::employee >::projects_traits:: grow (data_image_type& i, my_bool* t) { bool grew (false); // value // if (t[0UL]) { i.value_value.capacity (i.value_size); grew = true; } if (grew) i.version++; } void access::object_traits< ::employee >::projects_traits:: init (data_image_type& i, const value_type& v) { using namespace mysql; statement_kind sk (statement_insert); ODB_POTENTIALLY_UNUSED (sk); bool grew (false); // value // { typedef object_traits< ::project > obj_traits; typedef pointer_traits< value_type > ptr_traits; bool is_null (ptr_traits::null_ptr (v)); if (!is_null) { const obj_traits::id_type& id ( ptr_traits::object_id< ptr_traits::element_type > (v)); std::size_t size (0); std::size_t cap (i.value_value.capacity ()); mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_image ( i.value_value, size, is_null, id); i.value_size = static_cast (size); grew = grew || (cap != i.value_value.capacity ()); } else throw null_pointer (); i.value_null = is_null; } if (grew) i.version++; } void access::object_traits< ::employee >::projects_traits:: init (value_type& v, const data_image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (db); // value // { typedef object_traits< ::project > obj_traits; typedef pointer_traits< value_type > ptr_traits; if (i.value_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_value ( id, i.value_value, i.value_size, i.value_null); v = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::employee >::projects_traits:: insert_one (index_type, const value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); binding& b (sts.data_image_binding ()); data_image_type& di (sts.data_image ()); init (di, v); if (di.version != sts.data_image_version ()) { bind (b.bind, 0, sts.id_binding ().count, di); sts.data_image_version (di.version); b.version++; sts.select_image_binding ().version++; } if (!sts.insert_one_statement ().execute ()) throw object_already_persistent (); } bool access::object_traits< ::employee >::projects_traits:: load_all (index_type&, value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); data_image_type& di (sts.data_image ()); init (v, di, sts.connection ().database ()); select_statement& st (sts.select_all_statement ()); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { grow (di, sts.data_image_truncated ()); if (di.version != sts.data_image_version ()) { binding& b (sts.data_image_binding ()); bind (b.bind, 0, sts.id_binding ().count, di); sts.data_image_version (di.version); b.version++; sts.select_image_binding ().version++; st.refetch (); } } if (r == select_statement::no_data) { st.free_result (); return false; } return true; } void access::object_traits< ::employee >::projects_traits:: delete_all (void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); sts.delete_all_statement ().execute (); } void access::object_traits< ::employee >::projects_traits:: persist (const container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& b (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || b.version == 0) { bind (b.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); b.version++; sts.select_image_binding ().version++; } sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::persist (c, fs); } void access::object_traits< ::employee >::projects_traits:: load (container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } select_statement& st (sts.select_all_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { data_image_type& di (sts.data_image ()); grow (di, sts.data_image_truncated ()); if (di.version != sts.data_image_version ()) { bind (db.bind, 0, id.count, sts.data_image ()); sts.data_image_version (di.version); db.version++; sts.select_image_binding ().version++; st.refetch (); } } bool more (r != select_statement::no_data); if (!more) st.free_result (); sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::load (c, more, fs); } void access::object_traits< ::employee >::projects_traits:: update (const container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::update (c, fs); } void access::object_traits< ::employee >::projects_traits:: erase (const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& b (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || b.version == 0) { bind (b.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); b.version++; } sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::erase (fs); } access::object_traits< ::employee >::id_type access::object_traits< ::employee >:: id (const image_type& i) { id_type id; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( id, i.id_value, i.id_null); return id; } bool access::object_traits< ::employee >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // id_ // t[0UL] = 0; // first_ // if (t[1UL]) { i.first_value.capacity (i.first_size); grew = true; } // last_ // if (t[2UL]) { i.last_value.capacity (i.last_size); grew = true; } // employer_ // if (t[3UL]) { i.employer_value.capacity (i.employer_size); grew = true; } // position_ // t[4UL] = 0; return grew; } void access::object_traits< ::employee >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // id_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; n++; } // first_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.first_value.data (); b[n].buffer_length = static_cast ( i.first_value.capacity ()); b[n].length = &i.first_size; b[n].is_null = &i.first_null; n++; // last_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.last_value.data (); b[n].buffer_length = static_cast ( i.last_value.capacity ()); b[n].length = &i.last_size; b[n].is_null = &i.last_null; n++; // employer_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.employer_value.data (); b[n].buffer_length = static_cast ( i.employer_value.capacity ()); b[n].length = &i.employer_size; b[n].is_null = &i.employer_null; n++; // position_ // b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.position_value; b[n].is_null = &i.position_null; n++; } void access::object_traits< ::employee >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; } bool access::object_traits< ::employee >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // id_ // if (sk == statement_insert) { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, o.id_); i.id_null = is_null; } // first_ // { bool is_null; std::size_t size (0); std::size_t cap (i.first_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.first_value, size, is_null, o.first_); i.first_size = static_cast (size); grew = grew || (cap != i.first_value.capacity ()); i.first_null = is_null; } // last_ // { bool is_null; std::size_t size (0); std::size_t cap (i.last_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.last_value, size, is_null, o.last_); i.last_size = static_cast (size); grew = grew || (cap != i.last_value.capacity ()); i.last_null = is_null; } // employer_ // { typedef object_traits< ::employer > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::employer > > ptr_traits; bool is_null (ptr_traits::null_ptr (o.employer_)); if (!is_null) { const obj_traits::id_type& id ( ptr_traits::object_id< ptr_traits::element_type > (o.employer_)); std::size_t size (0); std::size_t cap (i.employer_value.capacity ()); mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_image ( i.employer_value, size, is_null, id); i.employer_size = static_cast (size); grew = grew || (cap != i.employer_value.capacity ()); } else throw null_pointer (); i.employer_null = is_null; } // position_ // { typedef object_traits< ::position > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::position > > ptr_traits; bool is_null (ptr_traits::null_ptr (o.position_)); if (!is_null) { const obj_traits::id_type& id ( ptr_traits::object_id< ptr_traits::element_type > (o.position_)); mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_image ( i.position_value, is_null, id); } else throw null_pointer (); i.position_null = is_null; } return grew; } void access::object_traits< ::employee >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // id_ // mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( o.id_, i.id_value, i.id_null); // first_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.first_, i.first_value, i.first_size, i.first_null); // last_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.last_, i.last_value, i.last_size, i.last_null); // employer_ // { typedef object_traits< ::employer > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::employer > > ptr_traits; if (i.employer_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_value ( id, i.employer_value, i.employer_size, i.employer_null); o.employer_ = ptr_traits::pointer_type (db, id); } } // position_ // { typedef object_traits< ::position > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::position > > ptr_traits; if (i.position_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.position_value, i.position_null); o.position_ = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::employee >:: init (id_image_type& i, const id_type& id) { { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, id); i.id_null = is_null; } } struct access::object_traits< ::employee >::container_statement_cache_type { mysql::container_statements_impl< projects_traits > projects_; container_statement_cache_type (mysql::connection& c) : projects_ (c) { } }; const char access::object_traits< ::employee >::persist_statement[] = "INSERT INTO `employee` (" "`id`," "`first`," "`last`," "`employer`," "`position`)" " VALUES (?,?,?,?,?)"; const char access::object_traits< ::employee >::find_statement[] = "SELECT " "`employee`.`id`," "`employee`.`first`," "`employee`.`last`," "`employee`.`employer`," "`employee`.`position`" " FROM `employee`" " WHERE `employee`.`id`=?"; const char access::object_traits< ::employee >::update_statement[] = "UPDATE `employee` SET " "`first`=?," "`last`=?," "`employer`=?," "`position`=?" " WHERE `id`=?"; const char access::object_traits< ::employee >::erase_statement[] = "DELETE FROM `employee`" " WHERE `id`=?"; const char access::object_traits< ::employee >::query_statement[] = "SELECT " "`employee`.`id`," "`employee`.`first`," "`employee`.`last`," "`employee`.`employer`," "`employee`.`position`" " FROM `employee`" " LEFT JOIN `employer` AS `employer` ON `employer`.`name` = `employee`.`employer`" " LEFT JOIN `position` AS `position` ON `position`.`id` = `employee`.`position`" " "; const char access::object_traits< ::employee >::erase_query_statement[] = "DELETE FROM `employee`" " "; const char access::object_traits< ::employee >::table_name[] = "`employee`"; void access::object_traits< ::employee >:: persist (database&, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; im.id_value = 0; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); obj.id_ = static_cast< id_type > (st.id ()); id_image_type& i (sts.id_image ()); init (i, obj.id_); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } projects_traits::persist ( obj.projects_, idb, sts.container_statment_cache ().projects_); } void access::object_traits< ::employee >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, obj.id_); image_type& im (sts.image ()); if (init (im, obj, statement_update)) im.version++; bool u (false); binding& imb (sts.update_image_binding ()); if (im.version != sts.update_image_version () || imb.version == 0) { bind (imb.bind, im, statement_update); sts.update_image_version (im.version); imb.version++; u = true; } binding& idb (sts.id_image_binding ()); if (i.version != sts.update_id_image_version () || idb.version == 0) { if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } sts.update_id_image_version (i.version); if (!u) imb.version++; } if (sts.update_statement ().execute () == 0) throw object_not_persistent (); projects_traits::update ( obj.projects_, idb, sts.container_statment_cache ().projects_); } void access::object_traits< ::employee >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } projects_traits::erase ( idb, sts.container_statment_cache ().projects_); if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::employee >::pointer_type access::object_traits< ::employee >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::employee >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::employee >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.id_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::employee >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } void access::object_traits< ::employee >:: load_ (mysql::object_statements< object_type >& sts, object_type& obj) { mysql::binding& idb (sts.id_image_binding ()); projects_traits::load ( obj.projects_, idb, sts.container_statment_cache ().projects_); } result< access::object_traits< ::employee >::object_type > access::object_traits< ::employee >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::employee >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } } // Begin epilogue. // // // End epilogue. #include -------------- next part -------------- A non-text attachment was scrubbed... Name: employee-odb.hxx Type: application/octet-stream Size: 29150 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20120313/2b1767cf/employee-odb-0002.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: employee-odb.ixx Type: application/octet-stream Size: 6034 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20120313/2b1767cf/employee-odb-0003.obj -------------- next part -------------- // This file was generated by ODB, object-relational mapping (ORM) // compiler for C++. // #include // Begin prologue. // // // End prologue. #include "employee-odb.hxx" #include #include // std::memcpy #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace odb { // employer // // employees_ // const char access::object_traits< ::employer >::employees_traits::select_all_statement[] = "SELECT " "`inverse_employee`.`id`" " FROM `inverse_employee` WHERE `inverse_employee`.`employer`=?"; const char access::object_traits< ::employer >::employees_traits::insert_one_statement[] = ""; const char access::object_traits< ::employer >::employees_traits::delete_all_statement[] = ""; void access::object_traits< ::employer >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, cond_image_type& c) { ODB_POTENTIALLY_UNUSED (c); std::size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; } void access::object_traits< ::employer >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, data_image_type& d) { using namespace mysql; statement_kind sk (statement_select); ODB_POTENTIALLY_UNUSED (sk); size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; // value // b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &d.value_value; b[n].is_null = &d.value_null; } void access::object_traits< ::employer >::employees_traits:: grow (data_image_type& i, my_bool* t) { bool grew (false); // value // t[0UL] = 0; if (grew) i.version++; } void access::object_traits< ::employer >::employees_traits:: init (value_type& v, const data_image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (db); // value // { typedef object_traits< ::employee > obj_traits; typedef pointer_traits< value_type > ptr_traits; if (i.value_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.value_value, i.value_null); v = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::employer >::employees_traits:: insert_one (index_type, const value_type&, void*) { } bool access::object_traits< ::employer >::employees_traits:: load_all (index_type&, value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); data_image_type& di (sts.data_image ()); init (v, di, sts.connection ().database ()); select_statement& st (sts.select_all_statement ()); select_statement::result r (st.fetch ()); if (r == select_statement::no_data) { st.free_result (); return false; } return true; } void access::object_traits< ::employer >::employees_traits:: delete_all (void*) { } void access::object_traits< ::employer >::employees_traits:: load (container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } select_statement& st (sts.select_all_statement ()); st.execute (); select_statement::result r (st.fetch ()); bool more (r != select_statement::no_data); if (!more) st.free_result (); sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::load (c, more, fs); } access::object_traits< ::employer >::id_type access::object_traits< ::employer >:: id (const image_type& i) { id_type id; mysql::value_traits< ::std::string, mysql::id_string >::set_value ( id, i.name_value, i.name_size, i.name_null); return id; } bool access::object_traits< ::employer >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // name_ // if (t[0UL]) { i.name_value.capacity (i.name_size); grew = true; } return grew; } void access::object_traits< ::employer >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // name_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.name_value.data (); b[n].buffer_length = static_cast ( i.name_value.capacity ()); b[n].length = &i.name_size; b[n].is_null = &i.name_null; n++; } } void access::object_traits< ::employer >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.id_value.data (); b[n].buffer_length = static_cast ( i.id_value.capacity ()); b[n].length = &i.id_size; b[n].is_null = &i.id_null; } bool access::object_traits< ::employer >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // name_ // if (sk == statement_insert) { bool is_null; std::size_t size (0); std::size_t cap (i.name_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.name_value, size, is_null, o.name_); i.name_size = static_cast (size); grew = grew || (cap != i.name_value.capacity ()); i.name_null = is_null; } return grew; } void access::object_traits< ::employer >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // name_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.name_, i.name_value, i.name_size, i.name_null); } void access::object_traits< ::employer >:: init (id_image_type& i, const id_type& id) { bool grew (false); { bool is_null; std::size_t size (0); std::size_t cap (i.id_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.id_value, size, is_null, id); i.id_size = static_cast (size); grew = grew || (cap != i.id_value.capacity ()); i.id_null = is_null; } if (grew) i.version++; } struct access::object_traits< ::employer >::container_statement_cache_type { mysql::container_statements_impl< employees_traits > employees_; container_statement_cache_type (mysql::connection& c) : employees_ (c) { } }; const char access::object_traits< ::employer >::persist_statement[] = "INSERT INTO `inverse_employer` (" "`name`)" " VALUES (?)"; const char access::object_traits< ::employer >::find_statement[] = "SELECT " "`inverse_employer`.`name`" " FROM `inverse_employer`" " WHERE `inverse_employer`.`name`=?"; const char access::object_traits< ::employer >::erase_statement[] = "DELETE FROM `inverse_employer`" " WHERE `name`=?"; const char access::object_traits< ::employer >::query_statement[] = "SELECT " "`inverse_employer`.`name`" " FROM `inverse_employer`" " "; const char access::object_traits< ::employer >::erase_query_statement[] = "DELETE FROM `inverse_employer`" " "; const char access::object_traits< ::employer >::table_name[] = "`inverse_employer`"; void access::object_traits< ::employer >:: persist (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); } void access::object_traits< ::employer >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); if (!find_ (sts, obj.name_)) throw object_not_persistent (); } void access::object_traits< ::employer >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::employer >::pointer_type access::object_traits< ::employer >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::employer >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::employer >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.name_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::employer >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } void access::object_traits< ::employer >:: load_ (mysql::object_statements< object_type >& sts, object_type& obj) { mysql::binding& idb (sts.id_image_binding ()); employees_traits::load ( obj.employees_, idb, sts.container_statment_cache ().employees_); } result< access::object_traits< ::employer >::object_type > access::object_traits< ::employer >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::employer >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } // position // const char query_columns_base< ::position >::employee_alias_[] = "`employee`"; const query_columns_base< ::position >::employee_type_ query_columns_base< ::position >::employee; access::object_traits< ::position >::id_type access::object_traits< ::position >:: id (const image_type& i) { id_type id; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( id, i.id_value, i.id_null); return id; } bool access::object_traits< ::position >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // id_ // t[0UL] = 0; // title_ // if (t[1UL]) { i.title_value.capacity (i.title_size); grew = true; } // employee_ // t[2UL] = 0; return grew; } void access::object_traits< ::position >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // id_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; n++; } // title_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.title_value.data (); b[n].buffer_length = static_cast ( i.title_value.capacity ()); b[n].length = &i.title_size; b[n].is_null = &i.title_null; n++; // employee_ // if (sk == statement_select) { b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.employee_value; b[n].is_null = &i.employee_null; n++; } } void access::object_traits< ::position >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; } bool access::object_traits< ::position >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // id_ // if (sk == statement_insert) { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, o.id_); i.id_null = is_null; } // title_ // { bool is_null; std::size_t size (0); std::size_t cap (i.title_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.title_value, size, is_null, o.title_); i.title_size = static_cast (size); grew = grew || (cap != i.title_value.capacity ()); i.title_null = is_null; } return grew; } void access::object_traits< ::position >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // id_ // mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( o.id_, i.id_value, i.id_null); // title_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.title_, i.title_value, i.title_size, i.title_null); // employee_ // { typedef object_traits< ::employee > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_weak_ptr< ::employee > > ptr_traits; if (i.employee_null) o.employee_ = ptr_traits::pointer_type (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.employee_value, i.employee_null); o.employee_ = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::position >:: init (id_image_type& i, const id_type& id) { { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, id); i.id_null = is_null; } } struct access::object_traits< ::position >::container_statement_cache_type { container_statement_cache_type (mysql::connection&) { } }; const char access::object_traits< ::position >::persist_statement[] = "INSERT INTO `inverse_position` (" "`id`," "`title`)" " VALUES (?,?)"; const char access::object_traits< ::position >::find_statement[] = "SELECT " "`inverse_position`.`id`," "`inverse_position`.`title`," "`employee`.`id`" " FROM `inverse_position`" " LEFT JOIN `inverse_employee` AS `employee` ON `employee`.`position` = `inverse_position`.`id`" " WHERE `inverse_position`.`id`=?"; const char access::object_traits< ::position >::update_statement[] = "UPDATE `inverse_position` SET " "`title`=?" " WHERE `id`=?"; const char access::object_traits< ::position >::erase_statement[] = "DELETE FROM `inverse_position`" " WHERE `id`=?"; const char access::object_traits< ::position >::query_statement[] = "SELECT " "`inverse_position`.`id`," "`inverse_position`.`title`," "`employee`.`id`" " FROM `inverse_position`" " LEFT JOIN `inverse_employee` AS `employee` ON `employee`.`position` = `inverse_position`.`id`" " "; const char access::object_traits< ::position >::erase_query_statement[] = "DELETE FROM `inverse_position`" " "; const char access::object_traits< ::position >::table_name[] = "`inverse_position`"; void access::object_traits< ::position >:: persist (database&, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; im.id_value = 0; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); obj.id_ = static_cast< id_type > (st.id ()); } void access::object_traits< ::position >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, obj.id_); image_type& im (sts.image ()); if (init (im, obj, statement_update)) im.version++; bool u (false); binding& imb (sts.update_image_binding ()); if (im.version != sts.update_image_version () || imb.version == 0) { bind (imb.bind, im, statement_update); sts.update_image_version (im.version); imb.version++; u = true; } binding& idb (sts.id_image_binding ()); if (i.version != sts.update_id_image_version () || idb.version == 0) { if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } sts.update_id_image_version (i.version); if (!u) imb.version++; } if (sts.update_statement ().execute () == 0) throw object_not_persistent (); } void access::object_traits< ::position >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::position >::pointer_type access::object_traits< ::position >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::position >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::position >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.id_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::position >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } result< access::object_traits< ::position >::object_type > access::object_traits< ::position >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::position >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } // project // // employees_ // const char access::object_traits< ::project >::employees_traits::select_all_statement[] = "SELECT " "`inverse_employee_projects`.`object_id`" " FROM `inverse_employee_projects` WHERE `inverse_employee_projects`.`value`=?"; const char access::object_traits< ::project >::employees_traits::insert_one_statement[] = ""; const char access::object_traits< ::project >::employees_traits::delete_all_statement[] = ""; void access::object_traits< ::project >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, cond_image_type& c) { ODB_POTENTIALLY_UNUSED (c); std::size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; } void access::object_traits< ::project >::employees_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, data_image_type& d) { using namespace mysql; statement_kind sk (statement_select); ODB_POTENTIALLY_UNUSED (sk); size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; // value // b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &d.value_value; b[n].is_null = &d.value_null; } void access::object_traits< ::project >::employees_traits:: grow (data_image_type& i, my_bool* t) { bool grew (false); // value // t[0UL] = 0; if (grew) i.version++; } void access::object_traits< ::project >::employees_traits:: init (value_type& v, const data_image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (db); // value // { typedef object_traits< ::employee > obj_traits; typedef pointer_traits< value_type > ptr_traits; if (i.value_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.value_value, i.value_null); v = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::project >::employees_traits:: insert_one (index_type, const value_type&, void*) { } bool access::object_traits< ::project >::employees_traits:: load_all (index_type&, value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); data_image_type& di (sts.data_image ()); init (v, di, sts.connection ().database ()); select_statement& st (sts.select_all_statement ()); select_statement::result r (st.fetch ()); if (r == select_statement::no_data) { st.free_result (); return false; } return true; } void access::object_traits< ::project >::employees_traits:: delete_all (void*) { } void access::object_traits< ::project >::employees_traits:: load (container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } select_statement& st (sts.select_all_statement ()); st.execute (); select_statement::result r (st.fetch ()); bool more (r != select_statement::no_data); if (!more) st.free_result (); sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::load (c, more, fs); } access::object_traits< ::project >::id_type access::object_traits< ::project >:: id (const image_type& i) { id_type id; mysql::value_traits< ::std::string, mysql::id_string >::set_value ( id, i.name_value, i.name_size, i.name_null); return id; } bool access::object_traits< ::project >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // name_ // if (t[0UL]) { i.name_value.capacity (i.name_size); grew = true; } return grew; } void access::object_traits< ::project >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // name_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.name_value.data (); b[n].buffer_length = static_cast ( i.name_value.capacity ()); b[n].length = &i.name_size; b[n].is_null = &i.name_null; n++; } } void access::object_traits< ::project >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.id_value.data (); b[n].buffer_length = static_cast ( i.id_value.capacity ()); b[n].length = &i.id_size; b[n].is_null = &i.id_null; } bool access::object_traits< ::project >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // name_ // if (sk == statement_insert) { bool is_null; std::size_t size (0); std::size_t cap (i.name_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.name_value, size, is_null, o.name_); i.name_size = static_cast (size); grew = grew || (cap != i.name_value.capacity ()); i.name_null = is_null; } return grew; } void access::object_traits< ::project >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // name_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.name_, i.name_value, i.name_size, i.name_null); } void access::object_traits< ::project >:: init (id_image_type& i, const id_type& id) { bool grew (false); { bool is_null; std::size_t size (0); std::size_t cap (i.id_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.id_value, size, is_null, id); i.id_size = static_cast (size); grew = grew || (cap != i.id_value.capacity ()); i.id_null = is_null; } if (grew) i.version++; } struct access::object_traits< ::project >::container_statement_cache_type { mysql::container_statements_impl< employees_traits > employees_; container_statement_cache_type (mysql::connection& c) : employees_ (c) { } }; const char access::object_traits< ::project >::persist_statement[] = "INSERT INTO `inverse_project` (" "`name`)" " VALUES (?)"; const char access::object_traits< ::project >::find_statement[] = "SELECT " "`inverse_project`.`name`" " FROM `inverse_project`" " WHERE `inverse_project`.`name`=?"; const char access::object_traits< ::project >::erase_statement[] = "DELETE FROM `inverse_project`" " WHERE `name`=?"; const char access::object_traits< ::project >::query_statement[] = "SELECT " "`inverse_project`.`name`" " FROM `inverse_project`" " "; const char access::object_traits< ::project >::erase_query_statement[] = "DELETE FROM `inverse_project`" " "; const char access::object_traits< ::project >::table_name[] = "`inverse_project`"; void access::object_traits< ::project >:: persist (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); } void access::object_traits< ::project >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); if (!find_ (sts, obj.name_)) throw object_not_persistent (); } void access::object_traits< ::project >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::project >::pointer_type access::object_traits< ::project >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::project >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::project >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.name_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::project >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } void access::object_traits< ::project >:: load_ (mysql::object_statements< object_type >& sts, object_type& obj) { mysql::binding& idb (sts.id_image_binding ()); employees_traits::load ( obj.employees_, idb, sts.container_statment_cache ().employees_); } result< access::object_traits< ::project >::object_type > access::object_traits< ::project >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::project >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } // employee // const char query_columns_base< ::employee >::employer_alias_[] = "`employer`"; const char query_columns_base< ::employee >::position_alias_[] = "`position`"; // projects_ // const char access::object_traits< ::employee >::projects_traits::select_all_statement[] = "SELECT " "`inverse_employee_projects`.`value`" " FROM `inverse_employee_projects` WHERE `inverse_employee_projects`.`object_id`=?"; const char access::object_traits< ::employee >::projects_traits::insert_one_statement[] = "INSERT INTO `inverse_employee_projects` (" "`object_id`," "`value`)" " VALUES (?,?)"; const char access::object_traits< ::employee >::projects_traits::delete_all_statement[] = "DELETE FROM `inverse_employee_projects`" " WHERE `object_id`=?"; void access::object_traits< ::employee >::projects_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, cond_image_type& c) { ODB_POTENTIALLY_UNUSED (c); std::size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; } void access::object_traits< ::employee >::projects_traits:: bind (MYSQL_BIND* b, const MYSQL_BIND* id, std::size_t id_size, data_image_type& d) { using namespace mysql; statement_kind sk (statement_select); ODB_POTENTIALLY_UNUSED (sk); size_t n (0); // object_id // if (id != 0) std::memcpy (&b[n], id, id_size * sizeof (id[0])); n += id_size; // value // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = d.value_value.data (); b[n].buffer_length = static_cast ( d.value_value.capacity ()); b[n].length = &d.value_size; b[n].is_null = &d.value_null; } void access::object_traits< ::employee >::projects_traits:: grow (data_image_type& i, my_bool* t) { bool grew (false); // value // if (t[0UL]) { i.value_value.capacity (i.value_size); grew = true; } if (grew) i.version++; } void access::object_traits< ::employee >::projects_traits:: init (data_image_type& i, const value_type& v) { using namespace mysql; statement_kind sk (statement_insert); ODB_POTENTIALLY_UNUSED (sk); bool grew (false); // value // { typedef object_traits< ::project > obj_traits; typedef pointer_traits< value_type > ptr_traits; bool is_null (ptr_traits::null_ptr (v)); if (!is_null) { const obj_traits::id_type& id ( ptr_traits::object_id< ptr_traits::element_type > (v)); std::size_t size (0); std::size_t cap (i.value_value.capacity ()); mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_image ( i.value_value, size, is_null, id); i.value_size = static_cast (size); grew = grew || (cap != i.value_value.capacity ()); } else throw null_pointer (); i.value_null = is_null; } if (grew) i.version++; } void access::object_traits< ::employee >::projects_traits:: init (value_type& v, const data_image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (db); // value // { typedef object_traits< ::project > obj_traits; typedef pointer_traits< value_type > ptr_traits; if (i.value_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_value ( id, i.value_value, i.value_size, i.value_null); v = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::employee >::projects_traits:: insert_one (index_type, const value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); binding& b (sts.data_image_binding ()); data_image_type& di (sts.data_image ()); init (di, v); if (di.version != sts.data_image_version ()) { bind (b.bind, 0, sts.id_binding ().count, di); sts.data_image_version (di.version); b.version++; sts.select_image_binding ().version++; } if (!sts.insert_one_statement ().execute ()) throw object_already_persistent (); } bool access::object_traits< ::employee >::projects_traits:: load_all (index_type&, value_type& v, void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); data_image_type& di (sts.data_image ()); init (v, di, sts.connection ().database ()); select_statement& st (sts.select_all_statement ()); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { grow (di, sts.data_image_truncated ()); if (di.version != sts.data_image_version ()) { binding& b (sts.data_image_binding ()); bind (b.bind, 0, sts.id_binding ().count, di); sts.data_image_version (di.version); b.version++; sts.select_image_binding ().version++; st.refetch (); } } if (r == select_statement::no_data) { st.free_result (); return false; } return true; } void access::object_traits< ::employee >::projects_traits:: delete_all (void* d) { using namespace mysql; statements_type& sts (*static_cast< statements_type* > (d)); sts.delete_all_statement ().execute (); } void access::object_traits< ::employee >::projects_traits:: persist (const container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& b (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || b.version == 0) { bind (b.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); b.version++; sts.select_image_binding ().version++; } sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::persist (c, fs); } void access::object_traits< ::employee >::projects_traits:: load (container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } select_statement& st (sts.select_all_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { data_image_type& di (sts.data_image ()); grow (di, sts.data_image_truncated ()); if (di.version != sts.data_image_version ()) { bind (db.bind, 0, id.count, sts.data_image ()); sts.data_image_version (di.version); db.version++; sts.select_image_binding ().version++; st.refetch (); } } bool more (r != select_statement::no_data); if (!more) st.free_result (); sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::load (c, more, fs); } void access::object_traits< ::employee >::projects_traits:: update (const container_type& c, const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& db (sts.data_image_binding ()); if (id.version != sts.data_id_binding_version () || db.version == 0) { bind (db.bind, id.bind, id.count, sts.data_image ()); sts.data_id_binding_version (id.version); db.version++; sts.select_image_binding ().version++; } binding& cb (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || cb.version == 0) { bind (cb.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); cb.version++; } sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::update (c, fs); } void access::object_traits< ::employee >::projects_traits:: erase (const mysql::binding& id, statements_type& sts) { using namespace mysql; binding& b (sts.cond_image_binding ()); if (id.version != sts.cond_id_binding_version () || b.version == 0) { bind (b.bind, id.bind, id.count, sts.cond_image ()); sts.cond_id_binding_version (id.version); b.version++; } sts.id_binding (id); functions_type& fs (sts.functions ()); fs.ordered (false); container_traits_type::erase (fs); } access::object_traits< ::employee >::id_type access::object_traits< ::employee >:: id (const image_type& i) { id_type id; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( id, i.id_value, i.id_null); return id; } bool access::object_traits< ::employee >:: grow (image_type& i, my_bool* t) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (t); bool grew (false); // id_ // t[0UL] = 0; // first_ // if (t[1UL]) { i.first_value.capacity (i.first_size); grew = true; } // last_ // if (t[2UL]) { i.last_value.capacity (i.last_size); grew = true; } // employer_ // if (t[3UL]) { i.employer_value.capacity (i.employer_size); grew = true; } // position_ // t[4UL] = 0; return grew; } void access::object_traits< ::employee >:: bind (MYSQL_BIND* b, image_type& i, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; std::size_t n (0); // id_ // if (sk != statement_update) { b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; n++; } // first_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.first_value.data (); b[n].buffer_length = static_cast ( i.first_value.capacity ()); b[n].length = &i.first_size; b[n].is_null = &i.first_null; n++; // last_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.last_value.data (); b[n].buffer_length = static_cast ( i.last_value.capacity ()); b[n].length = &i.last_size; b[n].is_null = &i.last_null; n++; // employer_ // b[n].buffer_type = MYSQL_TYPE_STRING; b[n].buffer = i.employer_value.data (); b[n].buffer_length = static_cast ( i.employer_value.capacity ()); b[n].length = &i.employer_size; b[n].is_null = &i.employer_null; n++; // position_ // b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.position_value; b[n].is_null = &i.position_null; n++; } void access::object_traits< ::employee >:: bind (MYSQL_BIND* b, id_image_type& i) { std::size_t n (0); b[n].buffer_type = MYSQL_TYPE_LONGLONG; b[n].is_unsigned = 1; b[n].buffer = &i.id_value; b[n].is_null = &i.id_null; } bool access::object_traits< ::employee >:: init (image_type& i, const object_type& o, mysql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mysql; bool grew (false); // id_ // if (sk == statement_insert) { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, o.id_); i.id_null = is_null; } // first_ // { bool is_null; std::size_t size (0); std::size_t cap (i.first_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.first_value, size, is_null, o.first_); i.first_size = static_cast (size); grew = grew || (cap != i.first_value.capacity ()); i.first_null = is_null; } // last_ // { bool is_null; std::size_t size (0); std::size_t cap (i.last_value.capacity ()); mysql::value_traits< ::std::string, mysql::id_string >::set_image ( i.last_value, size, is_null, o.last_); i.last_size = static_cast (size); grew = grew || (cap != i.last_value.capacity ()); i.last_null = is_null; } // employer_ // { typedef object_traits< ::employer > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::employer > > ptr_traits; bool is_null (ptr_traits::null_ptr (o.employer_)); if (!is_null) { const obj_traits::id_type& id ( ptr_traits::object_id< ptr_traits::element_type > (o.employer_)); std::size_t size (0); std::size_t cap (i.employer_value.capacity ()); mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_image ( i.employer_value, size, is_null, id); i.employer_size = static_cast (size); grew = grew || (cap != i.employer_value.capacity ()); } else throw null_pointer (); i.employer_null = is_null; } // position_ // { typedef object_traits< ::position > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::position > > ptr_traits; bool is_null (ptr_traits::null_ptr (o.position_)); if (!is_null) { const obj_traits::id_type& id ( ptr_traits::object_id< ptr_traits::element_type > (o.position_)); mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_image ( i.position_value, is_null, id); } else throw null_pointer (); i.position_null = is_null; } return grew; } void access::object_traits< ::employee >:: init (object_type& o, const image_type& i, database& db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // id_ // mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_value ( o.id_, i.id_value, i.id_null); // first_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.first_, i.first_value, i.first_size, i.first_null); // last_ // mysql::value_traits< ::std::string, mysql::id_string >::set_value ( o.last_, i.last_value, i.last_size, i.last_null); // employer_ // { typedef object_traits< ::employer > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::employer > > ptr_traits; if (i.employer_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_string >::set_value ( id, i.employer_value, i.employer_size, i.employer_null); o.employer_ = ptr_traits::pointer_type (db, id); } } // position_ // { typedef object_traits< ::position > obj_traits; typedef pointer_traits< ::odb::tr1::lazy_shared_ptr< ::position > > ptr_traits; if (i.position_null) throw null_pointer (); else { obj_traits::id_type id; mysql::value_traits< obj_traits::id_type, mysql::id_ulonglong >::set_value ( id, i.position_value, i.position_null); o.position_ = ptr_traits::pointer_type (db, id); } } } void access::object_traits< ::employee >:: init (id_image_type& i, const id_type& id) { { bool is_null; mysql::value_traits< long unsigned int, mysql::id_ulonglong >::set_image ( i.id_value, is_null, id); i.id_null = is_null; } } struct access::object_traits< ::employee >::container_statement_cache_type { mysql::container_statements_impl< projects_traits > projects_; container_statement_cache_type (mysql::connection& c) : projects_ (c) { } }; const char access::object_traits< ::employee >::persist_statement[] = "INSERT INTO `inverse_employee` (" "`id`," "`first`," "`last`," "`employer`," "`position`)" " VALUES (?,?,?,?,?)"; const char access::object_traits< ::employee >::find_statement[] = "SELECT " "`inverse_employee`.`id`," "`inverse_employee`.`first`," "`inverse_employee`.`last`," "`inverse_employee`.`employer`," "`inverse_employee`.`position`" " FROM `inverse_employee`" " WHERE `inverse_employee`.`id`=?"; const char access::object_traits< ::employee >::update_statement[] = "UPDATE `inverse_employee` SET " "`first`=?," "`last`=?," "`employer`=?," "`position`=?" " WHERE `id`=?"; const char access::object_traits< ::employee >::erase_statement[] = "DELETE FROM `inverse_employee`" " WHERE `id`=?"; const char access::object_traits< ::employee >::query_statement[] = "SELECT " "`inverse_employee`.`id`," "`inverse_employee`.`first`," "`inverse_employee`.`last`," "`inverse_employee`.`employer`," "`inverse_employee`.`position`" " FROM `inverse_employee`" " LEFT JOIN `inverse_employer` AS `employer` ON `employer`.`name` = `inverse_employee`.`employer`" " LEFT JOIN `inverse_position` AS `position` ON `position`.`id` = `inverse_employee`.`position`" " "; const char access::object_traits< ::employee >::erase_query_statement[] = "DELETE FROM `inverse_employee`" " "; const char access::object_traits< ::employee >::table_name[] = "`inverse_employee`"; void access::object_traits< ::employee >:: persist (database&, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); if (init (im, obj, statement_insert)) im.version++; im.id_value = 0; if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); obj.id_ = static_cast< id_type > (st.id ()); id_image_type& i (sts.id_image ()); init (i, obj.id_); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } projects_traits::persist ( obj.projects_, idb, sts.container_statment_cache ().projects_); } void access::object_traits< ::employee >:: update (database&, const object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, obj.id_); image_type& im (sts.image ()); if (init (im, obj, statement_update)) im.version++; bool u (false); binding& imb (sts.update_image_binding ()); if (im.version != sts.update_image_version () || imb.version == 0) { bind (imb.bind, im, statement_update); sts.update_image_version (im.version); imb.version++; u = true; } binding& idb (sts.id_image_binding ()); if (i.version != sts.update_id_image_version () || idb.version == 0) { if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } sts.update_id_image_version (i.version); if (!u) imb.version++; } if (sts.update_statement ().execute () == 0) throw object_not_persistent (); projects_traits::update ( obj.projects_, idb, sts.container_statment_cache ().projects_); } void access::object_traits< ::employee >:: erase (database&, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } projects_traits::erase ( idb, sts.container_statment_cache ().projects_); if (sts.erase_statement ().execute () != 1) throw object_not_persistent (); } access::object_traits< ::employee >::pointer_type access::object_traits< ::employee >:: find (database& db, const id_type& id) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (l.locked ()) { if (!find_ (sts, id)) return pointer_type (); } pointer_type p ( access::object_factory< object_type, pointer_type >::create ()); pointer_traits< pointer_type >::guard pg (p); pointer_cache_traits< pointer_type >::insert_guard ig ( pointer_cache_traits< pointer_type >::insert (db, id, p)); object_type& obj (pointer_traits< pointer_type >::get_ref (p)); if (l.locked ()) { callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); } else sts.delay_load (id, obj, ig.position ()); ig.release (); pg.release (); return p; } bool access::object_traits< ::employee >:: find (database& db, const id_type& id, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, id)) return false; reference_cache_traits< object_type >::insert_guard ig ( reference_cache_traits< object_type >::insert (db, id, obj)); callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); ig.release (); return true; } bool access::object_traits< ::employee >:: reload (database& db, object_type& obj) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); object_statements< object_type >::auto_lock l (sts); if (!find_ (sts, obj.id_)) return false; callback (db, obj, callback_event::pre_load); init (obj, sts.image (), db); load_ (sts, obj); sts.load_delayed (); l.unlock (); callback (db, obj, callback_event::post_load); return true; } bool access::object_traits< ::employee >:: find_ (mysql::object_statements< object_type >& sts, const id_type& id) { using namespace mysql; id_image_type& i (sts.id_image ()); init (i, id); binding& idb (sts.id_image_binding ()); if (i.version != sts.id_image_version () || idb.version == 0) { bind (idb.bind, i); sts.id_image_version (i.version); idb.version++; } image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } select_statement& st (sts.find_statement ()); st.execute (); select_statement::result r (st.fetch ()); if (r == select_statement::truncated) { if (grow (im, sts.select_image_truncated ())) im.version++; if (im.version != sts.select_image_version ()) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; st.refetch (); } } st.free_result (); return r != select_statement::no_data; } void access::object_traits< ::employee >:: load_ (mysql::object_statements< object_type >& sts, object_type& obj) { mysql::binding& idb (sts.id_image_binding ()); projects_traits::load ( obj.projects_, idb, sts.container_statment_cache ().projects_); } result< access::object_traits< ::employee >::object_type > access::object_traits< ::employee >:: query (database&, const query_base_type& q) { using namespace mysql; using odb::details::shared; using odb::details::shared_ptr; mysql::connection& conn ( mysql::transaction::current ().connection ()); object_statements< object_type >& sts ( conn.statement_cache ().find_object ()); image_type& im (sts.image ()); binding& imb (sts.select_image_binding ()); if (im.version != sts.select_image_version () || imb.version == 0) { bind (imb.bind, im, statement_select); sts.select_image_version (im.version); imb.version++; } shared_ptr st ( new (shared) select_statement ( sts.connection (), query_statement + q.clause (), q.parameters_binding (), imb)); st->execute (); shared_ptr< odb::object_result_impl > r ( new (shared) mysql::object_result_impl ( q, st, sts)); return result (r); } unsigned long long access::object_traits< ::employee >:: erase_query (database&, const query_base_type& q) { using namespace mysql; mysql::connection& conn ( mysql::transaction::current ().connection ()); delete_statement st ( conn, erase_query_statement + q.clause (), q.parameters_binding ()); return st.execute (); } } // Begin epilogue. // // // End epilogue. #include -------------- next part -------------- A non-text attachment was scrubbed... Name: valid employee-odb.hxx Type: application/octet-stream Size: 29328 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20120313/2b1767cf/validemployee-odb-0002.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: valid employee-odb.ixx Type: application/octet-stream Size: 6034 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20120313/2b1767cf/validemployee-odb-0003.obj From boris at codesynthesis.com Tue Mar 13 06:44:08 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Mar 13 06:38:27 2012 Subject: [odb-users] Problem: odb.exe fails to generate valid hxx/cxx file, not adding shared_ptr in typedef In-Reply-To: References: Message-ID: Hi Wayne, Wayne Hackle writes: > So I dug a bit deeper, ran "odb --database mysql --generate-query > employee.hxx", then the project fails to build. If you read the README file that accompanies the example, you will notice this fragment: These files are generated by the ODB compiler from employee.hxx using the following command line: odb -d --generate-schema --generate-query \ --default-pointer std::tr1::shared_ptr employee.hxx Where stands for the database system we are using, for example, 'mysql'. The --default-pointer option is used to make TR1 shared_ptr the default object pointer. Boris From hacklew at hotmail.com Tue Mar 13 20:12:26 2012 From: hacklew at hotmail.com (Wayne Hackle) Date: Tue Mar 13 20:12:33 2012 Subject: [odb-users] Problem: odb.exe fails to generate valid hxx/cxx file, not adding shared_ptr in typedef In-Reply-To: References: , Message-ID: Yes Boris, that solves it, thanks! I actually looked into the Visual Studio building file, and found out the automatically generated .bat file contains the correct odb command line. now with your explanation it's all clear. do you mind me asking another question: what puzzles me infinitely now is, how does the VC project run the "odb" commandline automatically before the actual "exe" file is created? I looked looked and looked more, and couldn't find where the trick is. Thanks! Hackle > Date: Tue, 13 Mar 2012 12:44:08 +0200 > From: boris@codesynthesis.com > To: hacklew@hotmail.com > CC: odb-users@codesynthesis.com > Subject: Re: [odb-users] Problem: odb.exe fails to generate valid hxx/cxx file, not adding shared_ptr in typedef > > Hi Wayne, > > Wayne Hackle writes: > > > So I dug a bit deeper, ran "odb --database mysql --generate-query > > employee.hxx", then the project fails to build. > > If you read the README file that accompanies the example, you will notice > this fragment: > > These files are generated by the ODB compiler from employee.hxx using the > following command line: > > odb -d --generate-schema --generate-query \ > --default-pointer std::tr1::shared_ptr employee.hxx > > Where stands for the database system we are using, for example, > 'mysql'. > > The --default-pointer option is used to make TR1 shared_ptr the default > object pointer. > > Boris From boris at codesynthesis.com Wed Mar 14 14:08:48 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Mar 14 14:03:12 2012 Subject: [odb-users] Problem: odb.exe fails to generate valid hxx/cxx file, not adding shared_ptr in typedef In-Reply-To: References: Message-ID: Hi Wayne, Wayne Hackle writes: > what puzzles me infinitely now is, how does the VC project run the > "odb" commandline automatically before the actual "exe" file is > created? It is done using a custom build step. I've created a Wiki page that describes how to set this up: http://wiki.codesynthesis.com/Using_ODB_with_Microsoft_Visual_Studio Boris From hacklew at hotmail.com Tue Mar 27 07:51:37 2012 From: hacklew at hotmail.com (Wayne Hackle) Date: Tue Mar 27 07:51:43 2012 Subject: [odb-users] What is the proper practice in using smart pointer in querying In-Reply-To: References: , Message-ID: Hi dear all, I've been digging around with ODB for quite a while now, with great help from Boris and other more experienced users every now and then. The new question is: what is the proper practice in using shared_ptr as default pointer? I ran into very annoying errors that indicate memory management fault (destructors especially). Here is my code: session s; auto_ptr db(new odb::mysql::database("root","somepassword","somedatabase", "localhost")); vector v_person; transaction t(db->begin()); result r(db->query()); for (result::iterator i(r.begin()); i != r.end(); ++i) { shared_ptr p(i.load()); v_person.push_back(*p); } t.commit(); The project builds successfully, but throws this exception when run:> odb::mysql::database::`scalar deleting destructor'() + 0x2e bit C++ looks like it's related to the destructor, but I am totally clueless. Any help is appreciated, thank you very much. Hackle From boris at codesynthesis.com Tue Mar 27 09:28:58 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Mar 27 09:23:58 2012 Subject: [odb-users] What is the proper practice in using smart pointer in querying In-Reply-To: References: Message-ID: Hi Wayne, Wayne Hackle writes: > The new question is: what is the proper practice in using shared_ptr > as default pointer? I ran into very annoying errors that indicate memory > management fault (destructors especially). > Here is my code: > > [...] I don't see anything "illegal" in your code itself (though I don't know what the person class looks like). The only problematic part is vector. You probably want to store shared pointers there instead of copies of the objects. I would also move the session closer to where it is actually needed: auto_ptr db( new odb::mysql::database("root", "somepassword", "somedatabase", "localhost")); vector > v_person; { session s; transaction t(db->begin()); result r(db->query()); for (result::iterator i(r.begin()); i != r.end(); ++i) { shared_ptr p(i.load()); v_person.push_back(p); } t.commit(); } Boris From Davide.Anastasia at qualitycapital.com Tue Mar 27 11:08:39 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Tue Mar 27 11:10:38 2012 Subject: [odb-users] PostgreSQL NUMERIC type Message-ID: Hi All, We are currently trying to write a bespoke C++ class to support the NUMERIC type on PostgreSQL. However, I haven't found an hint on how to plug such a class into ODB seamlessly. Is there something I can read that would help me find the right way? Thanks a lot, Davide Anastasia Analyst, Research & Development Quality Capital Management Ltd. QCM House * Horizon Business Village No. 1 Brooklands Road Weybridge * Surrey KT13 0TJ United Kingdom Tel: +44 (0) 1932 334 400 Fax: +44 (0) 1932 334 415 Email: Davide.Anastasia@QualityCapital.com www.qualitycapital.com ________________________________ This email and any attachments are confidential and intended solely for the use of the individual(s) to whom it is addressed. Any views or opinions presented are solely those of the author and do not necessarily represent those of Quality Capital Management Ltd. If you are not the intended recipient, be advised that you have received this email in error and that any use, dissemination, printing, forwarding or copying of this email is strictly prohibited. Please contact the sender if you have received this email in error. You should also be aware that emails are susceptible to interference and you should not assume that the contents of this email originated from the sender above or that they have been accurately reproduced in their original form. Quality Capital Management Ltd is authorised and regulated by the Financial Services Authority in the UK and is a member of the National Futures Association in the US. ________________________________ From hacklew at hotmail.com Tue Mar 27 23:09:35 2012 From: hacklew at hotmail.com (Wayne Hackle) Date: Tue Mar 27 23:09:43 2012 Subject: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap In-Reply-To: References: , Message-ID: Thanks but that doesn't work either. I used a new subject because I think the original one is misleading. I am using ODB with a VS2008 WTL dialog program. All the code that works with a Console program, when used with the WTL one, gives this exception:HEAP[scheduler.exe]: Invalid Address specified to RtlValidateHeap and the stacktrace goes (possibly need to scroll all the way to the bottom where the bold lines are) msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x00fd35d0, int nBlockUse=1) ?1317 + 0x9 ?? C++ msvcr90d.dll!_free_dbg(void * pUserData=0x00fd35d0, int nBlockUse=1) ?1258 + 0xd ?? C++ msvcr90d.dll!operator delete(void * pUserData=0x00fd35d0) ?54 + 0x10 ?? C++ odb-mysql-d-1.8-vc9.dll!std::allocator,odb::details::type_info_comparator,std::allocator > >,0> >::_Node>::deallocate(std::_Tree_nod,odb::details::type_info_comparator,std::allocator > >,0> >::_Node * _Ptr=0x00fd35d0, unsigned int __formal=1) ?140 + 0x9 ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::_Erase(std::_Tree_nod,odb::details::type_info_comparator,std::allocator > >,0> >::_Node * _Rootnode=0x00fd35d0) ?1173 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::clear() ?972 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::erase(std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::const_iterator _First=(0x005438ec class person `RTTI Type Descriptor' {_m_data=0x00000000 _m_d_name=0x005438f4 ".?AVperson@@" },{x_=0x00037af0 }), std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::const_iterator _Last=(0xcdcdcdcd {_m_data=??? _m_d_name=0xcdcdcdd5 },{x_=0xcdcdcdcd })) ?938 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::_Tidy() ?1421 + 0xaa ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::~_Tree,odb::details::type_info_comparator,std::allocator > >,0> >() ?541 C++ odb-mysql-d-1.8-vc9.dll!std::map,odb::details::type_info_comparator,std::allocator > > >::~map,odb::details::type_info_comparator,std::allocator > > >() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::statement_cache::~statement_cache() + 0x2e ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::statement_cache::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!std::auto_ptr::~auto_ptr() ?718 + 0x2d ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection::~connection() ?86 + 0x24 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::pooled_connection::~pooled_connection() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::pooled_connection::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::details::bits::counter_ops::dec(odb::mysql::connection_pool_factory::pooled_connection * p=0x000375e0) ?172 + 0x35 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::details::shared_ptr::~shared_ptr() ?27 C++ odb-mysql-d-1.8-vc9.dll!odb::details::shared_ptr::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy >(odb::details::shared_ptr * _Ptr=0x000382c8) ?60 C++ odb-mysql-d-1.8-vc9.dll!std::allocator >::destroy(odb::details::shared_ptr * _Ptr=0x000382c8) ?160 + 0x9 ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy_range > >(odb::details::shared_ptr * _First=0x000382c8, odb::details::shared_ptr * _Last=0x000382cc, std::allocator > & _Al={...}, std::_Nonscalar_ptr_iterator_tag __formal={...}) ?234 + 0xc ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy_range > >(odb::details::shared_ptr * _First=0x000382c8, odb::details::shared_ptr * _Last=0x000382cc, std::allocator > & _Al={...}) ?225 + 0x2f ?? C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::_Destroy(odb::details::shared_ptr * _First=0x000382c8, odb::details::shared_ptr * _Last=0x000382cc) ?1124 + 0x14 ?? C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::_Tidy() ?1137 C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::~vector,std::allocator > >() ?560 C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::~connection_pool_factory() ?170 + 0x57 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::`vector deleting destructor'() + 0x69 ?? C++ odb-mysql-d-1.8-vc9.dll!std::auto_ptr::~auto_ptr() ?718 + 0x37 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::database::~database() ?23 + 0xe ?? C++ scheduler.exe!odb::mysql::database::`scalar deleting destructor'() + 0x2e ?? C++ scheduler.exe!std::auto_ptr::~auto_ptr() ?718 + 0x36 ?? C++ Would it be a known issue with WTL? Or it seems more likely that it's about auto_ptr destructor? I googled googled and googled and no luck. Any help is appreciated. Hackle > Date: Tue, 27 Mar 2012 15:28:58 +0200 > From: boris@codesynthesis.com > To: hacklew@hotmail.com > CC: odb-users@codesynthesis.com > Subject: Re: [odb-users] What is the proper practice in using smart pointer in querying > > Hi Wayne, > > Wayne Hackle writes: > > > The new question is: what is the proper practice in using shared_ptr > > as default pointer? I ran into very annoying errors that indicate memory > > management fault (destructors especially). > > Here is my code: > > > > [...] > > I don't see anything "illegal" in your code itself (though I don't > know what the person class looks like). The only problematic part > is vector. You probably want to store shared pointers there > instead of copies of the objects. I would also move the session > closer to where it is actually needed: > > auto_ptr db( > new odb::mysql::database("root", > "somepassword", > "somedatabase", > "localhost")); > > vector > v_person; > > { > session s; > transaction t(db->begin()); > > result r(db->query()); > for (result::iterator i(r.begin()); i != r.end(); ++i) > { > shared_ptr p(i.load()); > v_person.push_back(p); > } > > t.commit(); > } > > Boris From hacklew at hotmail.com Wed Mar 28 00:27:37 2012 From: hacklew at hotmail.com (Wayne Hackle) Date: Wed Mar 28 00:27:44 2012 Subject: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap In-Reply-To: References: , , , , , Message-ID: it's not auto_ptr or any smart pointer's problem, as i have checked. It must be a conflict between WTL/MFC and ODB. Sorry to have rushed the question out of panic, please help. > From: hacklew@hotmail.com > To: odb-users@codesynthesis.com > Date: Wed, 28 Mar 2012 03:09:35 +0000 > Subject: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap > > > Thanks but that doesn't work either. > I used a new subject because I think the original one is misleading. > > I am using ODB with a VS2008 WTL dialog program. > All the code that works with a Console program, when used with the WTL one, gives this exception:HEAP[scheduler.exe]: Invalid Address specified to RtlValidateHeap > and the stacktrace goes (possibly need to scroll all the way to the bottom where the bold lines are) > msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x00fd35d0, int nBlockUse=1) ?1317 + 0x9 ?? C++ msvcr90d.dll!_free_dbg(void * pUserData=0x00fd35d0, int nBlockUse=1) ?1258 + 0xd ?? C++ msvcr90d.dll!operator delete(void * pUserData=0x00fd35d0) ?54 + 0x10 ?? C++ odb-mysql-d-1.8-vc9.dll!std::allocator,odb::details::type_info_comparator,std::allocator > >,0> >::_Node>::deallocate(std::_Tree_nod,odb::details::type_info_comparator,std::allocator > >,0> >::_Node * _Ptr=0x00fd35d0, unsigned int __formal=1) ?140 + 0x9 ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Tree details::shared_ptr,odb::details::type_info_comparator,std::allocator > >,0> >::_Erase(std::_Tree_nod,odb::details::type_info_comparator,std::allocator > >,0> >::_Node * _Rootnode=0x00fd35d0) ?1173 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::clear() ?972 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator const * const,odb::details::shared_ptr > > > >,0> >::erase(std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::const_iterator _First=(0x005438ec class person `RTTI Type Descriptor' {_m_data=0x00000000 _m_d_name=0x005438f4 ".?AVperson@@" },{x_=0x00037af0 }), std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::const_iterator _Last=(0xcdcdcdcd {_m_data=??? _m_d_name=0xcdcdcdd5 },{x_=0xcdcdcdcd })) ?938 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator ails::shared_ptr > >,0> >::_Tidy() ?1421 + 0xaa ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::~_Tree,odb::details::type_info_comparator,std::allocator > >,0> >() ?541 C++ odb-mysql-d-1.8-vc9.dll!std::map,odb::details::type_info_comparator,std::allocator > > >::~map,odb::details::type_info_comparator,std::a! > llocator > b::mysql::statements_base> > > >() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::statement_cache::~statement_cache() + 0x2e ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::statement_cache::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!std::auto_ptr::~auto_ptr() ?718 + 0x2d ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection::~connection() ?86 + 0x24 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::pooled_connection::~pooled_connection() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::pooled_connection::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::details::bits::counter_ops::dec(odb::mysql::connection_pool_factory::pooled_connection * p=0x000375e0) ?172 + 0x35 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::details::sh! > ared_ptr::~shared_ptr() ?27 C++ odb-mysql-d-1.8-vc9.dll!odb::details::shared_ptr::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy >(odb::details::shared_ptr * _Ptr=0x000382c8) ?60 C++ odb-mysql-d-1.8-vc9.dll!std::allocator >::destroy(odb::details::shared_ptr * _Ptr=0x000382c8) ?160 + 0x9 ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy_range > >(odb::details::shared_ptr tory::pooled_connection> * _First=0x000382c8, odb::details::shared_ptr > > * _Last=0x000382cc, std::allocator > & _Al={...}, std::_Nonscalar_ptr_iterator_tag __formal={...}) ?234 + 0xc ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy_range > >(odb::details::shared_ptr * _First=0x000382c8, odb::details::shared_ptr * _Last=0x000382cc, std::allocator > & _Al={...}) ?225 + 0x2f ?? C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::_Destroy(odb::details::shared! > _ptr * _First=0x000382c8, odb::details::shared_ptr * _Last=0x000382cc) ?1124 + 0x14 ?? C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::_Tidy() ?1137 C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::~vector,std::allocator > >() ?560 C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::~connection_pool_factory() ?170 + 0x57 ?? C++ odb-mysq! > l-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::`vector deleting > > destructor'() + 0x69 ?? C++ odb-mysql-d-1.8-vc9.dll!std::auto_ptr::~auto_ptr() ?718 + 0x37 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::database::~database() ?23 + 0xe ?? C++ scheduler.exe!odb::mysql::database::`scalar deleting destructor'() + 0x2e ?? C++ scheduler.exe!std::auto_ptr::~auto_ptr() ?718 + 0x36 ?? C++ > Would it be a known issue with WTL? Or it seems more likely that it's about auto_ptr destructor? > I googled googled and googled and no luck. > Any help is appreciated. > Hackle > > > Date: Tue, 27 Mar 2012 15:28:58 +0200 > > From: boris@codesynthesis.com > > To: hacklew@hotmail.com > > CC: odb-users@codesynthesis.com > > Subject: Re: [odb-users] What is the proper practice in using smart pointer in querying > > > > Hi Wayne, > > > > Wayne Hackle writes: > > > > > The new question is: what is the proper practice in using shared_ptr > > > as default pointer? I ran into very annoying errors that indicate memory > > > management fault (destructors especially). > > > Here is my code: > > > > > > [...] > > > > I don't see anything "illegal" in your code itself (though I don't > > know what the person class looks like). The only problematic part > > is vector. You probably want to store shared pointers there > > instead of copies of the objects. I would also move the session > > closer to where it is actually needed: > > > > auto_ptr db( > > new odb::mysql::database("root", > > "somepassword", > > "somedatabase", > > "localhost")); > > > > vector > v_person; > > > > { > > session s; > > transaction t(db->begin()); > > > > result r(db->query()); > > for (result::iterator i(r.begin()); i != r.end(); ++i) > > { > > shared_ptr p(i.load()); > > v_person.push_back(p); > > } > > > > t.commit(); > > } > > > > Boris > From hacklew at hotmail.com Wed Mar 28 02:32:36 2012 From: hacklew at hotmail.com (Wayne Hackle) Date: Wed Mar 28 02:32:45 2012 Subject: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap In-Reply-To: References: , , , , , , , , , , Message-ID: It's definitely WTL now as I have tried with MFC and it works. Damn, I had wanted WTL so much! > From: hacklew@hotmail.com > To: odb-users@codesynthesis.com > Subject: RE: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap > Date: Wed, 28 Mar 2012 04:27:37 +0000 > > > it's not auto_ptr or any smart pointer's problem, as i have checked. It must be a conflict between WTL/MFC and ODB. > Sorry to have rushed the question out of panic, please help. > > > From: hacklew@hotmail.com > > To: odb-users@codesynthesis.com > > Date: Wed, 28 Mar 2012 03:09:35 +0000 > > Subject: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap > > > > > > Thanks but that doesn't work either. > > I used a new subject because I think the original one is misleading. > > > > I am using ODB with a VS2008 WTL dialog program. > > All the code that works with a Console program, when used with the WTL one, gives this exception:HEAP[scheduler.exe]: Invalid Address specified to RtlValidateHeap > > and the stacktrace goes (possibly need to scroll all the way to the bottom where the bold lines are) > > msvcr90d.dll!_free_dbg_nolock(void * pUserData=0x00fd35d0, int nBlockUse=1) ?1317 + 0x9 ?? C++ msvcr90d.dll!_free_dbg(void * pUserData=0x00fd35d0, int nBlockUse=1) ?1258 + 0xd ?? C++ msvcr90d.dll!operator delete(void * pUserData=0x00fd35d0) ?54 + 0x10 ?? C++ odb-mysql-d-1.8-vc9.dll!std::allocator,odb::details::type_info_comparator,std::allocator > >,0> >::_Node>::deallocate(std::_Tree_nod,odb::details::type_info_comparator,std::allocator > >,0> >::_Node * _Ptr=0x00fd35d0, unsigned int __formal=1) ?140 + 0x9 ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Tree ::! > > details::shared_ptr,odb::details::type_info_comparator,std::allocator > >,0> >::_Erase(std::_Tree_nod,odb::details::type_info_comparator,std::allocator > >,0> >::_Node * _Rootnode=0x00fd35d0) ?1173 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::clear() ?972 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator o ! > > const * const,odb::details::shared_ptr > > > > > >,0> >::erase(std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::const_iterator _First=(0x005438ec class person `RTTI Type Descriptor' {_m_data=0x00000000 _m_d_name=0x005438f4 ".?AVperson@@" },{x_=0x00037af0 }), std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::const_iterator _Last=(0xcdcdcdcd {_m_data=??? _m_d_name=0xcdcdcdd5 },{x_=0xcdcdcdcd })) ?938 C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator et! > > ails::shared_ptr > >,0> >::_Tidy() ?1421 + 0xaa ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Tree,odb::details::type_info_comparator,std::allocator > >,0> >::~_Tree,odb::details::type_info_comparator,std::allocator > >,0> >() ?541 C++ odb-mysql-d-1.8-vc9.dll!std::map,odb::details::type_info_comparator,std::allocator > > >::~map,odb::details::type_info_comparator,std:! > :a! > > llocator > > > b::mysql::statements_base> > > >() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::statement_cache::~statement_cache() + 0x2e ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::statement_cache::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!std::auto_ptr::~auto_ptr() ?718 + 0x2d ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection::~connection() ?86 + 0x24 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::pooled_connection::~pooled_connection() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::pooled_connection::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!odb::details::bits::counter_ops::dec(odb::mysql::connection_pool_factory::pooled_connection * p=0x000375e0) ?172 + 0x35 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::details::! > sh! > > ared_ptr::~shared_ptr() ?27 C++ odb-mysql-d-1.8-vc9.dll!odb::details::shared_ptr::`scalar deleting destructor'() + 0x2b ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy >(odb::details::shared_ptr * _Ptr=0x000382c8) ?60 C++ odb-mysql-d-1.8-vc9.dll!std::allocator >::destroy(odb::details::shared_ptr * _Ptr=0x000382c8) ?160 + 0x9 ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy_range > >(odb::details::shared_ptr ac! > > tory::pooled_connection> * _First=0x000382c8, odb::details::shared_ptr > > > > * _Last=0x000382cc, std::allocator > & _Al={...}, std::_Nonscalar_ptr_iterator_tag __formal={...}) ?234 + 0xc ?? C++ odb-mysql-d-1.8-vc9.dll!std::_Destroy_range > >(odb::details::shared_ptr * _First=0x000382c8, odb::details::shared_ptr * _Last=0x000382cc, std::allocator > & _Al={...}) ?225 + 0x2f ?? C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::_Destroy(odb::details::shar! > ed! > > _ptr * _First=0x000382c8, odb::details::shared_ptr * _Last=0x000382cc) ?1124 + 0x14 ?? C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::_Tidy() ?1137 C++ odb-mysql-d-1.8-vc9.dll!std::vector,std::allocator > >::~vector,std::allocator > >() ?560 C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::~connection_pool_factory() ?170 + 0x57 ?? C++ odb-my! > sq! > > l-d-1.8-vc9.dll!odb::mysql::connection_pool_factory::`vector deleting > > > > destructor'() + 0x69 ?? C++ odb-mysql-d-1.8-vc9.dll!std::auto_ptr::~auto_ptr() ?718 + 0x37 ?? C++ odb-mysql-d-1.8-vc9.dll!odb::mysql::database::~database() ?23 + 0xe ?? C++ scheduler.exe!odb::mysql::database::`scalar deleting destructor'() + 0x2e ?? C++ scheduler.exe!std::auto_ptr::~auto_ptr() ?718 + 0x36 ?? C++ > > Would it be a known issue with WTL? Or it seems more likely that it's about auto_ptr destructor? > > I googled googled and googled and no luck. > > Any help is appreciated. > > Hackle > > > > > Date: Tue, 27 Mar 2012 15:28:58 +0200 > > > From: boris@codesynthesis.com > > > To: hacklew@hotmail.com > > > CC: odb-users@codesynthesis.com > > > Subject: Re: [odb-users] What is the proper practice in using smart pointer in querying > > > > > > Hi Wayne, > > > > > > Wayne Hackle writes: > > > > > > > The new question is: what is the proper practice in using shared_ptr > > > > as default pointer? I ran into very annoying errors that indicate memory > > > > management fault (destructors especially). > > > > Here is my code: > > > > > > > > [...] > > > > > > I don't see anything "illegal" in your code itself (though I don't > > > know what the person class looks like). The only problematic part > > > is vector. You probably want to store shared pointers there > > > instead of copies of the objects. I would also move the session > > > closer to where it is actually needed: > > > > > > auto_ptr db( > > > new odb::mysql::database("root", > > > "somepassword", > > > "somedatabase", > > > "localhost")); > > > > > > vector > v_person; > > > > > > { > > > session s; > > > transaction t(db->begin()); > > > > > > result r(db->query()); > > > for (result::iterator i(r.begin()); i != r.end(); ++i) > > > { > > > shared_ptr p(i.load()); > > > v_person.push_back(p); > > > } > > > > > > t.commit(); > > > } > > > > > > Boris > > > From boris at codesynthesis.com Wed Mar 28 02:42:51 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Mar 28 02:37:52 2012 Subject: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap In-Reply-To: References: Message-ID: Hi Wayne, Wayne Hackle writes: > It's definitely WTL now as I have tried with MFC and it works. Can you send me a test project so that I could try to reproduce and debug the problem? You can send it off-list. Boris From boris at codesynthesis.com Wed Mar 28 03:36:46 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Mar 28 03:31:48 2012 Subject: [odb-users] PostgreSQL NUMERIC type In-Reply-To: References: Message-ID: Hi Davide, Davide Anastasia writes: > We are currently trying to write a bespoke C++ class to support the > NUMERIC type on PostgreSQL. However, I haven't found an hint on how to > plug such a class into ODB seamlessly. Is there something I can read > that would help me find the right way? There is an example in the odb-examples package called 'mapping' that shows how to map (and re-map) C++ types to database types. But generally, the process involves the following steps: 1. Implement odb::::value_traits specialization for the C++ type. In your case, if we assume the C++ type is called numeric, then it will be: #include namespace odb { namespace pgsql { template <> class value_traits { public: typedef numeric value_type; typedef numeric query_type; typedef details::buffer image_type; static void set_value (numeric& v, const details::buffer& b, std::size_t n, bool is_null) { ... } static void set_image (details::buffer& b, std::size_t& n, bool& is_null, const numeric& v) { ... } }; } } Generally, the signatures of the set_value()/set_image() vary depending on the database type (identifier by the second template argument in the template specialization; id_numeric in our case). The implementations of the above functions will need to read/write PostgreSQL NUMERIC values in the binary format. The PostgreSQL documentation has the following note about this format: "Values passed in binary format require knowledge of the internal representation expected by the backend. For example, integers must be passed in network byte order. Passing numeric values requires knowledge of the server storage format, as implemented in src/backend/utils/adt/numeric.c::numeric_send() and src/backend/utils/adt/numeric.c::numeric_recv()." I also found this thread on the pgsql-interfaces mailing list that could be helpful: http://archives.postgresql.org/pgsql-interfaces/2004-08/msg00000.php 2. Once the specialization is implemented and saved to, say, traits.hxx, the next step is to include it into the generated header files with the --hxx-prologue ODB compiler option: odb -d pgsql ... --hxx-prologue '#include "traits.hxx"' file.hxx 3. The final step is to tell the ODB compiler that data members of the numeric C++ type should be mapped to the NUMERIC PostgreSQL type. This can be done on the per-type or per-member basis (or both). For example, we could map the numeric C++ type to NUMERIC with default precision and scale and then customize the precision and/or scale on the per-member basis if needed: #pragma db value(numeric) type("NUMERIC") #pragma db object class person { ... #pragma db type("NUMERIC(3,1)") numeric hight_; // mapped to NUMERIC(3,1) numeric weight_; // mapped to NUMERIC }; Boris From Davide.Anastasia at qualitycapital.com Wed Mar 28 05:20:02 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Wed Mar 28 05:20:12 2012 Subject: [odb-users] Commit in batch Message-ID: Hi All, I am trying to write a custom output iterator for STL that persist a certain object using ODB. My application is quite fast and I would to commit every (let's say) 1000 updates, in order to decrease DB overhead. Is there a way to achieve that? Unfortunately, the object odb::transaction, once committed, cannot be restarted again (is that correct?). Best, Davide Anastasia Analyst, Research & Development Quality Capital Management Ltd. QCM House * Horizon Business Village No. 1 Brooklands Road Weybridge * Surrey KT13 0TJ United Kingdom Tel: +44 (0) 1932 334 400 Fax: +44 (0) 1932 334 415 Email: Davide.Anastasia@QualityCapital.com www.qualitycapital.com ________________________________ This email and any attachments are confidential and intended solely for the use of the individual(s) to whom it is addressed. Any views or opinions presented are solely those of the author and do not necessarily represent those of Quality Capital Management Ltd. If you are not the intended recipient, be advised that you have received this email in error and that any use, dissemination, printing, forwarding or copying of this email is strictly prohibited. Please contact the sender if you have received this email in error. You should also be aware that emails are susceptible to interference and you should not assume that the contents of this email originated from the sender above or that they have been accurately reproduced in their original form. Quality Capital Management Ltd is authorised and regulated by the Financial Services Authority in the UK and is a member of the National Futures Association in the US. ________________________________ From Davide.Anastasia at qualitycapital.com Wed Mar 28 05:20:26 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Wed Mar 28 05:20:55 2012 Subject: [odb-users] PostgreSQL NUMERIC type In-Reply-To: References: Message-ID: Hi Boris, Thanks a lot for your answer, it was really helpful. Best, Davide -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: 28 March 2012 08:37 To: Davide Anastasia Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] PostgreSQL NUMERIC type Hi Davide, Davide Anastasia writes: > We are currently trying to write a bespoke C++ class to support the > NUMERIC type on PostgreSQL. However, I haven't found an hint on how to > plug such a class into ODB seamlessly. Is there something I can read > that would help me find the right way? There is an example in the odb-examples package called 'mapping' that shows how to map (and re-map) C++ types to database types. But generally, the process involves the following steps: 1. Implement odb::::value_traits specialization for the C++ type. In your case, if we assume the C++ type is called numeric, then it will be: #include namespace odb { namespace pgsql { template <> class value_traits { public: typedef numeric value_type; typedef numeric query_type; typedef details::buffer image_type; static void set_value (numeric& v, const details::buffer& b, std::size_t n, bool is_null) { ... } static void set_image (details::buffer& b, std::size_t& n, bool& is_null, const numeric& v) { ... } }; } } Generally, the signatures of the set_value()/set_image() vary depending on the database type (identifier by the second template argument in the template specialization; id_numeric in our case). The implementations of the above functions will need to read/write PostgreSQL NUMERIC values in the binary format. The PostgreSQL documentation has the following note about this format: "Values passed in binary format require knowledge of the internal representation expected by the backend. For example, integers must be passed in network byte order. Passing numeric values requires knowledge of the server storage format, as implemented in src/backend/utils/adt/numeric.c::numeric_send() and src/backend/utils/adt/numeric.c::numeric_recv()." I also found this thread on the pgsql-interfaces mailing list that could be helpful: http://archives.postgresql.org/pgsql-interfaces/2004-08/msg00000.php 2. Once the specialization is implemented and saved to, say, traits.hxx, the next step is to include it into the generated header files with the --hxx-prologue ODB compiler option: odb -d pgsql ... --hxx-prologue '#include "traits.hxx"' file.hxx 3. The final step is to tell the ODB compiler that data members of the numeric C++ type should be mapped to the NUMERIC PostgreSQL type. This can be done on the per-type or per-member basis (or both). For example, we could map the numeric C++ type to NUMERIC with default precision and scale and then customize the precision and/or scale on the per-member basis if needed: #pragma db value(numeric) type("NUMERIC") #pragma db object class person { ... #pragma db type("NUMERIC(3,1)") numeric hight_; // mapped to NUMERIC(3,1) numeric weight_; // mapped to NUMERIC }; Boris From boris at codesynthesis.com Wed Mar 28 05:45:49 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Mar 28 05:40:54 2012 Subject: [odb-users] Commit in batch In-Reply-To: References: Message-ID: Hi Davide, Davide Anastasia writes: > My application is quite fast and I would to commit every (let's say) > 1000 updates, in order to decrease DB overhead. Is there a way to > achieve that? Unfortunately, the object odb::transaction, once > committed, cannot be restarted again (is that correct?). Hm, looks like having something like transaction::reset() would be useful here: transaction t (db.begin ()); ... t.commit (); t.reset (db.begin ()); ... t.commit (); I've added this to the TODO list for the next release. In the meantime you can use this approach, which is not very elegant but essentially equivalent: transaction t (db.begin ()); ... t.commit (); t.~transaction (); new (&t) transaction (db.begin ()); ... t.commit (); Boris From Davide.Anastasia at qualitycapital.com Wed Mar 28 05:44:47 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Wed Mar 28 05:46:06 2012 Subject: [odb-users] Commit in batch In-Reply-To: References: Message-ID: Hi Boris, I end up to this approach (essentially equivalent to your second one): boost::shared_ptr m_transaction(new odb::transaction(m_db->begin())); .... m_transaction->commit(); // commit transaction m_transaction.reset(new odb::transaction(m_db->begin())); // start new transaction ... m_transaction->commit(); // commit transaction Does this look better than t.~transaction (); ? Thanks a lot Boris, this library is such a great source of code insipiration for both my work and my personal projects. D. -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: 28 March 2012 10:46 To: Davide Anastasia Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Commit in batch Hi Davide, Davide Anastasia writes: > My application is quite fast and I would to commit every (let's say) > 1000 updates, in order to decrease DB overhead. Is there a way to > achieve that? Unfortunately, the object odb::transaction, once > committed, cannot be restarted again (is that correct?). Hm, looks like having something like transaction::reset() would be useful here: transaction t (db.begin ()); ... t.commit (); t.reset (db.begin ()); ... t.commit (); I've added this to the TODO list for the next release. In the meantime you can use this approach, which is not very elegant but essentially equivalent: transaction t (db.begin ()); ... t.commit (); t.~transaction (); new (&t) transaction (db.begin ()); ... t.commit (); Boris From Davide.Anastasia at qualitycapital.com Wed Mar 28 06:03:35 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Wed Mar 28 06:04:39 2012 Subject: [odb-users] Commit in batch In-Reply-To: References: Message-ID: Hi Boris, Actually, it's not that equivalent. Shared_ptr will allocate the memory every time, and this seems to be quite a big cost in fast applications. Your method decreased the overhead. Thanks, Davide -----Original Message----- From: odb-users-bounces@codesynthesis.com [mailto:odb-users-bounces@codesynthesis.com] On Behalf Of Davide Anastasia Sent: 28 March 2012 10:45 To: Boris Kolpackov Cc: odb-users@codesynthesis.com Subject: RE: [odb-users] Commit in batch Hi Boris, I end up to this approach (essentially equivalent to your second one): boost::shared_ptr m_transaction(new odb::transaction(m_db->begin())); .... m_transaction->commit(); // commit transaction m_transaction.reset(new odb::transaction(m_db->begin())); // start new transaction ... m_transaction->commit(); // commit transaction Does this look better than t.~transaction (); ? Thanks a lot Boris, this library is such a great source of code insipiration for both my work and my personal projects. D. -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: 28 March 2012 10:46 To: Davide Anastasia Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Commit in batch Hi Davide, Davide Anastasia writes: > My application is quite fast and I would to commit every (let's say) > 1000 updates, in order to decrease DB overhead. Is there a way to > achieve that? Unfortunately, the object odb::transaction, once > committed, cannot be restarted again (is that correct?). Hm, looks like having something like transaction::reset() would be useful here: transaction t (db.begin ()); ... t.commit (); t.reset (db.begin ()); ... t.commit (); I've added this to the TODO list for the next release. In the meantime you can use this approach, which is not very elegant but essentially equivalent: transaction t (db.begin ()); ... t.commit (); t.~transaction (); new (&t) transaction (db.begin ()); ... t.commit (); Boris From boris at codesynthesis.com Wed Mar 28 09:13:51 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Mar 28 09:08:57 2012 Subject: [odb-users] Commit in batch In-Reply-To: References: Message-ID: Hi Davide, Davide Anastasia writes: > Actually, it's not that equivalent. Shared_ptr will allocate the memory > every time, and this seems to be quite a big cost in fast applications. > Your method decreased the overhead. Yes, my approach is slightly more efficient, though compared to persisting 1000 objects, this probably won't make much difference. > Thanks a lot Boris, this library is such a great source of code > insipiration for both my work and my personal projects. Thanks, I am glad you are enjoying ODB. Boris From boris at codesynthesis.com Thu Mar 29 10:05:15 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Mar 29 10:00:23 2012 Subject: [odb-users] WTL + ODB / or maybe auto_ptr Exception: Invalid Address specified to RtlValidateHeap In-Reply-To: References: Message-ID: Hi Wayne, Wayne Hackle writes: > > Can you send me a test project so that I could try to reproduce and > > debug the problem? You can send it off-list. > > Here you go. Thanks for the test project. I took a look and the problem appears to be due to different runtimes used by the ODB DLLs and your project. ODB uses Multi-threaded DLL (which is the default) while your project uses Multi-threaded static. If I change your project to use the DLL runtime, everything works fine. To do this. go to Project->Properties-> C/C++-> Code Generation->Runtime Library and change "Multi-threaded Debug (/MTd)" to "Multi-threaded Debug DLL (/MDd)". Do the same for Release but use "Multi-threaded DLL (/MD)". Boris