From boris at codesynthesis.com Tue Sep 1 07:50:49 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 1 07:50:53 2015 Subject: [odb-users] Segmentation fault while executing odb compiler avoided adding a typedef sentence In-Reply-To: References: Message-ID: MM writes: > As I have the odb sources now, i am able to quickly test out any fix you > may think of. Before I can start thinking of a fix, I need a test case that reproduces the problem. Ideally, an archive with all the necessary headers and the ODB command line that you used. Thanks, Boris From markus at markusklemm.net Tue Sep 1 11:40:07 2015 From: markus at markusklemm.net (Markus Klemm) Date: Tue Sep 1 11:40:24 2015 Subject: [odb-users] ORDER BY clause in ODB query language In-Reply-To: References: Message-ID: <2FE30C1A-F0F9-4594-99FD-6F454B0D2A5D@markusklemm.net> I was close to start a new thread, but it basicly the same topic: My point in the previous question was, that I can't solve this use case below, without choosing the column by a string, rather than by a odb::query_column,yet?! I didn't minimized it completly because @Boris was wondering about the use cases. So obvouisly I'm not a fan of the one suggested future solution of using operator<, because ordering criteria changes/ depens on the column. This is the real usecase when using the framework Wt (e.g. part of the user supplied model for a table view). Raw Sourcecode below, gist here: https://gist.github.com/Superlokkus/a994d42534beca9ed5c6 void sort(int column, Wt::SortOrder order = Wt::AscendingOrder){ odb::query first_part("ORDER BY"), middle_part,end_part; //odb::query_column middle_type; and decltype(odb::query::added) middle_type; were my next guesses switch (column){ default: middle_part = odb::query::added;/*Error: no operator "=" matches these operands operand types are : odb::query = const odb::mssql::query_column*/ break; } switch (order){ case Wt::DescendingOrder: end_part = odb::query("DESC"); break; default: end_part = odb::query("ASC"); break; } odb::query final_query(first_part + middle_part + end_part); } Best Regards Markus Klemm > Am 27.08.2015 um 14:14 schrieb Boris Kolpackov : > > Hi Markus, > > Markus Klemm writes: > >> Is there a way to get a query with an ORDER BY clause with the typed >> checked, static, non-native ODB query language? The examples in the >> manual is using the database system-native query language e.g. a >> concatenated string. > > Currently you have to spell "ORDER BY" as a string, though the column > can be specified as a C++ name: > > db->query ((query::first == "John") + "ORDER BY" + query::age); > > We do plan to provide some syntactic sugar for this, though I am not > sure how much static type checking we will be able to do. For example, > should we assume if the C++ type provides operator<, then we can do > ORDER BY? > > >> That also makes it hard to use the ORDER BY clause because after >> the odb macro for the column, I need to concatenate the DESC/ASC >> clause but can?t due type mismatch. > > This should work: > > db->query ((...) + "ORDER BY" + query::age + "ASC"); > > BTW, "the odb macro for the column" is not a macro, it is a proper > C++ variable name. > > Boris From finjulhich at gmail.com Tue Sep 1 16:21:04 2015 From: finjulhich at gmail.com (MM) Date: Tue Sep 1 16:21:11 2015 Subject: [odb-users] Segmentation fault while executing odb compiler avoided adding a typedef sentence Message-ID: On 1 September 2015 at 12:50, Boris Kolpackov wrote: > MM writes: > > > As I have the odb sources now, i am able to quickly test out any fix you > > may think of. > > Before I can start thinking of a fix, I need a test case that reproduces > the problem. Ideally, an archive with all the necessary headers and the > ODB command line that you used. > > Thanks, > Boris > Please find attached 5 c++ files. Donwload them in the same directory and run: /usr/local/bin/odb --std c++11 -I/usr/local/include --database sqlite -I/usr/include derived_odb.hpp with odb built off master. This crashes. Please let me know if I missed to post something, Thanks, -------------- next part -------------- A non-text attachment was scrubbed... Name: base.hpp Type: text/x-c++hdr Size: 145 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20150901/bad07942/base.hpp -------------- next part -------------- A non-text attachment was scrubbed... Name: base_odb.hpp Type: text/x-c++hdr Size: 119 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20150901/bad07942/base_odb.hpp -------------- next part -------------- A non-text attachment was scrubbed... Name: cloneable.hpp Type: text/x-c++hdr Size: 219 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20150901/bad07942/cloneable.hpp -------------- next part -------------- A non-text attachment was scrubbed... Name: derived.hpp Type: text/x-c++hdr Size: 92 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20150901/bad07942/derived.hpp -------------- next part -------------- A non-text attachment was scrubbed... Name: derived_odb.hpp Type: text/x-c++hdr Size: 206 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20150901/bad07942/derived_odb.hpp From yoav.weiss at intel.com Wed Sep 2 07:42:52 2015 From: yoav.weiss at intel.com (Weiss, Yoav) Date: Wed Sep 2 07:43:03 2015 Subject: [odb-users] A view on top of several tables from different sqlite files (DB) Message-ID: Hi, My question is related to views with multiple tables like: #pragma db view object (Cell = c) \ object (Instance = i : c::m_id == i::m_cell_id) \ query((?) + " GROUP BY " + c::m_name) struct CellOccCount { #pragma db column("c.cell_name") std::string m_name; #pragma db column ("count(*)") long m_count; }; And the way I query the view is: odb::result results(m_p_db->query(query_cond)); Now suppose these 2 tables (Cell and Instance) are located in 2 different sqlite databases. My questions are: 1. How should I modify the view (if at all) to reflect this? 2. On which odb::database should I initiate the query (assuming I have 2 instances - one for each database)? Thanks, Yoav --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. From boris at codesynthesis.com Wed Sep 2 11:31:54 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 2 11:31:58 2015 Subject: [odb-users] A view on top of several tables from different sqlite files (DB) In-Reply-To: References: Message-ID: Hi Yoav, Weiss, Yoav writes: > #pragma db view object (Cell = c) \ > object (Instance = i : c::m_id == i::m_cell_id) \ > query((?) + " GROUP BY " + c::m_name) > struct CellOccCount { > #pragma db column("c.cell_name") > std::string m_name; > > #pragma db column ("count(*)") > long m_count; > }; > > And the way I query the view is: > odb::result results(m_p_db->query(query_cond)); > > Now suppose these 2 tables (Cell and Instance) are located in 2 different > sqlite databases. My questions are: > > 1. How should I modify the view (if at all) to reflect this? The view doesn't need to be modified, but see #2 below. > 2. On which odb::database should I initiate the query (assuming I have > 2 instances - one for each database)? No, that's not going to work. You cannot have a query span multiple SQLite connections. Instead, what you will have to do is attach the second database file to the existing connection with the SQLite ATTACH DATABASE statement: https://www.sqlite.org/lang_attach.html In ODB you can use execute(), for example: m_p_db->execute ("ATTACH DATABASE cell.sqlite AS cells"); If you don't have identically names tables in the two databases, then you should be all set. Otherwise, you would have to qualify the table names, for example: #pragma db object table("cells.Cell") class Cell { ... }; Boris From markus at markusklemm.net Thu Sep 3 09:32:33 2015 From: markus at markusklemm.net (Markus Klemm) Date: Thu Sep 3 09:32:48 2015 Subject: [odb-users] Query object A by range of objects B, with 1:n relation Message-ID: <91197426-FA08-473F-89F5-BA264AFC1379@markusklemm.net> I have a problem using the odb query language with a one to many relationship. Suppose I have a persistent class file and directory. These have a bidirection one-to-many relationship. To query a set of files with criteria of one directory I successfully used the directory member of the query class. But how do I use it with a range of directories, i.e. all files from this set of directories. To get more concrete, said I have the definitions: #pragma db object table("directories") session pointer(std::shared_ptr) struct directory{ #pragma db column("directory_id") type("uniqueidentifier") id not_null boost::uuids::uuid directory_id; #pragma db inverse(directory) std::vector> files;}}; #pragma db object table("files") session pointer(std::shared_ptr) struct file{ #pragma db column("file_id") type("uniqueidentifier") id not_null boost::uuids::uuid file_id; #pragma db column("directory_id") not_null std::weak_ptr directory;}; So for one directory the query is obvious: query(query::directory == query::_val(directory_instance)). But the two solutions I've come to have 2 different problems: Solution 1: set directories; odb::query::directory->directory_id.in_range(directories.cbegin(),directories.cend()); Fails with a sql exception, "wrong syntax near directory_id" Solution 2: std::set directories odb::query::directory.in_range(directories.cbegin(),directories.cend()); Can't compile because there is, I assume, no overload of in_range() for directory. (Error is 'odb::mssql::val_bind::val_bind' : none of the 2 overloads could convert all the argument types) Can I solve this with the odb query language? Thanks in advance and best regards/Mit freundlichen Gr??en Markus Klemm From finjulhich at gmail.com Thu Sep 3 10:18:42 2015 From: finjulhich at gmail.com (MM) Date: Thu Sep 3 10:18:48 2015 Subject: [odb-users] Segmentation fault while executing odb compiler avoided adding a typedef sentence Message-ID: Just checking my previous post about the reproducer arrived to the mailing list. I am having gmail issues, it's rejecting some sends becaus it's thinking i'm spaming:-) Thanks From boris at codesynthesis.com Thu Sep 3 10:50:37 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 3 10:50:46 2015 Subject: [odb-users] Query object A by range of objects B, with 1:n relation In-Reply-To: <91197426-FA08-473F-89F5-BA264AFC1379@markusklemm.net> References: <91197426-FA08-473F-89F5-BA264AFC1379@markusklemm.net> Message-ID: Hi Markus, Markus Klemm writes: > set directories; > odb::query::directory->directory_id.in_range(directories.cbegin(),directories.cend()); > Fails with a sql exception, "wrong syntax near directory_id" I believe you are getting this error because the range is empty. This, BTW, has been fixed for the next release of ODB. Also, chances are, your next question will be how to find files that belong to directories that in turn match a certain query condition. For that you would need to use ODB views (Chapter 10). Boris From markus at markusklemm.net Thu Sep 3 11:09:49 2015 From: markus at markusklemm.net (Markus Klemm) Date: Thu Sep 3 11:10:04 2015 Subject: [odb-users] Query object A by range of objects B, with 1:n relation In-Reply-To: References: <91197426-FA08-473F-89F5-BA264AFC1379@markusklemm.net> Message-ID: I figured out the problem in the instant you replied: Solution 1 was right, but I accidentialy built the final query with the order query first. But thank you very much for the odb view tip, I stick very close to the documentation, and read it thru first, but I wasn't aware/forggot that views are the way to go for this transitive purpose: Thank you and I'm sorry. Good day and Mit freundlichen Gr??en Markus Klemm > Am 03.09.2015 um 16:50 schrieb Boris Kolpackov : > > Hi Markus, > > Markus Klemm writes: > >> set directories; >> odb::query::directory->directory_id.in_range(directories.cbegin(),directories.cend()); >> Fails with a sql exception, "wrong syntax near directory_id" > > I believe you are getting this error because the range is empty. This, > BTW, has been fixed for the next release of ODB. > > Also, chances are, your next question will be how to find files > that belong to directories that in turn match a certain query > condition. For that you would need to use ODB views (Chapter 10). > > Boris From boris at codesynthesis.com Fri Sep 4 09:31:47 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Sep 4 09:31:56 2015 Subject: [odb-users] Segmentation fault while executing odb compiler avoided adding a typedef sentence In-Reply-To: References: Message-ID: MM writes: > Please find attached 5 c++ files. Thanks for the test. The problem is again with the order in which ODB "sees" C++ classes. I've added some more diagnostics (available in master) with which your test case produces: derived.hpp:4:8: error: base class derived_from_base must be defined before derived class Derived derived_odb.hpp:5:12: info: class derived_from_base is define here I've re-arranged the order of things in your derived_odb.hpp to be: #include "base_odb.hpp" #include "cloneable.hpp" struct Derived; using derived_from_base = cloneable; #pragma db object(derived_from_base) abstract definition #include "derived.hpp" #pragma db object(Derived) table("TD") definition That and adding '#pragma once' to cloneable.hpp fixes the error and even produces compilable code. If you meditate on it, the order in which things are now included/defined actually makes quite a bit of sense. Boris From boris at codesynthesis.com Fri Sep 4 09:37:55 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Sep 4 09:38:04 2015 Subject: [odb-users] Segmentation fault while executing odb compiler avoided adding a typedef sentence In-Reply-To: References: Message-ID: MM writes: > Just checking my previous post about the reproducer arrived to the mailing > list. You can always check the archives: http://www.codesynthesis.com/pipermail/odb-users/ Boris From boris at codesynthesis.com Fri Sep 4 10:41:58 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Sep 4 10:42:06 2015 Subject: [odb-users] ORDER BY clause in ODB query language In-Reply-To: <2FE30C1A-F0F9-4594-99FD-6F454B0D2A5D@markusklemm.net> References: <2FE30C1A-F0F9-4594-99FD-6F454B0D2A5D@markusklemm.net> Message-ID: Hi Markus, Markus Klemm writes: > Raw Sourcecode below [...] Wouldn't something like this work: using dir_query = odb::query; dir_query q ("ORDER BY"); switch (column) { case added: q += dir_query::added; ... } switch (order) { case desc: q += "DESC"; ... } db.query (q); Boris From finjulhich at gmail.com Fri Sep 4 16:40:29 2015 From: finjulhich at gmail.com (MM) Date: Fri Sep 4 16:40:36 2015 Subject: [odb-users] Segmentation fault while executing odb compiler avoided adding a typedef sentence Message-ID: On 4 September 2015 at 14:31, Boris Kolpackov wrote: > MM writes: > > > Please find attached 5 c++ files. > > Thanks for the test. The problem is again with the order in which > ODB "sees" C++ classes. I've added some more diagnostics (available > in master) with which your test case produces: > > derived.hpp:4:8: error: base class derived_from_base must be defined > before derived class Derived > derived_odb.hpp:5:12: info: class derived_from_base is define here > > I've re-arranged the order of things in your derived_odb.hpp to be: > > #include "base_odb.hpp" > > #include "cloneable.hpp" > struct Derived; > using derived_from_base = cloneable; > #pragma db object(derived_from_base) abstract definition > > #include "derived.hpp" > #pragma db object(Derived) table("TD") definition > > That and adding '#pragma once' to cloneable.hpp fixes the error and > even produces compilable code. > > If you meditate on it, the order in which things are now included/defined > actually makes quite a bit of sense. > > Boris > Indeed, reordering fixes the odb compiler crash. My executable builds. Post successful link, I generate the sql once with odb. I have the following snippet that tries to adapt boost::gregorian::date_period as I don't see it in the profile.. namespace boost { namespace gregorian { #pragma db value(date_period) transient definition #pragma db member(date_period::begin) virtual(date) get(begin())\ set(this = ::boost::gregorian::date_period((?), this.end())) #pragma db member(date_period::end) virtual(date) get(end())\ set(this = ::boost::gregorian::date_period(this.begin(), (?))) } } odb barks for the same reason:-) Is this why only date is in the boost/date_time subprofile :-) Any workaround you think of? My onw wrapper class around date_period? Thanks MM From soroush.rabiei at gmail.com Sun Sep 6 06:53:31 2015 From: soroush.rabiei at gmail.com (Soroush Rabiei) Date: Sun Sep 6 06:53:58 2015 Subject: [odb-users] nullable unsigned variables Message-ID: Hi I have a problem using nullable types aka `odb::nullable'. It seems it can't handle `unsigned' variables. Here is a small test and it's output error: #include > #include > class foo > { > friend class odb::access; > private: > odb::nullable x; > }; > #pragma db object(foo) no_id table("foo_table") > #pragma db member(foo::x) column("X") I'm getting these errors: g++ --std=c++11 -c -Wall -Wextra -Wno-unknown-pragmas --pedantic > test-odb.cxx > test-odb.cxx: In static member function ?static void > odb::access::object_traits_impl (odb::database_id)3u>::init(odb::access::object_traits_impl (odb::database_id)3u>::image_type&, const object_type&, > odb::oracle::statement_kind)?: > test-odb.cxx:70:30: error: no matching function for call to > ?odb::oracle::value_traits, > (odb::oracle::database_type_id)0u>::set_image(int&, bool&, const > odb::nullable&)? > test-odb.cxx:70:30: note: candidates are: > In file included from test-odb.cxx:13:0: > /usr/include/odb/oracle/traits.hxx:351:7: note: static void > odb::oracle::wrapped_value_traits true>::set_image(odb::oracle::wrapped_value_traits true>::image_type&, bool&, const W&) [with W = odb::nullable int>; odb::oracle::database_type_id ID = (odb::oracle::database_type_id)0u; > odb::oracle::wrapped_value_traits::image_type = unsigned int] > /usr/include/odb/oracle/traits.hxx:351:7: note: no known conversion for > argument 1 from ?int? to > ?odb::oracle::wrapped_value_traits, > (odb::oracle::database_type_id)0u, true>::image_type& {aka unsigned int&}? > /usr/include/odb/oracle/traits.hxx:373:7: note: static void > odb::oracle::wrapped_value_traits::set_image(char*, > std::size_t, std::size_t&, bool&, const W&) [with W = odb::nullable unsigned int>; odb::oracle::database_type_id ID = > (odb::oracle::database_type_id)0u; std::size_t = long unsigned int] > /usr/include/odb/oracle/traits.hxx:373:7: note: candidate expects 5 > arguments, 3 provided > /usr/include/odb/oracle/traits.hxx:388:7: note: static void > odb::oracle::wrapped_value_traits::set_image(char*, > std::size_t&, bool&, const W&) [with W = odb::nullable; > odb::oracle::database_type_id ID = (odb::oracle::database_type_id)0u; > std::size_t = long unsigned int] > /usr/include/odb/oracle/traits.hxx:388:7: note: candidate expects 4 > arguments, 3 provided > /usr/include/odb/oracle/traits.hxx:408:7: note: static void > odb::oracle::wrapped_value_traits::set_image(bool (*&)(const > void*, ub4*, const void**, ub4*, odb::oracle::chunk_position*, void*, ub4), > const void*&, bool&, const W&) [with W = odb::nullable; > odb::oracle::database_type_id ID = (odb::oracle::database_type_id)0u; > odb::oracle::param_callback_type = bool (*)(const void*, unsigned int*, > const void**, unsigned int*, odb::oracle::chunk_position*, void*, unsigned > int); ub4 = unsigned int] > /usr/include/odb/oracle/traits.hxx:408:7: note: candidate expects 4 > arguments, 3 provided > make: *** [test-odb.o] Error 1 From yoav.weiss at intel.com Sun Sep 6 11:10:29 2015 From: yoav.weiss at intel.com (Weiss, Yoav) Date: Sun Sep 6 11:10:41 2015 Subject: [odb-users] A view on top of several tables from different sqlite files (DB) In-Reply-To: References: Message-ID: Sounds promising. I still have an issue though. When I call m_p_db->execute ("ATTACH DATABASE cell.sqlite AS cells") I get: operation can only be performed in transaction So I did: m_p_db->connection()->execute ("ATTACH DATABASE cell.sqlite AS cells") Which worked fine, but the first query (using m_p_db->query_one()) on a table inside cells DB, I got: 1: no such table: hier_version I think this is caused by me using the connection pointer, but I'm not sure. Table names are unique across databases Yoav -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Wednesday, September 02, 2015 18:32 To: Weiss, Yoav Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] A view on top of several tables from different sqlite files (DB) Hi Yoav, Weiss, Yoav writes: > #pragma db view object (Cell = c) \ > object (Instance = i : c::m_id == i::m_cell_id) \ > query((?) + " GROUP BY " + c::m_name) struct > CellOccCount { > #pragma db column("c.cell_name") > std::string m_name; > > #pragma db column ("count(*)") > long m_count; > }; > > And the way I query the view is: > odb::result > results(m_p_db->query(query_cond)); > > Now suppose these 2 tables (Cell and Instance) are located in 2 > different sqlite databases. My questions are: > > 1. How should I modify the view (if at all) to reflect this? The view doesn't need to be modified, but see #2 below. > 2. On which odb::database should I initiate the query (assuming I have > 2 instances - one for each database)? No, that's not going to work. You cannot have a query span multiple SQLite connections. Instead, what you will have to do is attach the second database file to the existing connection with the SQLite ATTACH DATABASE statement: https://www.sqlite.org/lang_attach.html In ODB you can use execute(), for example: m_p_db->execute ("ATTACH DATABASE cell.sqlite AS cells"); If you don't have identically names tables in the two databases, then you should be all set. Otherwise, you would have to qualify the table names, for example: #pragma db object table("cells.Cell") class Cell { ... }; Boris --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. From finjulhich at gmail.com Sun Sep 6 17:19:34 2015 From: finjulhich at gmail.com (MM) Date: Sun Sep 6 17:19:42 2015 Subject: [odb-users] 2-table query Message-ID: Hello, I have the following 2 tables and their relevant columns: M == id: PRIMARY KEY month1: TEXT (encoded month,year combination) month2: TEXT F == id: PRIMARY KEY mid: NOT NULL REFERENCES M("id") month: TEXT There can 0..N rows in F for each row in M. My question is two-fold: 1. How do I select all the F rows such that their month is 1 of the 2months in the relevant M row (the one where F.mid=M.id)? 2. How do I express this with an odb:query? Both M and F tables are the mapping of c++ classes. db is sqlite. F has about 100 000 rows. The result of the query is about 200. Thanks, MM From markus at markusklemm.net Mon Sep 7 08:19:17 2015 From: markus at markusklemm.net (Markus Klemm) Date: Mon Sep 7 08:19:32 2015 Subject: [odb-users] Inverse pragma using composite value types Message-ID: <632BCDC6-2C6F-4D49-9968-21416609E465@markusklemm.net> Hi again everyone, I have the problem that the inverse pragma don't work with composite value types. I fails to parse the . operator correctly. The problematic scenario is that object A's ID is part of object B's composite ID. I'm of course not sure if ODB ever had in mind to offer that solution or if it is expected that I use a odb view. Example (or link here for syntax highlighting https://gist.github.com/Superlokkus/44d69167ca1a82e150e9 ) Given tables: create table measurement_set( measurement_id uniqueidentifier primary key ) create table measurement_parameter( measurement_set_id uniqueidentifier not null foreign key references measurement_set(id_col), parameter_name nvarchar(32) not null, --other columns constraint pk primary key(measurement_set_id,parameter_name) ) I suppose the solution should be: struct measurement_set; #pragma db value struct measurement_parameter_key{ #pragma db column("measurement_set_id") type("uniqueidentifier") not_null boost::uuids::uuid measurement_set_id; #pragma db column("parameter_name") type("nvarchar(32)") not_null std::wstring parameter_name; }; #pragma db object table("measurement_parameter") struct measurement_parameter{ #pragma db id measurement_parameter_key measurement_set_id; /* Other members*/ }; #pragma db object table("measurement_set") struct measurement_set { #pragma db column("measurement_id") type("uniqueidentifier") id not_null boost::uuids::uuid measurement_id; #pragma db inverse(measurement_set_id.measurement_set_id) //^ odb parser: error: ')' expected at the end of db pragma inverse std::set parameters; /* Other members*/ }; Regards and Boris thank you especially in advance for your time and patience Markus Klemm From adanesh at noornet.net Sat Sep 5 06:26:06 2015 From: adanesh at noornet.net (=?utf-8?B?2LnZhNuMINiv2KfZhti0?=) Date: Mon Sep 7 10:14:31 2015 Subject: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type Message-ID: <9c80cadbfcf747068d7a391042134ea4@exch.crcis.local> Hi, First, thanks for the work on this great tool. I have a problem with QDate and sqlite database when QDate is mapped with TEXT type (default behavior). When it is mapped with INTEGER there is no problem, but when it is mapped with TEXT, it is persisted correctly, but retrieved incorrectly (it looks like an uninitialized variable!) Test code: Using odb-2.4.0 and Visual Studio 2013 and Qt 5.4.0 1- odb.exe --std c++11 --profile qt --database sqlite --generate-query --generate-schema "%(Identity)" -I "$(MSBuildProjectDirectory)" -I "$(QTDIR)\\include" -I "$(QTDIR)\\include\\QtCore" 2- test_qdate.h: #pragma once #include #include #include "odb/core.hxx" #pragma db object pointer(std::shared_ptr) class ProgramModel { public: #pragma db id auto int m_id; QString m_title; #pragma db type("TEXT") QDate m_insertDate; }; 3- test_qdate.cpp: #include #include #include #include #include #include "odb/schema-catalog.hxx" #include "test_qdate.h" #include "test_qdate-odb.hxx" auto DATABASE_NAME = L"test.sqlite"; void createDB() { auto db = std::make_shared(DATABASE_NAME, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); odb::transaction t(db->begin()); try { odb::schema_catalog::create_schema(*db, "", false); } catch (odb::exception&) { } t.commit(); } int persist(std::shared_ptr& program) { auto db = std::make_shared(DATABASE_NAME, SQLITE_OPEN_READWRITE); odb::transaction t(db->begin()); auto id = db->persist(program); t.commit(); return id; } std::shared_ptr load(int id) { auto db = std::make_shared(DATABASE_NAME, SQLITE_OPEN_READWRITE); odb::transaction t(db->begin()); auto result = db->load(id); t.commit(); return result; } int main(int argc, char* argv[]) { createDB(); auto item1 = std::make_shared(); item1->m_title = "test"; item1->m_insertDate = QDate::currentDate(); //--- auto item2 = load(persist(item1)); assert(item1->m_insertDate == item2->m_insertDate); return 0; } Best regards, Ali From markus at markusklemm.net Mon Sep 7 10:59:42 2015 From: markus at markusklemm.net (Markus Klemm) Date: Mon Sep 7 10:59:55 2015 Subject: [odb-users] ORDER BY clause in ODB query language Message-ID: <3868BE88-67A0-4118-989D-090B23CE52C6@markusklemm.net> Hi Boris, I didn't use the += operator, because it causes compiler errors for at least the wstring members. Surprisingly the bit type works. I updated the according gist ( https://gist.github.com/Superlokkus/a994d42534beca9ed5c6 ), added the erros to the relevant lines and also added the object definition. But as always, already a big thank you, for your efforts and this still great library. Regards Markus Klemm > Am 04.09.2015 um 16:41 schrieb Boris Kolpackov : > > Hi Markus, > > Markus Klemm writes: > >> Raw Sourcecode below [...] > > Wouldn't something like this work: > > using dir_query = odb::query; > > dir_query q ("ORDER BY"); > > switch (column) > { > case added: > q += dir_query::added; > ... > } > > switch (order) > { > case desc: > q += "DESC"; > ... > } > > db.query (q); > > Boris From boris at codesynthesis.com Mon Sep 7 12:00:54 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 7 12:01:01 2015 Subject: [odb-users] A view on top of several tables from different sqlite files (DB) In-Reply-To: References: Message-ID: Hi Yoav, Weiss, Yoav writes: > So I did: m_p_db->connection()->execute ("ATTACH DATABASE cell.sqlite > AS cells") Which worked fine, but the first query (using > m_p_db->query_one()) on a table inside cells DB, I got: 1: no such > table: hier_version > > I think this is caused by me using the connection pointer, but I'm > not sure. It would only be a problem if your application needed several connections at the same time. If you executed the two statements one after another, the query_one() would reuse the connection that was created for the first. Try to qualify the table name with the database name as I suggested in my previous reply. I am suspecting this ability to use unqualified table names with multiple databases is a recent addition to SQLite. Boris From finjulhich at gmail.com Mon Sep 7 12:23:10 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 7 12:23:17 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: On 6 September 2015 at 22:19, MM wrote: > Hello, > > I have the following 2 tables and their relevant columns: > > M > == > id: PRIMARY KEY > month1: TEXT (encoded month,year combination) > month2: TEXT > > F > == > id: PRIMARY KEY > mid: NOT NULL REFERENCES M("id") > month: TEXT > > There can 0..N rows in F for each row in M. > > My question is two-fold: > > 1. How do I select all the F rows such that their month is 1 of the > 2months in the relevant M row (the one where F.mid=M.id)? > > from stackoverflow, this is simply: SELECT * FROM F LEFT OUTER JOIN M ON F.mid = M.ID WHERE (F.month = M.month1 OR F.month = M.month2) > > 1. How do I express this with an odb:query? Both M and F tables are > the mapping of c++ classes. > > db is sqlite. F has about 100 000 rows. The result of the query is about > 200. > > Thanks, > MM > Is this expressable as a high-level odb query? typedef odb::query Query; db.query( Query::.month.in( .......... , ......... ) ) ? MM From boris at codesynthesis.com Mon Sep 7 12:33:44 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 7 12:33:52 2015 Subject: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type In-Reply-To: <9c80cadbfcf747068d7a391042134ea4@exch.crcis.local> References: <9c80cadbfcf747068d7a391042134ea4@exch.crcis.local> Message-ID: Hi Ali, > I have a problem with QDate and sqlite database when QDate is mapped > with TEXT type (default behavior). When it is mapped with INTEGER > there is no problem, but when it is mapped with TEXT, it is persisted > correctly, but retrieved incorrectly (it looks like an uninitialized > variable!) We have the TEXT mapping exercised in the ODB test suite and everything works correctly, including on Windows. So we will have to do a little debugging to figure out what's going on. Specifically, can you set the breakpoint in file: libodb-qt/odb/qt/date-time/sqlite/qdate-traits.hxx Line 37 (the 'if (is_null)' statement in set_value()). Then run your test and see what happens there. Specifically, you want to look at i.data() and 'n' and verify that they describe the correct string representation of the date. Boris From boris at codesynthesis.com Mon Sep 7 12:36:01 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 7 12:36:07 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: Hi, MM writes: > SELECT * FROM > F LEFT OUTER JOIN M ON F.mid = M.ID > WHERE (F.month = M.month1 OR F.month = M.month2) Good, this is much better than saying "I need to achieve X, do it for me". > Is this expressable as a high-level odb query? Yes, pretty easily using ODB views. Boris From boris at codesynthesis.com Mon Sep 7 12:41:54 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 7 12:42:00 2015 Subject: [odb-users] Inverse pragma using composite value types In-Reply-To: <632BCDC6-2C6F-4D49-9968-21416609E465@markusklemm.net> References: <632BCDC6-2C6F-4D49-9968-21416609E465@markusklemm.net> Message-ID: Hi Markus, Markus Klemm writes: > I have the problem that the inverse pragma don't work with composite > value types. I fails to parse the . operator correctly. The problematic > scenario is that object A's ID is part of object B's composite ID. No, ODB doesn't support inverse relationships on "half an object id". Boris From boris at codesynthesis.com Mon Sep 7 13:13:45 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 7 13:13:52 2015 Subject: [odb-users] nullable unsigned variables In-Reply-To: References: Message-ID: Hi Soroush, Soroush Rabiei writes: > I have a problem using nullable types aka `odb::nullable'. It seems it > can't handle `unsigned' variables. Yes, that's an Oracle-specific bug in the ODB compiler which I have now fixed: http://scm.codesynthesis.com/?p=odb/odb.git;a=commit;h=f70642bcdc61d679981a55ce9bcd88c08c8dadc1 Thanks for the report and the test case, much appreciated! Boris From adanesh at noornet.net Tue Sep 8 04:35:07 2015 From: adanesh at noornet.net (=?utf-8?B?2LnZhNuMINiv2KfZhti0?=) Date: Tue Sep 8 04:35:18 2015 Subject: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type In-Reply-To: References: <9c80cadbfcf747068d7a391042134ea4@exch.crcis.local> Message-ID: Hi Boris, Thanks for your reply. The problem is related to my operating system locale, because Qt uses operating system locale. My OS locale is Persian. odb\qt\date-time\sqlite\qdate-traits.hxx, Line 64: std::string s (v.toString ("yyyy-MM-dd").toLatin1 ().constData ()); must be changed to: std::string s(QLocale(QLocale::English).toString(v, "yyyy-MM-dd").toLatin1().constData()); There are some other places that must be corrected. Best regards, Ali -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Monday, September 7, 2015 9:04 PM To: ??? ???? Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type Hi Ali, > I have a problem with QDate and sqlite database when QDate is mapped > with TEXT type (default behavior). When it is mapped with INTEGER > there is no problem, but when it is mapped with TEXT, it is persisted > correctly, but retrieved incorrectly (it looks like an uninitialized > variable!) We have the TEXT mapping exercised in the ODB test suite and everything works correctly, including on Windows. So we will have to do a little debugging to figure out what's going on. Specifically, can you set the breakpoint in file: libodb-qt/odb/qt/date-time/sqlite/qdate-traits.hxx Line 37 (the 'if (is_null)' statement in set_value()). Then run your test and see what happens there. Specifically, you want to look at i.data() and 'n' and verify that they describe the correct string representation of the date. Boris From yoav.weiss at intel.com Tue Sep 8 08:57:39 2015 From: yoav.weiss at intel.com (Weiss, Yoav) Date: Tue Sep 8 08:57:50 2015 Subject: [odb-users] A view on top of several tables from different sqlite files (DB) In-Reply-To: References: Message-ID: Hi Boris, My issue was resolved. I simply saved the connection ptr (by using the database::connection() API) and used it for all subsequent queries and transactions. I didn't need to qualify my tables since they have unique names across the 2 database schemas. I simply used --schema-name switch in the odb code generation to create specific tables in specific databases. Thanks for your help. Yoav -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Monday, September 07, 2015 19:01 To: Weiss, Yoav Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] A view on top of several tables from different sqlite files (DB) Hi Yoav, Weiss, Yoav writes: > So I did: m_p_db->connection()->execute ("ATTACH DATABASE cell.sqlite > AS cells") Which worked fine, but the first query (using > m_p_db->query_one()) on a table inside cells DB, I got: 1: no such > table: hier_version > > I think this is caused by me using the connection pointer, but I'm not > sure. It would only be a problem if your application needed several connections at the same time. If you executed the two statements one after another, the query_one() would reuse the connection that was created for the first. Try to qualify the table name with the database name as I suggested in my previous reply. I am suspecting this ability to use unqualified table names with multiple databases is a recent addition to SQLite. Boris --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. From markus at markusklemm.net Tue Sep 8 10:50:37 2015 From: markus at markusklemm.net (Markus Klemm) Date: Tue Sep 8 10:50:52 2015 Subject: [odb-users] Inverse pragma using composite value types In-Reply-To: References: <632BCDC6-2C6F-4D49-9968-21416609E465@markusklemm.net> Message-ID: <0723AC01-43E4-4A13-9519-F3EE66B04A97@markusklemm.net> Good day Boris, so I guess support for views is not intented either?! Because #pragma db view object(measurement_parameter) object(measurement_set:measurement_parameter::measurement_parameter_key. measurement_set_id) which is what I'm guessing would be the right prgma for a object view, is not working due a missing query conversion. I wouldn't call it "half an object id" but rather "natural key" (instead of a surrogate key). Regards Markus Klemm > Am 07.09.2015 um 18:41 schrieb Boris Kolpackov : > > Hi Markus, > > Markus Klemm writes: > >> I have the problem that the inverse pragma don't work with composite >> value types. I fails to parse the . operator correctly. The problematic >> scenario is that object A's ID is part of object B's composite ID. > > No, ODB doesn't support inverse relationships on "half an object id". > > Boris From boris at codesynthesis.com Tue Sep 8 10:58:30 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 8 10:58:35 2015 Subject: [odb-users] Inverse pragma using composite value types In-Reply-To: <0723AC01-43E4-4A13-9519-F3EE66B04A97@markusklemm.net> References: <632BCDC6-2C6F-4D49-9968-21416609E465@markusklemm.net> <0723AC01-43E4-4A13-9519-F3EE66B04A97@markusklemm.net> Message-ID: Hi Markus, Markus Klemm writes: > so I guess support for views is not intented either?! No you should be able to slice & dice it pretty much any way you want with an ODB view. > Because #pragma db view object(measurement_parameter) > object(measurement_set:measurement_parameter::measurement_parameter_key.measurement_set_id) Since this is not a relationship in ODB terms, you will have to spell out the actual JOIN condition. See the manual, it has examples of this. Boris From boris at codesynthesis.com Tue Sep 8 11:05:03 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 8 11:05:08 2015 Subject: [odb-users] A view on top of several tables from different sqlite files (DB) In-Reply-To: References: Message-ID: Hi Yoav, Weiss, Yoav writes: > My issue was resolved. I simply saved the connection ptr (by using > the database::connection() API) and used it for all subsequent > queries and transactions. Glad to hear it is working now. For completeness, if you don't want to have to deal with connection_ptr, then the "proper" way to implement this would be to provide a derived connection_pool implementation that attaches all the necessary databases for every connection that is created. If you are interested, see Section 18.3, "SQLite Connection and Connection Factory". The function you would want to override is connection_pool_factory::create() in which you would first call the base version to actually create the connection and then attach all the databases to it before returning. Boris From boris at codesynthesis.com Tue Sep 8 11:29:52 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 8 11:29:58 2015 Subject: [odb-users] ORDER BY clause in ODB query language In-Reply-To: <3868BE88-67A0-4118-989D-090B23CE52C6@markusklemm.net> References: <3868BE88-67A0-4118-989D-090B23CE52C6@markusklemm.net> Message-ID: Hi Markus, Markus Klemm writes: > I didn't use the += operator, because it causes compiler errors I've added the missing operator. Can you apply this patch and let me know if there are any issues remaining: http://scm.codesynthesis.com/?p=odb/libodb-mssql.git;a=commit;h=2d228c59fc6bd96944f91912c2b174cc63f56aab Thanks, Boris From markus at markusklemm.net Tue Sep 8 12:47:24 2015 From: markus at markusklemm.net (Markus Klemm) Date: Tue Sep 8 12:47:49 2015 Subject: [odb-users] ORDER BY clause in ODB query language In-Reply-To: References: <3868BE88-67A0-4118-989D-090B23CE52C6@markusklemm.net> Message-ID: <751E0A8C-D4A8-4AFC-897C-A51ED2F31FA8@markusklemm.net> I'd love to but: in contrast to the 2.4.0 package, opening the project with visual studio 2013 express does not work anymore (output below), but because my shift just ends in a couple of minutes I applied the patch on the used package, e.g. used header, manually instead. But I'm not sure if it's due that I just changed the header or if there is a problem, it didn't work. But I wanted to give a 'quick' response: [Microsoft][SQL Server Native Client 11.0][SQL Server]Falsche Syntax in der N?he von ')'. 8180 (42000): [Microsoft][SQL Server Native Client 11.0][SQL Server]Anweisung(en ) konnte(n) nicht vorbereitet werden." Translation: Wrong syntax around ')'... query could not be perpared. (I'm sorry for the german error message, microsoft ;-( ) Visual Studio 2013 express error: C:\Users\klm\Downloads\libodb-mssql\odb\mssql\libodb-mssql-vc12.vcxproj : error : Unable to read the project file "libodb-mssql-vc12.vcxproj". C:\Users\klm\Downloads\libodb-mssql\odb\mssql\libodb-mssql-vc12.vcxproj(173,3): The element <#text> beneath element is unrecognized. Regards/ Mit freundlichen Gr??en Markus Klemm Gesendet via Mobiltelefon > Am 08.09.2015 um 17:29 schrieb Boris Kolpackov : > > Hi Markus, > > Markus Klemm writes: > >> I didn't use the += operator, because it causes compiler errors > > I've added the missing operator. Can you apply this patch and let > me know if there are any issues remaining: > > http://scm.codesynthesis.com/?p=odb/libodb-mssql.git;a=commit;h=2d228c59fc6bd96944f91912c2b174cc63f56aab > > Thanks, > Boris From boris at codesynthesis.com Wed Sep 9 11:12:59 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 9 11:13:04 2015 Subject: [odb-users] ORDER BY clause in ODB query language In-Reply-To: <751E0A8C-D4A8-4AFC-897C-A51ED2F31FA8@markusklemm.net> References: <3868BE88-67A0-4118-989D-090B23CE52C6@markusklemm.net> <751E0A8C-D4A8-4AFC-897C-A51ED2F31FA8@markusklemm.net> Message-ID: Hi Markus, Markus Klemm writes: > in contrast to the 2.4.0 package, opening the project with visual > studio 2013 express does not work anymore... By applying the patch I meant applying the changes from this specific commit to what you are currently using. Getting the whole library from master is not a good idea for multiple reasons. > Translation: Wrong syntax around ')'... query could not be perpared. Ok, so your application now compiles fine but you get this error at runtime. Can you enable statement tracing for the affected transaction so that we can see the query that causes this error: t.tracer (odb::stderr_tracer); Boris From pietrino.atzeni at di-side.com Thu Sep 10 03:17:10 2015 From: pietrino.atzeni at di-side.com (Pietrino Atzeni) Date: Thu Sep 10 03:17:48 2015 Subject: [odb-users] Cannot compile on Yosemite 10.10.5 Message-ID: Hi, I just installed a fresh copy of Yosemite, and tried to compile odb, without success. I tried: - compiling with clang (Apple LLVM version 6.1.0 (clang-602.0.53)), but during ./configure it says "g++ does not support plugins; reconfigure GCC with --enable-plugin" - compiling with gcc-4.9, installed with brew, but I get some errors when using odb in my project (I can provide further details if needed); - compiling with gcc-5.2, as above. Is there anything more I can try? Thanks in advance, Pietro From markus at markusklemm.net Thu Sep 10 04:13:11 2015 From: markus at markusklemm.net (Markus Klemm) Date: Thu Sep 10 04:13:26 2015 Subject: [odb-users] ORDER BY clause in ODB query language In-Reply-To: References: <3868BE88-67A0-4118-989D-090B23CE52C6@markusklemm.net> <751E0A8C-D4A8-4AFC-897C-A51ED2F31FA8@markusklemm.net> Message-ID: <08D5CFDB-23A9-410E-9029-5A342EF66345@markusklemm.net> Alright I checked out tag 2.4.0 (which differs from the downloadable 2.4.0 package btw) and cherrypicked your commit. It broke where I want to filter the files by the directories (1:n bidirect.) and still want a particular ordering of the files. const std::vector &directories odb::query filter_by_directory_query = odb::query::directory->directory_id.in_range(directories.cbegin(), directories.cend()); odb::query order_by_query("ORDER BY" + odb::query::read_time + "ASC"); odb::query final_query = filter_by_directory_query + order_by_query; I'm sorry in advance because I guess I did something wrong/unelegant again. Resulting SQL Query: SELECT [files].[file_id], [files].[file_name], [files].[directory_id], [files].[ fully_uploaded], [files].[partially_uploaded], [files].[read_time], [files].[upl oader_log] FROM [files] LEFT JOIN [directories] AS [directory_id] ON [directory_ id].[directory_id]=[files].[directory_id] WHERE [directory_id].[directory_id] IN () ORDER BY [files].[read_time] ASC Other querys looked fine: SELECT [directories].[directory_id], [directories].[full_path], [directories].[f ile_type], [directories].[active], [directories].[added], [directories].[added_b y] FROM [directories] ORDER BY [directories].[full_path] ASC SELECT [file_types].[type_id], [file_types].[type_description], [file_types].[md db_importer_flag], [file_types].[search_string], [file_types].[odbc_connection_t emplate] FROM [file_types] WHERE [file_types].[type_id]=? SELECT [directories].[directory_id], [directories].[full_path], [directories].[f ile_type], [directories].[active], [directories].[added], [directories].[added_b y] FROM [directories] ORDER BY [directories].[added] ASC SELECT [files].[file_id], [files].[file_name], [files].[directory_id], [files].[ fully_uploaded], [files].[partially_uploaded], [files].[read_time], [files].[upl oader_log] FROM [files] WHERE [files].[file_id]=? Regards Markus Klemm From soroush.rabiei at gmail.com Thu Sep 10 04:59:36 2015 From: soroush.rabiei at gmail.com (Soroush Rabiei) Date: Thu Sep 10 05:00:03 2015 Subject: [odb-users] nullable unsigned variables In-Reply-To: References: Message-ID: On Mon, Sep 7, 2015 at 5:13 PM, Boris Kolpackov wrote: > Hi Soroush, > > Soroush Rabiei writes: > > > I have a problem using nullable types aka `odb::nullable'. It seems it > > can't handle `unsigned' variables. > > Yes, that's an Oracle-specific bug in the ODB compiler which I have > now fixed: > > > http://scm.codesynthesis.com/?p=odb/odb.git;a=commit;h=f70642bcdc61d679981a55ce9bcd88c08c8dadc1 > > Thanks for the report and the test case, much appreciated! > > Boris > Thanks for the patch! From markus at markusklemm.net Thu Sep 10 05:20:09 2015 From: markus at markusklemm.net (Markus Klemm) Date: Thu Sep 10 05:20:25 2015 Subject: [odb-users] ORDER BY clause in ODB query language In-Reply-To: <08D5CFDB-23A9-410E-9029-5A342EF66345@markusklemm.net> References: <3868BE88-67A0-4118-989D-090B23CE52C6@markusklemm.net> <751E0A8C-D4A8-4AFC-897C-A51ED2F31FA8@markusklemm.net> <08D5CFDB-23A9-410E-9029-5A342EF66345@markusklemm.net> Message-ID: <4A23B04E-A40A-4D5E-B88C-F7B976555D72@markusklemm.net> I'm sorry this bug is not causes by your fix, it judt slipped my tests before. Mit freundlichen Gr??en Markus Klemm Gesendet via Mobiltelefon > Am 10.09.2015 um 10:13 schrieb Markus Klemm : > > Alright I checked out tag 2.4.0 (which differs from the downloadable 2.4.0 package btw) and cherrypicked your commit. > > It broke where I want to filter the files by the directories (1:n bidirect.) and still want a particular ordering of the files. > > const std::vector &directories > odb::query filter_by_directory_query = odb::query::directory->directory_id.in_range(directories.cbegin(), directories.cend()); > odb::query order_by_query("ORDER BY" + odb::query::read_time + "ASC"); > odb::query final_query = filter_by_directory_query + order_by_query; > > I'm sorry in advance because I guess I did something wrong/unelegant again. > > Resulting SQL Query: > SELECT [files].[file_id], [files].[file_name], [files].[directory_id], [files].[ > fully_uploaded], [files].[partially_uploaded], [files].[read_time], [files].[upl > oader_log] FROM [files] LEFT JOIN [directories] AS [directory_id] ON [directory_ > id].[directory_id]=[files].[directory_id] WHERE [directory_id].[directory_id] IN > () ORDER BY [files].[read_time] ASC > > Other querys looked fine: > SELECT [directories].[directory_id], [directories].[full_path], [directories].[f > ile_type], [directories].[active], [directories].[added], [directories].[added_b > y] FROM [directories] ORDER BY [directories].[full_path] ASC > SELECT [file_types].[type_id], [file_types].[type_description], [file_types].[md > db_importer_flag], [file_types].[search_string], [file_types].[odbc_connection_t > emplate] FROM [file_types] WHERE [file_types].[type_id]=? > SELECT [directories].[directory_id], [directories].[full_path], [directories].[f > ile_type], [directories].[active], [directories].[added], [directories].[added_b > y] FROM [directories] ORDER BY [directories].[added] ASC > > SELECT [files].[file_id], [files].[file_name], [files].[directory_id], [files].[ > fully_uploaded], [files].[partially_uploaded], [files].[read_time], [files].[upl > oader_log] FROM [files] WHERE [files].[file_id]=? > > Regards > > Markus Klemm > From boris at codesynthesis.com Thu Sep 10 05:28:21 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 10 05:28:25 2015 Subject: [odb-users] Cannot compile on Yosemite 10.10.5 In-Reply-To: References: Message-ID: Hi Pietrino, Pietrino Atzeni writes: > - compiling with clang (Apple LLVM version 6.1.0 (clang-602.0.53)), but > during ./configure it says "g++ does not support plugins; reconfigure GCC > with --enable-plugin" > - compiling with gcc-4.9, installed with brew, but I get some errors when > using odb in my project (I can provide further details if needed); > - compiling with gcc-5.2, as above. Check this page, it has more information on using ODB on Mac OS: http://codesynthesis.com/products/odb/doc/install-macosx.xhtml If you are still having issues, please do provide more information. Boris From boris at codesynthesis.com Thu Sep 10 10:31:34 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 10 10:31:40 2015 Subject: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type In-Reply-To: References: <9c80cadbfcf747068d7a391042134ea4@exch.crcis.local> Message-ID: Hi Ali, > The problem is related to my operating system locale, because Qt > uses operating system locale. My OS locale is Persian. > > odb\qt\date-time\sqlite\qdate-traits.hxx, Line 64: > > std::string s (v.toString ("yyyy-MM-dd").toLatin1 ().constData ()); > > must be changed to: > > std::string s(QLocale(QLocale::English).toString(v, "yyyy-MM-dd").toLatin1().constData()); Thanks for tracking it down. The problem with the proposed fix is that locales are quite heavy-weight. I am not 100% sure about Qt but standard ones are. So I am not sure it would make sense to impose this overhead on cases where it is not necessary, which is probably 99% of all of them. We have the same issue with using stringstream to parse integers, etc. When we switch to C++11, the plan is to use to_string()/sto*() instead which always use "C" locale. I wonder if there is a similar, locale-independent Date/Time parsing support in Qt? Boris From finjulhich at gmail.com Fri Sep 11 14:57:47 2015 From: finjulhich at gmail.com (MM) Date: Fri Sep 11 14:57:55 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: On 7 September 2015 at 17:36, Boris Kolpackov wrote: > Hi, > > MM writes: > > > SELECT * FROM > > F LEFT OUTER JOIN M ON F.mid = M.ID > > WHERE (F.month = M.month1 OR F.month = M.month2) > > Good, this is much better than saying "I need to achieve X, do it > for me". > > > > Is this expressable as a high-level odb query? > > Yes, pretty easily using ODB views. > > Boris > I am struggling after reading chapter 10. Let me put the schema here again: M == id: PRIMARY KEY month1: TEXT (encoded month,year combination) month2: TEXT F == id: PRIMARY KEY mid: NOT NULL REFERENCES M("id") month: TEXT There can 0..N rows in F for each row in M. The intended SQL query is: > SELECT * FROM > F LEFT OUTER JOIN M ON F.mid = M.ID > WHERE (F.month = M.month1 OR F.month = M.month2) class F : public SomeBase { /// SomeBase provides get_m and set_m public: const M* get_m() const override; /// this is how I access the related M instance static const std::string type; /// identifies which of the derived classes from SomeBase this is }; #pragma db object(F) table("F") definition #pragma db member(F::mid) virtual(std::uint32_t)\ get(this.get_m()? this.get_m()->id: std::uint32_t())\ set(this.set_m(find_m(F::type,(?)))) 1) I explicitly load all the M instances and populate them myself in a boost::ptr_map db.query(); //// use the iterator .load() to get a raw pointer to M and take ownership of it. 2) I then load the F instances. Either I load them all, the same way as I load the Ms (store them in their own ptr_map), or I want to load only those Fs where the month in either month1 or month2 of the relevant M, and store the loaded instances (by getting raw pointers and storing them in my ptr_map) I added the following view: //// Specifying the joint condition to be F::get_m to tell odb that's how you get the M instance from the F instance #pragma db view object(F) object(M: F::get_m)\ query( F::month.in (M::month1, M::month2) ) struct F_current { F* f; }; odb generates the ?xx files, but it doesn't compile All the M objects are already loaded and stored in the ptr_map. I do not want the view loading to load them again. The odb loader of the F instances can find the relevant instances because I provided the get and set accessors in the pragma for F. Is this the way to express this view? Regards, MM From adanesh at noornet.net Sat Sep 12 00:09:09 2015 From: adanesh at noornet.net (=?utf-8?B?2LnZhNuMINiv2KfZhti0?=) Date: Sat Sep 12 00:09:19 2015 Subject: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type In-Reply-To: References: <9c80cadbfcf747068d7a391042134ea4@exch.crcis.local> Message-ID: <27bcd53e22fc41819a170195d668732e@exch.crcis.local> Hi Boris, Very good point! Using QLocate::c() static function, the problem of the proposed fix can be solved. std::string s(QLocale::c().toString(v, "yyyy-MM-dd").toLatin1().constData()); Best regards, Ali -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Thursday, September 10, 2015 7:02 PM To: ??? ???? Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type Hi Ali, > The problem is related to my operating system locale, because Qt uses > operating system locale. My OS locale is Persian. > > odb\qt\date-time\sqlite\qdate-traits.hxx, Line 64: > > std::string s (v.toString ("yyyy-MM-dd").toLatin1 ().constData ()); > > must be changed to: > > std::string s(QLocale(QLocale::English).toString(v, > "yyyy-MM-dd").toLatin1().constData()); Thanks for tracking it down. The problem with the proposed fix is that locales are quite heavy-weight. I am not 100% sure about Qt but standard ones are. So I am not sure it would make sense to impose this overhead on cases where it is not necessary, which is probably 99% of all of them. We have the same issue with using stringstream to parse integers, etc. When we switch to C++11, the plan is to use to_string()/sto*() instead which always use "C" locale. I wonder if there is a similar, locale-independent Date/Time parsing support in Qt? Boris From andrew at a-cunningham.com Fri Sep 11 16:39:49 2015 From: andrew at a-cunningham.com (Andrew Cunningham) Date: Sat Sep 12 06:41:14 2015 Subject: [odb-users] SQLIte "INSERT" slows dramatically... Message-ID: Hi, In general I am very happy with the performance ODB 2.4.0 /SQLite. However I am running into some serious performance issues when creating ?large? databases - I am seeing SQLIte performance completely tanking , but only at a certain database size. Assume I have am inserting a thousand ?subsystem? objects to the database, each of those ?subsystem? objects has a std::vector of ?elements? that can be size 100-50,000 This is being done in a single transaction.. When creating this database, performance is perfectly fine until at some point the time to persist a ?subsystem and its elements? ( and all subsequent ones) increases dramatically by a factor of 1000. For example, early on in the database creation a subsystem with ~1000 elements might take 0.08s to persist (along with its elements) However, at a certain point, persisting a similar object starts to take 118s ( 1000x longer). Breaking into SQLite seems to show that the code is often in this phase. Looks like some kind of database paging/moving is going on?. > odb-sqlite-2.4-vc10.dll!winRead(sqlite3_file * id, void * pBuf, int amt, __int64 offset) Line 35654 + 0x2 bytes C odb-sqlite-2.4-vc10.dll!readDbPage(PgHdr * pPg, unsigned int iFrame) Line 44461 + 0x19 bytes C odb-sqlite-2.4-vc10.dll!sqlite3PagerAcquire(Pager * pPager, unsigned int pgno, PgHdr * * ppPage, int flags) Line 46979 + 0xb bytes C odb-sqlite-2.4-vc10.dll!getAndInitPage(BtShared * pBt, unsigned int pgno, MemPage * * ppPage, int bReadonly) Line 54790 + 0xd bytes C odb-sqlite-2.4-vc10.dll!moveToRoot(BtCursor * pCur) Line 57596 + 0x22 bytes C odb-sqlite-2.4-vc10.dll!sqlite3VdbeExec(Vdbe * p) Line 9732 + 0x8 bytes C odb-sqlite-2.4-vc10.dll!sqlite3Step(Vdbe * p) Line 3812 C odb-sqlite-2.4-vc10.dll!sqlite3_step(sqlite3_stmt * pStmt) Line 3878 + 0x8 bytes C odb-sqlite-2.4-vc10.dll!odb::sqlite::insert_statement::execute() Line 649 + 0xd bytes C++ Monitoring the process with ?Process Monitor?, shows that SQLite is making a very large number of calls to the Windows API ReadFile at this point. Any ideas welcome! Andrew From sean.clarke at sec-consulting.co.uk Sun Sep 13 11:20:41 2015 From: sean.clarke at sec-consulting.co.uk (Sean Clarke) Date: Sun Sep 13 11:20:50 2015 Subject: [odb-users] include issues and unknown class errors on many-to-one relationships Message-ID: Hi, For some reason I keep getting include issues when I try and set up some basic many-to-one relationships- I can get your examples to work because they are in the same file, yet mine (when I split across multiple headers) seem to get in a bit of a state.... ------------------------------------------------ Job.hpp ------------------------------------------------ #pragma once class Job { // lots of stuff #pragma db value_not_null inverse(m_job) std::vector> m_job_items; }; ------------------------------------------------ and then in another header file I have: ------------------------------------------------ SomeJobItem.hpp ------------------------------------------------ #pragma once class SomeJobItem { // lots of stuff #pragma db not_null std::weak_ptr m_job; }; ------------------------------------------------ This gives errors that it can't find the class (even though I include the headers in each of them) error: ?JSomJobItem? was not declared in this scope std::vector> m_job_items; etc. I can't forward declare the classes as ODB then complains that the type maps to a non DB type... Any ideas on what I am doing wrong on these simple examples? Regards Sean Clarke From sean.clarke at sec-consulting.co.uk Sun Sep 13 15:23:38 2015 From: sean.clarke at sec-consulting.co.uk (Sean Clarke) Date: Sun Sep 13 15:23:46 2015 Subject: [odb-users] Moving odb::result Message-ID: Hi, I have been doing some tidying etc. and moved some queries into a factory class, however I am getting segsv issues when I try and move the results of some queries... Program received signal SIGSEGV, Segmentation fault. 0x00000000004eca92 in odb::result::size (this=0x7fffffffd6f0) at orm_test/libodb-2.4.0/odb/result.hxx:209 209 return impl_ ? impl_->size () : 0; I just perform a simple query and return the resultant odb::result using a std::move.... If I don't call the std::move and just return the result it does not give a segv, but doesn't work - but I sort of expected this from the info you assisted me with previously regarding multiple iterations over the container/forward_iterator<>. I can "fudge" it by copying data to a std::vector, but would rather not if at all possible. Regards Sean Clarke From finjulhich at gmail.com Sun Sep 13 15:53:54 2015 From: finjulhich at gmail.com (MM) Date: Sun Sep 13 15:54:03 2015 Subject: [odb-users] include issues and unknown class errors on many-to-one relationships In-Reply-To: References: Message-ID: On 13 September 2015 at 16:20, Sean Clarke wrote: > Hi, > For some reason I keep getting include issues when I try and set up > some basic many-to-one relationships- I can get your examples to work > because they are in the same file, yet mine (when I split across multiple > headers) seem to get in a bit of a state.... > > ------------------------------------------------ > Job.hpp > ------------------------------------------------ > #pragma once > > class Job { > // lots of stuff > > #pragma db value_not_null inverse(m_job) > std::vector> m_job_items; > }; > ------------------------------------------------ > > and then in another header file I have: > > ------------------------------------------------ > SomeJobItem.hpp > ------------------------------------------------ > #pragma once > > class SomeJobItem { > // lots of stuff > > #pragma db not_null > std::weak_ptr m_job; > }; > ------------------------------------------------ > > This gives errors that it can't find the class (even though I include the > headers in each of them) > > error: ?JSomJobItem? was not declared in this scope > std::vector> m_job_items; > > etc. > > I can't forward declare the classes as ODB then complains that the type > maps to a non DB type... > > Any ideas on what I am doing wrong on these simple examples? > > Regards > Sean Clarke I would try to extract the minimal independent example that you can email here. It often happened to me that with the extracted example, an obvious error appeared that I couldn't see in the real code. Otherwise, a minimal example can help Boris or the list pinpoint a bug in the compiler, or just a wrong usage of the pragmas. Rds, From markus at markusklemm.net Mon Sep 14 05:26:47 2015 From: markus at markusklemm.net (Markus Klemm) Date: Mon Sep 14 05:27:01 2015 Subject: [odb-users] Assumed bug in odb::query in_range when range is empty Message-ID: <3314C3F1-850D-4ABF-A619-A5DCEB3D012E@markusklemm.net> Hi everyone, I think I found a bug in odb::query<>::field:in_range(begin,end) : If the given range is empty i.e. begin == end, the resulting sql query ("WHERE [type].[field] IN ()") is malformend or at least MS SQL server does not like it. It's basiclly the bug I encountered in the last messages of the mail thread ("ORDER BY clause in ODB query language"/Thu Sep 10 05:20:09 EDT 2015), but I minized it to the following code: Full example/Gist with syntax-highlighting: https://gist.github.com/Superlokkus/e23a5be5bcebf738b1a0 #pragma db object table("files") bulk(5000) session pointer(std::shared_ptr) class file { public: #pragma db column("file_id") type("uniqueidentifier") id not_null boost::uuids::uuid file_id; #pragma db column("file_name") type("nvarchar(256)") not_null std::wstring file_name; }; std::vector files; odb::query query = odb::query::file_id.in_range(files.cbegin(), files.cend()); odb::session s; odb::transaction t(db->begin()); t.tracer(odb::stderr_tracer); odb::result result( db->query (query)); for (const auto &f : result){ std::wcout << f.file_name << std::endl; } Output "SELECT [files].[file_id], [files].[file_name] FROM [files] WHERE [files].[file_i d] IN () ODB database error: 102 (42000): [Microsoft][SQL Server Native Client 11.0][SQL Server]Falsche Syntax in der N?he von ')'. 8180 (42000): [Microsoft][SQL Server Native Client 11.0][SQL Server]Anweisung(en ) konnte(n) nicht vorbereitet werden." Falsche Syntax in der N?he von ')'. == Wrong syntax near ')' Anweisung(en) konnte(n) nicht vorbereitet werden. == Could not prepare query I wish you a nice (or at least bearable) monday Markus Klemm From finjulhich at gmail.com Mon Sep 14 05:56:36 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 14 05:56:44 2015 Subject: [odb-users] sqlite mismatch in result column count Message-ID: Hello, This assertion, from sqlite, gets triggered: statement.cxx:331: bool odb::sqlite::statement::bind_result(const odb::sqlite::bind*, size_t, bool): Assertion `col == col_count' failed. Looking at the source code, there are 3 variables that relate to column count: bool statement:: bind_result (const bind* p, size_t count, bool truncated) { } 1. The 'count' argument of bind_result: looking at the core file, its value is 4 2. col_count: I couldn't find its value from the core file. Is it the expected number of columns that is deduced from the SQL query before it is executed? If so, that number is 4 also. 3. col, I suppose this is the actual number of columns that is returned after executing the SQL query. I traced the odb query, executed the SQL query I see traced out, it has 4 columns, and the result also includes 4 columns. 4. The query is the result of a call: db.query(); F is a struct, where the number of non transient fields overall is 4 as well. F(2 virtual members) derives from B1(odb abstract, 1 member) which derives from B0(odb abstract, 1 member). I will try to printout the values of those variables in my locally modified libodb-sqlite to see what's going on. Rds, From finjulhich at gmail.com Mon Sep 14 08:43:26 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 14 08:43:33 2015 Subject: [odb-users] Re: sqlite mismatch in result column count In-Reply-To: References: Message-ID: On 14 September 2015 at 10:56, MM wrote: > Hello, > > This assertion, from sqlite, gets triggered: > > statement.cxx:331: bool odb::sqlite::statement::bind_result(const > odb::sqlite::bind*, size_t, bool): Assertion `col == col_count' failed. > > Looking at the source code, there are 3 variables that relate to column > count: > > bool statement:: > bind_result (const bind* p, size_t count, bool truncated) > { > } > > 1. The 'count' argument of bind_result: looking at the core file, its > value is 4 > 2. col_count: I couldn't find its value from the core file. Is it the > expected number of columns that is deduced from the SQL query before it is > executed? > If so, that number is 4 also. > 3. col, I suppose this is the actual number of columns that is > returned after executing the SQL query. I traced the odb query, executed > the SQL query I see traced out, it has 4 columns, and the result also > includes 4 columns. > 4. The query is the result of a call: db.query(); > F is a struct, where the number of non transient fields overall is 4 > as well. > F(2 virtual members) derives from B1(odb abstract, 1 member) which > derives from B0(odb abstract, 1 member). > > I will try to printout the values of those variables in my locally > modified libodb-sqlite to see what's going on. > > Rds, > > After some debugging, I find that the value of 'col' is 3, not 4. The loop goes through i=0,1,2,3 as expected. if (b.buffer == 0) { // Skip NULL entries. } This happens once, and that is why col is 3. I printed b.type, and 3 times, it is 0, ie bind::integer The 4rd column (the missing one) is of type std::string in the c++ class (B1), and of type TEXT in the db. B1 is pragma'd like this #pragma db object(B1) abstract definition I assume this means to indeed declare all of its members as non transient. I'm gonna explicitly declare the member here with #pragma member and see if there's a difference Rds, From boris at codesynthesis.com Mon Sep 14 09:16:42 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 09:16:52 2015 Subject: [odb-users] include issues and unknown class errors on many-to-one relationships In-Reply-To: References: Message-ID: Hi Sean, Sean Clarke writes: > For some reason I keep getting include issues when I try and set up > some basic many-to-one relationships- I can get your examples to work > because they are in the same file, yet mine (when I split across multiple > headers) seem to get in a bit of a state.... Have you read Section 6.3, "Circular Relationships"? Boris From fredrik.strand at qliro.com Mon Sep 14 08:05:55 2015 From: fredrik.strand at qliro.com (Fredrik Strand) Date: Mon Sep 14 09:30:12 2015 Subject: [odb-users] Set Query timeout Message-ID: Hi, It's possible to set query timeout using raw odbc calls. However I don't find a way to set query timeout using ODB. Nor do I see any support for this in the source code. Is there a way to set query timeout using ODB? Fredrik Strand Lead Developer Qliro AB Sveav?gen 151, Stockholm 113 46 Mobile: +46733 30 83 82 E-mail: fredrik.strand@qliro.com [footer] Confidentiality Information contained in this e-mail is intended for the use of the addressee only, and is confidential. Any dissemination, distribution, copying or use of this communication without prior permission of the addressee is strictly prohibited. If you are not the intended addressee you must delete this e-mail and its attachments. -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.jpg Type: image/jpeg Size: 6743 bytes Desc: image001.jpg Url : http://codesynthesis.com/pipermail/odb-users/attachments/20150914/a5261ebb/image001.jpg From boris at codesynthesis.com Mon Sep 14 09:35:47 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 09:35:56 2015 Subject: [odb-users] Re: sqlite mismatch in result column count In-Reply-To: References: Message-ID: Hi, MM writes: > The 4rd column (the missing one) is of type std::string in the c++ class > (B1), and of type TEXT in the db. You seem to be trying to map C++ classes to an existing schema. In this case it is very helpful to still ask ODB to generate the schema and then make sure that what gets generated is equivalent to the existing schema. For SQLite, use '--generate-schema --schema-format sql' to get the schema as a standalone .sql file. Boris From finjulhich at gmail.com Mon Sep 14 09:40:56 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 14 09:41:04 2015 Subject: [odb-users] Re: sqlite mismatch in result column count In-Reply-To: References: Message-ID: On 14 September 2015 at 14:35, Boris Kolpackov wrote: > Hi, > > MM writes: > > > The 4rd column (the missing one) is of type std::string in the c++ class > > (B1), and of type TEXT in the db. > > You seem to be trying to map C++ classes to an existing schema. In this > case it is very helpful to still ask ODB to generate the schema and then > make sure that what gets generated is equivalent to the existing schema. > > For SQLite, use '--generate-schema --schema-format sql' to get the > schema as a standalone .sql file. > > Boris > Yes, I do that too. THe CREATE TABLE Statement does have 4 columns (3 INTEGER and 1 TEXT). Normally, #pragma odb (B1) abstract definition is equivalent to #pragma db object(B1) abstract definition #pragma db member(B1::field) with B1's base is abstract also, and F (derived from B) is not abstract ? From boris at codesynthesis.com Mon Sep 14 09:50:44 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 09:50:54 2015 Subject: [odb-users] Re: sqlite mismatch in result column count In-Reply-To: References: Message-ID: MM writes: > if (b.buffer == 0) { // Skip NULL entries. > } > > This happens once, and that is why col is 3. This should only happen if you are using schema evolution support and this column was soft-deleted. And in this case the corresponding column from the statement's SELECT-list should have been removed as well (see statement processing in the init() function in the same file). If you are not using schema evolution support, then this is either a bug in ODB or a memory corruption in your application. Can you run it under valgrind? Boris From finjulhich at gmail.com Mon Sep 14 10:00:58 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 14 10:01:05 2015 Subject: [odb-users] Re: sqlite mismatch in result column count In-Reply-To: References: Message-ID: On 14 September 2015 at 14:40, MM wrote: > > > On 14 September 2015 at 14:35, Boris Kolpackov > wrote: > >> Hi, >> >> MM writes: >> >> > The 4rd column (the missing one) is of type std::string in the c++ class >> > (B1), and of type TEXT in the db. >> >> You seem to be trying to map C++ classes to an existing schema. In this >> case it is very helpful to still ask ODB to generate the schema and then >> make sure that what gets generated is equivalent to the existing schema. >> >> For SQLite, use '--generate-schema --schema-format sql' to get the >> schema as a standalone .sql file. >> >> Boris >> > > Yes, I do that too. > THe CREATE TABLE Statement does have 4 columns (3 INTEGER and 1 TEXT). > > Normally, > > #pragma odb (B1) abstract definition > > is equivalent to > > #pragma db object(B1) abstract definition > #pragma db member(B1::field) > > with B1's base is abstract also, and F (derived from B) is not abstract > > ? > I just finished a long recompile because I had to add /usr/local/include to test with the modified libodb...:-) it now works. I thought that as long as the entire B1 was not marked transient, all its members would be considered, by non-abstract derived classes. This is: public std::string field Adding #pragma db member(B1::field) explicitly solved the problem Rds, From boris at codesynthesis.com Mon Sep 14 10:11:19 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 10:11:29 2015 Subject: [odb-users] Set Query timeout In-Reply-To: References: Message-ID: Hi Fredrik, Fredrik Strand writes: > It's possible to set query timeout using raw odbc calls. However I > don't find a way to set query timeout using ODB. Nor do I see any > support for this in the source code. I assume you are interesting in the SQL_ATTR_QUERY_TIMEOUT statement attribute. While ODB normally hides underlying database statements, you can get hold of it for a prepared query (Section 4.5 in the manual). Here is an outline based on the example from this section: #include #include using query = odb::query; using prep_query = odb::prepared_query; using result = odb::result; transaction t (db.begin ()); prep_query pq (db.prepare_query ("age-query", query::age > 18)); // Set timeout. // { auto& s (static_cast (pq.statement ())); SQLHSTMT h (s.handle ()); SQLULEN t (10); // In seconds. SQLRETURN r (SQLSetStmtAttr (h, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) t, nullptr)); // Translate errors to exceptions using ODB mechanisms. // if (!SQL_SUCCEEDED (r)) odb::mssql::translate_error (r, s.connection (), s); } // Run the query. // result r (pq.execute ()); ... t.commit (); Let me know if there are any problems with this approach. Boris From boris at codesynthesis.com Mon Sep 14 10:12:42 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 10:12:51 2015 Subject: [odb-users] Re: sqlite mismatch in result column count In-Reply-To: References: Message-ID: MM writes: > Adding > #pragma db member(B1::field) > explicitly solved the problem I don't think you know what exactly solved your problem... ;-) Boris From boris at codesynthesis.com Mon Sep 14 10:45:31 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 10:45:40 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: MM writes: > odb generates the ?xx files, but it doesn't compile What is the error?! > #pragma db view object(F) object(M: F::get_m)\ > query( F::month.in (M::month1, M::month2) ) ODB in() function only works on values, not members. I guess that's the error but I shouldn't be guessing. Boris From markus at markusklemm.net Mon Sep 14 12:09:23 2015 From: markus at markusklemm.net (Markus Klemm) Date: Mon Sep 14 12:09:38 2015 Subject: [odb-users] statement-cache.txx compiler error when using object loading views Message-ID: My second an last mail for today; Either I'm missing something essential about object loading views or I stumbled over a compile time bug of odb, in this case \libodb-mssql-2.4.0\odb\mssql\statement-cache.txx. Given for a simple example (code below), I got this compiler error 'odb::mssql::object_statements::object_type>' : class has no constructors \libodb-mssql-2.4.0\odb\mssql\statement-cache.txx 36 'static_cast' : cannot convert from 'odb::mssql::statements_base' to 'statements_type &' \libodb-mssql-2.4.0\odb\mssql\statement-cache.txx 33. Code: https://gist.github.com/Superlokkus/ea4a28e197fea67cec4e ODB-compile command I use: odb.exe -I \include -q -e -d mssql --profile boost --std c++11 I'm using MS MVC 2013 Regards Markus Klemm From boris at codesynthesis.com Mon Sep 14 13:49:56 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 13:50:06 2015 Subject: [odb-users] Assumed bug in odb::query in_range when range is empty In-Reply-To: <3314C3F1-850D-4ABF-A619-A5DCEB3D012E@markusklemm.net> References: <3314C3F1-850D-4ABF-A619-A5DCEB3D012E@markusklemm.net> Message-ID: Hi Markus, Markus Klemm writes: > I think I found a bug in odb::query<>::field:in_range(begin,end) : > If the given range is empty i.e. begin == end, the resulting sql > query ("WHERE [type].[field] IN ()") is malformend [...] Yes, as I mentioned in one of my previous emails, this is a known bug that we have fixed for the next release: http://scm.codesynthesis.com/?p=odb/libodb-mssql.git;a=commit;h=f25ff0d1163ea65abd709b6037098f6a2199a238 Boris From boris at codesynthesis.com Mon Sep 14 13:55:33 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 13:55:44 2015 Subject: [odb-users] Moving odb::result In-Reply-To: References: Message-ID: Hi Sean, Sean Clarke writes: > I just perform a simple query and return the resultant odb::result using a > std::move.... odb::result is copyable, you can just return it by value without move(). Second paragraph from Section 4.4, "Query Result": "It is best to view an instance of odb::result as a handle to a stream, such as a socket stream. While we can make a copy of a result or assign one result to another, the two instances will refer to the same result stream. Advancing the current position in one instance will also advance it in another. The result instance is only usable within the transaction it was created in. Trying to manipulate the result after the transaction has terminated leads to undefined behavior." My guess would be you return the result out of transaction scope. Boris From sean.clarke at sec-consulting.co.uk Mon Sep 14 14:11:59 2015 From: sean.clarke at sec-consulting.co.uk (Sean Clarke) Date: Mon Sep 14 14:12:06 2015 Subject: [odb-users] Moving odb::result In-Reply-To: References: Message-ID: > My guess would be you return the result out of transaction scope. You are indeed correct! Many thanks Boris, as helpful as ever. Regards Sean Clarke --------------------------------------------- SEC Consulting Limited Phone: +44 (0)23 8040 5599 Website: http://www.sec-consulting.co.uk Email: sean.clarke@sec-consulting.co.uk On 14 September 2015 at 18:55, Boris Kolpackov wrote: > Hi Sean, > > Sean Clarke writes: > > > I just perform a simple query and return the resultant odb::result using > a > > std::move.... > > odb::result is copyable, you can just return it by value without move(). > Second paragraph from Section 4.4, "Query Result": > > "It is best to view an instance of odb::result as a handle to a stream, > such as a socket stream. While we can make a copy of a result or assign > one result to another, the two instances will refer to the same result > stream. Advancing the current position in one instance will also advance > it in another. The result instance is only usable within the transaction > it was created in. Trying to manipulate the result after the transaction > has terminated leads to undefined behavior." > > My guess would be you return the result out of transaction scope. > > Boris > From boris at codesynthesis.com Mon Sep 14 14:36:29 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 14 14:36:38 2015 Subject: [odb-users] SQLIte "INSERT" slows dramatically... In-Reply-To: References: Message-ID: Hi Andrew, These two pages list various tuning options for using SQLite with very large databases. In particular, I would try the WAL journal. http://stackoverflow.com/questions/10209438/sqlite-end-transaction-is-taking-too-long http://stackoverflow.com/a/6533930 Boris From sean.clarke at sec-consulting.co.uk Mon Sep 14 14:42:21 2015 From: sean.clarke at sec-consulting.co.uk (Sean Clarke) Date: Mon Sep 14 14:42:28 2015 Subject: [odb-users] include issues and unknown class errors on many-to-one relationships In-Reply-To: References: Message-ID: Hi Boris, yes, I did - but I either get these errors or recursion include errors. I'll keep at it and try some things, it is probably conflicting with my pragma once guards - maybe I'll switch to the standard guards and put the include (with #ifdef ODB_COMPILER) outside of that. Regards Sean Clarke --------------------------------------------- SEC Consulting Limited Phone: +44 (0)23 8040 5599 Website: http://www.sec-consulting.co.uk Email: sean.clarke@sec-consulting.co.uk On 14 September 2015 at 14:16, Boris Kolpackov wrote: > Hi Sean, > > Sean Clarke writes: > > > For some reason I keep getting include issues when I try and set up > > some basic many-to-one relationships- I can get your examples to work > > because they are in the same file, yet mine (when I split across multiple > > headers) seem to get in a bit of a state.... > > Have you read Section 6.3, "Circular Relationships"? > > Boris > From finjulhich at gmail.com Mon Sep 14 16:27:52 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 14 16:28:00 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: On 14 September 2015 at 15:45, Boris Kolpackov wrote: > MM writes: > > > odb generates the ?xx files, but it doesn't compile > > What is the error?! > > > > #pragma db view object(F) object(M: F::get_m)\ > > query( F::month.in (M::month1, M::month2) ) > > ODB in() function only works on values, not members. I guess that's > the error but I shouldn't be guessing. > > Boris > I see. I changed that. Thanks. For the pragma syntax: *object(**name* [*=* *alias*] [*join-type*] [*:* *join-condition*]*)* In my case, I have 2 associated objects. F and M. One can obtain the M object from the F object through this public member function struct F : public Base { ... const M* getM() const override; }; I couldn't find out how to express the *join-condition.* I tried (and used 2 aliases as well) this: #pragma db view object(::NS::NS1::F = fctrct) object(::NS::NS2::M = fmkt: fctrct::getM) The error by the odb compiler is: error: unable to resolve data member 'getM' specified with db pragma object Basically, I don't understand the syntax of the join-condition. The example in the manual show actual data members. I couldn't find an example with a function member . Rds, From markus at markusklemm.net Tue Sep 15 05:23:26 2015 From: markus at markusklemm.net (Markus Klemm) Date: Tue Sep 15 05:23:41 2015 Subject: [odb-users] Order, Group by and Where in a view simultaneously Message-ID: <55C52526-8827-42A7-AA6F-DA0AFBC23FD6@markusklemm.net> In addition to Bruce Cresantas old question, I've got a question e.g. feature request: I know how to use a view for aggregate functions, and everything works, except when I also want to order that results and at the same moment have a where clause too. Because AFAIK I have to choose where to set the (?) placeholder in the views query pragma. Either I place it before the group-by clause for a where clause or behind for the order-by clause. Either way one gets a syntax expcetion from the server. Because I think that could be a nontrivial problem for ODB because of the SQL syntax ordering; I guess this is rather a feature request. It's not a big deal because I can use a compile-time static order-by clause in the view, but as many details, it's nice to have. Or is there something I missed in the manual? Example: #pragma db view object(measurement) object(order) query((?) + "GROUP BY" + order::order_number) class measurement_view{ public: int32_t order_number; #pragma db column("count(" + measurement::measurement_id + ")") std::size_t count; }; } void get(std::unique_ptr db){ odb::session s; odb::transaction t(db->begin()); t.tracer(odb::stderr_tracer); typedef odb::query query_t; query_t query(query_t::measurement::tests_passed == false); query += query_t("ORDER BY" + odb::query::order::order_number + "DESC"); odb::result result(db->query(query)); } Regards Markus Klemm From andrew at a-cunningham.com Mon Sep 14 15:10:43 2015 From: andrew at a-cunningham.com (Andrew Cunningham) Date: Tue Sep 15 05:31:07 2015 Subject: [odb-users] SQLIte "INSERT" slows dramatically... In-Reply-To: References: Message-ID: Actually, I **just** tracked down the problem. It was my fault, but the symptoms are interesting. I am using SQLite with "deferred" foreign keys. My data structure is a medium number (100's) of subsystems each pointing to "thousands" of elements. A small number of the elements may also point to an auxiliary object ( this object is typically NULL in the element data structure). The sudden SQLite performance degradation happened when one of my "elements" was persisted but was pointing to a non-persistent "auxiliary" object. This is a violation of a foreign key constraint,and would have caused an exception in immediate mode, or on "commit" in deferred mode - but I never got to that commit stage as it would have taken 24 hours at least. The key point I want to make here is that although this foreign key constraint was violated for only a handful of "elements" the performance of SQLite was degraded 1000x from that point on. On Mon, Sep 14, 2015 at 11:36 AM, Boris Kolpackov wrote: > Hi Andrew, > > These two pages list various tuning options for using SQLite with > very large databases. In particular, I would try the WAL journal. > > > http://stackoverflow.com/questions/10209438/sqlite-end-transaction-is-taking-too-long > > http://stackoverflow.com/a/6533930 > > Boris > From boris at codesynthesis.com Tue Sep 15 05:56:05 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 15 05:56:16 2015 Subject: [odb-users] Problem with QDate and Sqlite when it's mapped with TEXT type In-Reply-To: <27bcd53e22fc41819a170195d668732e@exch.crcis.local> References: <9c80cadbfcf747068d7a391042134ea4@exch.crcis.local> <27bcd53e22fc41819a170195d668732e@exch.crcis.local> Message-ID: Hi Ali, > Using QLocate::c() static function, the problem of the proposed > fix can be solved. > > std::string s(QLocale::c().toString(v, "yyyy-MM-dd").toLatin1().constData()); Ok, that looks better. Will apply the fix for the next release. Boris From christian at gsvitec.com Tue Sep 15 06:21:16 2015 From: christian at gsvitec.com (Christian Sell) Date: Tue Sep 15 06:21:20 2015 Subject: [odb-users] Schema evolution and upward compatibility Message-ID: <508878647.7268330.1442312476864.JavaMail.open-xchange@omgreatgod.store> Hello, we have a requirement that our application not only provide forward schema migration (i.e., a newer version of the app will be able to access and migrate a schema created with an older version), but also upward schema compatibility. By this I mean that an older application will be able to access a newer schema and still behave gracefully. Now, I understand that this will only work if the application has been designed with that compatibility in mind, but there are a few aspects that rely on ODB, namely: 1. if we enable schema versioning and forward migration, can we tell ODB to also accept newer schemas (without migrating of course) or will QDB simply refuse to cooperate 2. if 1. is true, would we be able to traverse polymorphic relationships where new classes have been defined and are referenced in the relationship? Our expectation would be that non-mapped classes would simply be ignored. example: schema 1: classA 1---N-> classB classB ---subclass--> classB1 schema 2: classA 1---N-> classB classB ---subclass--> classB1 classB ---subclass--> classB2 now, when I traverse the relationship a->b in the app based on schema1, and the relationship contains, say, {classB1, classB2}, I would only see {classB1} thanks, Christian From finjulhich at gmail.com Tue Sep 15 16:43:31 2015 From: finjulhich at gmail.com (MM) Date: Tue Sep 15 16:43:39 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: On 14 September 2015 at 21:27, MM wrote: > > > On 14 September 2015 at 15:45, Boris Kolpackov > wrote: > >> MM writes: >> >> > odb generates the ?xx files, but it doesn't compile >> >> What is the error?! >> >> >> > #pragma db view object(F) object(M: F::get_m)\ >> > query( F::month.in (M::month1, M::month2) ) >> >> ODB in() function only works on values, not members. I guess that's >> the error but I shouldn't be guessing. >> >> Boris >> > > I see. I changed that. Thanks. > > For the pragma syntax: > > *object(**name* [*=* *alias*] [*join-type*] [*:* *join-condition*]*)* > > In my case, I have 2 associated objects. F and M. > > One can obtain the M object from the F object through this public member > function > > struct F : public Base { > ... > const M* getM() const override; > }; > > I couldn't find out how to express the *join-condition.* > I tried (and used 2 aliases as well) this: > > #pragma db view object(::NS::NS1::F = fctrct) object(::NS::NS2::M = > fmkt: fctrct::getM) > > The error by the odb compiler is: > > error: unable to resolve data member 'getM' specified with db pragma > object > > Basically, I don't understand the syntax of the join-condition. The > example in the manual show actual data members. I couldn't find an example > with a function member . > > Rds, > > getM() in fact, only returns a protected data member const M* m_; from struct Base I change the pragma to #pragma db view object(::NS::NS1::F = fctrct) object(::NS::NS2::M = fmkt: fctrct::m_) struct Fcurrent { ::NS::NS1::F* fctrct; }; the odb compiler generates the cxx code, but compiling that code fails. Is the join-condition limited to data members? From a.pasternak at mt-robot.com Wed Sep 16 05:15:22 2015 From: a.pasternak at mt-robot.com (Andreas Pasternak MT-Robot AG) Date: Wed Sep 16 05:15:26 2015 Subject: [odb-users] Custom pointer as in pointer-traits.hxx Message-ID: <20150916111522.EGroupware.UPAXkY5Gv6ceA9ro9tM6_A1@mail.mt-robot.com> Hello all, A third party framework uses a custom pointer. So I tried to create a simple example: template class mypointer { public: T* ptr; }; I tried then according to the manual but also as a hack directly in pointer-traits.hxx to insert: namespace odb { template class pointer_traits > { public: static const pointer_kind kind = pk_unique; static const bool lazy = false; typedef T element_type; typedef mypointer pointer_type; typedef mypointer const_pointer_type; typedef smart_ptr_guard guard; }; } //end odb I then get the error message: error: unable to map C++ type '::mypointer' used in data member 'myptr' to a MySQL database type Other pointers (std::shared_ptr etc.) work. I also tried to copy&past the std::shared_ptr code and adapt it, leaving it as close to the original as possible. I just have no clue why it does not find my template spezialisation. But it does compile it, if I have an error in the code it complains. Also my container specialisation and string specialisation I made work flawlessly. I just don't get the pointers to work. Thank you, Andreas From fredrik.strand at qliro.com Wed Sep 16 05:06:24 2015 From: fredrik.strand at qliro.com (Fredrik Strand) Date: Wed Sep 16 10:08:25 2015 Subject: [odb-users] Set Query timeout In-Reply-To: References: Message-ID: Hi, I'm currently using a query object to call a stored procedure in SQL server. So this approach is only usable with prepared queries? Would be really nice to have a generic way to set query timeouts since it's probably a must have in enterprise applications. /Fredrik -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Monday, September 14, 2015 4:11 PM To: Fredrik Strand Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Set Query timeout Hi Fredrik, Fredrik Strand writes: > It's possible to set query timeout using raw odbc calls. However I > don't find a way to set query timeout using ODB. Nor do I see any > support for this in the source code. I assume you are interesting in the SQL_ATTR_QUERY_TIMEOUT statement attribute. While ODB normally hides underlying database statements, you can get hold of it for a prepared query (Section 4.5 in the manual). Here is an outline based on the example from this section: #include #include using query = odb::query; using prep_query = odb::prepared_query; using result = odb::result; transaction t (db.begin ()); prep_query pq (db.prepare_query ("age-query", query::age > 18)); // Set timeout. // { auto& s (static_cast (pq.statement ())); SQLHSTMT h (s.handle ()); SQLULEN t (10); // In seconds. SQLRETURN r (SQLSetStmtAttr (h, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) t, nullptr)); // Translate errors to exceptions using ODB mechanisms. // if (!SQL_SUCCEEDED (r)) odb::mssql::translate_error (r, s.connection (), s); } // Run the query. // result r (pq.execute ()); ... t.commit (); Let me know if there are any problems with this approach. Boris From a.pasternak at mt-robot.com Wed Sep 16 10:57:50 2015 From: a.pasternak at mt-robot.com (Andreas Pasternak MT-Robot AG) Date: Wed Sep 16 10:57:53 2015 Subject: [odb-users] Custom pointer as in pointer-traits.hxx Message-ID: <20150916165750.EGroupware.23OV33oLKtSKOMzYEFDGkg1@mail.mt-robot.com> Ok, I figured it out. I tried to create a pointer of a db value (an int exactly) and not an db object. Now everything works without any problems. ----------------original message----------------- From: Andreas Pasternak MT-Robot AG [a.pasternak@mt-robot.com ] To: odb-users@codesynthesis.com Date: Wed, 16 Sep 2015 11:15:22 +0200 ------------------------------------------------- > Hello all, > > A third party framework uses a custom pointer. So I tried to create > a simple example: > > template > class mypointer { > public: > T* ptr; > }; > > I tried then according to the manual but also as a hack directly in > pointer-traits.hxx to insert: > > namespace odb > { > template > class pointer_traits > > { > public: > static const pointer_kind kind = pk_unique; > static const bool lazy = false; > > typedef T element_type; > typedef mypointer pointer_type; > typedef mypointer const_pointer_type; > typedef smart_ptr_guard > guard; > }; > } //end odb > > I then get the error message: > > error: unable to map C++ type '::mypointer' used in data member > 'myptr' to a MySQL database type > > Other pointers (std::shared_ptr etc.) work. I also tried to > copy&past the std::shared_ptr code and adapt it, leaving it as close > to the original as possible. I just have no clue why it does not > find my template spezialisation. > > But it does compile it, if I have an error in the code it complains. > Also my container specialisation and string specialisation I made > work flawlessly. I just don't get the pointers to work. > > Thank you, > > Andreas > -- MT Robot AG Riedstrasse 16 CH-4222 Zwingen Tel. - +41 (0)61 775 20 20 Direkt - +41 (0)61 775 20 26 Mobile - +41 (0)76 489 21 16 Fax - +41 (0)61 775 20 21 Email - [ mailto:a.pasternak@mt-robot.com %20%20 -> a.pasternak@mt-robot.com ] Web - www.mt-robot.com Diese E-Mail k?nnte vertrauliche und/oder rechtlich gesch?tzte Informationen enthalten.Wenn Sie nicht der richtige Adressat sind oder diese E-Mail irrt?mlich erhalten haben, informieren Sie bitte sofort den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser E-Mail sind nicht gestattet. This e-mail may contain confidential and/or privileged information. If you are not the intended recipien From boris at codesynthesis.com Wed Sep 16 11:10:24 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 16 11:10:31 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: MM writes: > Is the join-condition limited to data members? Just think a little: how would a C++ member function be mapped to a relational model? In ODB views, the JOIN condition can be specified as either a data member, which should be a pointer to object, or you can spell the condition literally, as a comparison of the relevant columns. In other words, the JOIN condition in ODB views is a very thin abstraction of the SQL JOIN condition. So next time when you are try to "stick" something in there, find out it doesn't work, and start writing another email to the mailing list, pause and think how would something like this be mapped to SQL..? Boris From boris at codesynthesis.com Wed Sep 16 11:13:19 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 16 11:13:26 2015 Subject: [odb-users] SQLIte "INSERT" slows dramatically... In-Reply-To: References: Message-ID: Hi Andrew, Andrew Cunningham writes: > The key point I want to make here is that although this foreign key > constraint was violated for only a handful of "elements" the performance of > SQLite was degraded 1000x from that point on. Yes, that's indeed quite interesting, thanks for sharing! I found that SQLite has such "dark corners" here and there. I would suggest that you re-send your findings to the SQLite mailing list and see what the developers say. They are usually very helpful. Boris From boris at codesynthesis.com Wed Sep 16 11:20:18 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 16 11:20:25 2015 Subject: [odb-users] Custom pointer as in pointer-traits.hxx In-Reply-To: <20150916165750.EGroupware.23OV33oLKtSKOMzYEFDGkg1@mail.mt-robot.com> References: <20150916165750.EGroupware.23OV33oLKtSKOMzYEFDGkg1@mail.mt-robot.com> Message-ID: Andreas Pasternak MT-Robot AG writes: > Now everything works without any problems. Great, glad to hear that. Just for reference, to add support for a custom smart pointer in ODB: 1. You will need to implement a pointer_traits specialization. See libodb/odb/pointer-traits.hxx for inspirations. 2a. The easiest way to integrate this traits implementation into ODB is to simply add it at the end of the header that defines your smart pointer. 2b. If you want to make it a bit less intrusive (i.e., you may be using the same smart pointer in other parts of your application that have nothing to do with ODB), then you can place this traits specialization into a separate file and then: 1) Include it into the ODB compilation with the --odb-epilogue option, for example: --odb-epilogue '#include "ptr-traits.h"' 2) Include it into the generated source code with --hxx-prologue: --hxx-epilogue '#include "ptr-traits.h"' For an example on how to do this, see libodb-boost, specifically, the smart-ptr.options file. > I tried to create a pointer of a db value (an int exactly) and > not an db object. You can make that work as well: see wrapper_traits. Boris From boris at codesynthesis.com Wed Sep 16 11:59:24 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 16 11:59:32 2015 Subject: [odb-users] Schema evolution and upward compatibility In-Reply-To: <508878647.7268330.1442312476864.JavaMail.open-xchange@omgreatgod.store> References: <508878647.7268330.1442312476864.JavaMail.open-xchange@omgreatgod.store> Message-ID: Hi Christian, Christian Sell writes: > By this I mean that an older application will be able to access a > newer schema and still behave gracefully. Just to make it clear, ODB doesn't "officially" support this mode and probably never will; the "normal" direction is already complex enough. > Now, I understand that this will only work if the application has > been designed with that compatibility in mind [...] Right, you will at the least have to make sure that the new schema if always a superset of the old one. That is, not remove any objects, data members, etc. Even then, you can run into breakages. For example, the new version of the object might contain a non-NULLable pointer that the old code will fail to persist. So it seems like besides not removing anything, whatever new data members you add, they all should have default values (see 'default' pragma). > 1. if we enable schema versioning and forward migration, can we > tell ODB to also accept newer schemas (without migrating of > course) or will QDB simply refuse to cooperate All ODB statements always explicitly list all the columns in SELECT- lists, etc. In other words, we don't do "SELECT *". So, provided the new schema is a proper superset (see above) of the old one, the old code should theoretically work. > 2. if 1. is true, would we be able to traverse polymorphic > relationships where new classes have been defined and are > referenced in the relationship? Our expectation would be that > non-mapped classes would simply be ignored. > > example: > > schema 1: classA 1---N-> classB > classB ---subclass--> classB1 > > schema 2: classA 1---N-> classB > classB ---subclass--> classB1 > classB ---subclass--> classB2 > > now, when I traverse the relationship a->b in the app based on > schema1, and the relationship contains, say, {classB1, classB2}, > I would only see {classB1} This is a good one. No, unfortunately, it won't work. What will happen is schema1-based application will load the data from the classB table. It will examine the type_id stored in the classB table (root or the polymorphic hierarchy). It will see "classB1" id for the first entry, which it knows about and will load fine. For the second entry it will see "classB2" which it has no idea about. So it will throw the odb::no_type_info exception. The only way I can think of to make this work is to query the relationship manually (i.e., with a query that returns odb::result) and then, while iterating over the result, catch no_type_info and skip over such unknown entries. You could probably even do this inside a callback so that it works just like an ordinary relationship. Good luck. Boris From christian at gsvitec.com Wed Sep 16 12:23:47 2015 From: christian at gsvitec.com (Christian Sell) Date: Wed Sep 16 12:23:51 2015 Subject: [odb-users] Schema evolution and upward compatibility In-Reply-To: References: <508878647.7268330.1442312476864.JavaMail.open-xchange@omgreatgod.store> Message-ID: <683709131.7612559.1442420628117.JavaMail.open-xchange@omgreatgod.store> ok, thanks for the reply. So I take it that if my application contains a #pragma db model version(1, 1) and then encounters a model with, say, version (2, 2), ODB will not call exit() on my application. The rest of your answer is as expected. I really don't like this requirement myself, but wasn't able to talk them out of it.. thanks, Chris > Boris Kolpackov hat am 16. September 2015 um 17:59 > geschrieben: > > > Hi Christian, > > Christian Sell writes: > > > By this I mean that an older application will be able to access a > > newer schema and still behave gracefully. > > Just to make it clear, ODB doesn't "officially" support this mode > and probably never will; the "normal" direction is already complex > enough. > > > > Now, I understand that this will only work if the application has > > been designed with that compatibility in mind [...] > > Right, you will at the least have to make sure that the new schema > if always a superset of the old one. That is, not remove any objects, > data members, etc. Even then, you can run into breakages. For example, > the new version of the object might contain a non-NULLable pointer > that the old code will fail to persist. So it seems like besides > not removing anything, whatever new data members you add, they all > should have default values (see 'default' pragma). > > > > 1. if we enable schema versioning and forward migration, can we > > tell ODB to also accept newer schemas (without migrating of > > course) or will QDB simply refuse to cooperate > > All ODB statements always explicitly list all the columns in SELECT- > lists, etc. In other words, we don't do "SELECT *". So, provided > the new schema is a proper superset (see above) of the old one, > the old code should theoretically work. > > > > 2. if 1. is true, would we be able to traverse polymorphic > > relationships where new classes have been defined and are > > referenced in the relationship? Our expectation would be that > > non-mapped classes would simply be ignored. > > > > example: > > > > schema 1: classA 1---N-> classB > > classB ---subclass--> classB1 > > > > schema 2: classA 1---N-> classB > > classB ---subclass--> classB1 > > classB ---subclass--> classB2 > > > > now, when I traverse the relationship a->b in the app based on > > schema1, and the relationship contains, say, {classB1, classB2}, > > I would only see {classB1} > > This is a good one. No, unfortunately, it won't work. What will > happen is schema1-based application will load the data from the > classB table. It will examine the type_id stored in the classB > table (root or the polymorphic hierarchy). It will see "classB1" > id for the first entry, which it knows about and will load fine. > For the second entry it will see "classB2" which it has no idea > about. So it will throw the odb::no_type_info exception. > > The only way I can think of to make this work is to query the > relationship manually (i.e., with a query that returns odb::result) > and then, while iterating over the result, catch no_type_info and > skip over such unknown entries. You could probably even do this > inside a callback so that it works just like an ordinary > relationship. > > Good luck. > > Boris Christian Sell GS Vitec GmbH Im Ziegelhaus 6-8 D-63571 Gelnhausen mail: christian@gsvitec.com mobil: +49 (0) 173 5384289 Tel: +49 (0) 6051 601.26-90 Fax: +49 (0) 6051 601.26-91 From boris at codesynthesis.com Wed Sep 16 12:47:39 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 16 12:47:45 2015 Subject: [odb-users] Schema evolution and upward compatibility In-Reply-To: <683709131.7612559.1442420628117.JavaMail.open-xchange@omgreatgod.store> References: <508878647.7268330.1442312476864.JavaMail.open-xchange@omgreatgod.store> <683709131.7612559.1442420628117.JavaMail.open-xchange@omgreatgod.store> Message-ID: Hi Christian, Christian Sell writes: > So I take it that if my application contains a > > #pragma db model version(1, 1) > > and then encounters a model with, say, version (2, 2), ODB will not > call exit() on my application. No, it won't. You, however, can detect this situation (schema_version() function of the database) and, perhaps, warn the user that things are about to get rocky ;-). Boris From finjulhich at gmail.com Wed Sep 16 17:22:11 2015 From: finjulhich at gmail.com (MM) Date: Wed Sep 16 17:22:19 2015 Subject: [odb-users] Re: 2-table query In-Reply-To: References: Message-ID: On 16 September 2015 at 16:10, Boris Kolpackov wrote: > MM writes: > > > Is the join-condition limited to data members? > > Just think a little: how would a C++ member function be mapped to > a relational model? > > In ODB views, the JOIN condition can be specified as either a data > member, which should be a pointer to object, or you can spell the > condition literally, as a comparison of the relevant columns. In > other words, the JOIN condition in ODB views is a very thin > abstraction of the SQL JOIN condition. So next time when you are > try to "stick" something in there, find out it doesn't work, and > start writing another email to the mailing list, pause and think > how would something like this be mapped to SQL..? > > Boris > > Yes indeed it makes sense now. I suppose I assumed odb could magically make the association given the member function (and the fact that it returns the associated object pointer)... But that doesn't make sense. Is it possible to add a little paragraph to clarify this part for the join-condition in the case of? JOIN ON ( F::mid = M::id ) I could write something up and send a "pull request", I suppose, if that is how you merge things in. Thanks, I have made the changes, and the generated code compiles correctly. Runtime works as well, except that I have object ownership issues that cause a crash on exit, which I am trying to understand. Here is the types and pragmas again: struct M { ... std::uint32_t id; ... }; struct F { ... const M* m; /// gets stored/loaded as a mid in the table, setting m searchs for the right M object std::uint32_t id; ... }; #pragma db view object(F = fctrct) object(M = fmkt: fctrct::mid==fmkt::id)\ query( fctrct::month==fmkt::activemonth || fctrct::month==fmkt::nextmonth ) struct F_current { std::shared_ptr fctrct; }; and the query code is: odb::transaction t{ db.begin() }; odb::session s; /// as required mentioned in the manual auto res = db.query(); for (const auto& fc: res) { /// I would like to use the F* (take ownership of it) fc.fctrct.get(); ///this is probably wrong to take ownership of this pointer } As it happens, the M objects have manually been loaded prior to this query. After the crash, I printed the object F's address. It's the same address for each iteration of the loop. So, odb allocates a single F_current instance, and a single F instance with this code above, and populates it with the result of the query for each iteration. Is this correct? When does the F instance get deallocated? Obviously when the last shared_ptr pointing to it is destroyed, but when is that? Ie, in the code above, what is the scope of the fctrct shared pointer? When does the F_current instance get destroyed? This is similar to the employee/employer examples... But I manually load all the employers ahead of time, then load either all or some of the employees later. And the employed_by_ is not a shared pointer but a raw pointer in my case. The employers are stored in a boost ptr container, so are the employees. Can I get odb to allocate a new instance of F for each result from the query? I could just clone the F instance atevery iteration in the for loop, and take ownership of that instead. I appreciate all the help I can get. It is a difficult problem. Rds, From mne at qosmotec.com Thu Sep 17 05:38:12 2015 From: mne at qosmotec.com (Marcel Nehring) Date: Thu Sep 17 05:39:17 2015 Subject: [odb-users] many-to-many with two FKs Message-ID: Hi all, when modeling a many-to-many relationship in ODB the corresponding mapping table will have only one foreign key. Is there any way to make it two? Is there a reason not to make it two that I don't see? Instead of CREATE TABLE project ( name VARCHAR (255) NOT NULL PRIMARY KEY); CREATE TABLE employee ( id BIGINT UNSIGNED NOT NULL PRIMARY KEY); CREATE TABLE employee_projects ( object_id BIGINT UNSIGNED NOT NULL, value VARCHAR (255) NOT NULL REFERENCES project (name)); I would like CREATE TABLE project ( name VARCHAR (255) NOT NULL PRIMARY KEY); CREATE TABLE employee ( id BIGINT UNSIGNED NOT NULL PRIMARY KEY); CREATE TABLE employee_projects ( object_id BIGINT UNSIGNED NOT NULL REFERENCES employee (id), value VARCHAR (255) NOT NULL REFERENCES project (name)); Regards, Marcel From boris at codesynthesis.com Thu Sep 17 10:57:04 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 17 10:57:11 2015 Subject: [odb-users] many-to-many with two FKs In-Reply-To: References: Message-ID: Hi Marcel, Marcel Nehring writes: > Instead of > > CREATE TABLE project ( > name VARCHAR (255) NOT NULL PRIMARY KEY); > > CREATE TABLE employee ( > id BIGINT UNSIGNED NOT NULL PRIMARY KEY); > > CREATE TABLE employee_projects ( > object_id BIGINT UNSIGNED NOT NULL, > value VARCHAR (255) NOT NULL REFERENCES project (name)); > > I would like > > [...] > > CREATE TABLE employee_projects ( > object_id BIGINT UNSIGNED NOT NULL REFERENCES employee (id), > value VARCHAR (255) NOT NULL REFERENCES project (name)); And that's pretty much what I get: $ cat test.hxx #include #pragma db object struct project { #pragma db id int id; }; #pragma db object struct employee { #pragma db id int id; std::vector projects; }; $ odb -d oracle -s test.hxx $ cat test.sql CREATE TABLE "project" ( "id" NUMBER(10) NOT NULL PRIMARY KEY); CREATE TABLE "employee" ( "id" NUMBER(10) NOT NULL PRIMARY KEY); CREATE TABLE "employee_projects" ( "object_id" NUMBER(10) NOT NULL, "index" NUMBER(20) NOT NULL, "value" NUMBER(10) NULL, CONSTRAINT "employee_projects_object_id_fk" FOREIGN KEY ("object_id") REFERENCES "employee" ("id") ON DELETE CASCADE, CONSTRAINT "employee_projects_value_fk" FOREIGN KEY ("value") REFERENCES "project" ("id") DEFERRABLE INITIALLY DEFERRED); Boris From erick.jeronimo at aeronav.avianet.cu Thu Sep 17 11:24:16 2015 From: erick.jeronimo at aeronav.avianet.cu (Erick Jeronimo) Date: Thu Sep 17 11:26:16 2015 Subject: [odb-users] how to include compiles odb files in Subprojects of QtCreator Message-ID: <55FADB20.1070200@aeronav.avianet.cu> How can i import/include compiled odb files (-odb.hxx,..) to Subprojects in QtCreator without compile again the same files already compiled in other subproject. I followed the tutorial http://wiki.codesynthesis.com/Using_ODB_with_Qt_Creator_on_Linux and works ok, but... how can i use the compiled files in other subproject. thanks in advance From adanesh at noornet.net Fri Sep 18 00:19:57 2015 From: adanesh at noornet.net (=?utf-8?B?2LnZhNuMINiv2KfZhti0?=) Date: Fri Sep 18 02:07:22 2015 Subject: [odb-users] BaseDaoEnabled for ODB In-Reply-To: References: Message-ID: Hi Boris, Is there a feature in ODB similar to 'Class BaseDaoEnabled' in OrmLite? (http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/misc/BaseDaoEnabled.html) I need this feature in my project, I changed the odb code to add this feature. It works up to now and I have not any problem yet, but I am not sure is it a good solution or not? Is it possible for you to review it and inform me about possible problems in it? Steps to add this feature: 1- Add 'BaseDaoEnabled .hxx': #ifndef ODB_BASEDAOENABLED_HXX #define ODB_BASEDAOENABLED_HXX namespace odb { // Base of odb objects and views: class BaseDaoEnabled { template friend struct SetDaoEnabled; public: inline database* getDB() const { return db_; }; protected: inline void setDB(database* db){ db_ = db; }; private: database* db_ = nullptr; }; template ::value> struct SetDaoEnabled { static inline void setDB(T*, odb::database*) {} }; template struct SetDaoEnabled < T, true > { static inline void setDB(T*, odb::database*); }; template /*static*/ inline void SetDaoEnabled::setDB(T* p, odb::database* db) { p->BaseDaoEnabled::setDB(db); } } #endif //ODB_BASEDAOENABLED_HXX 2- odb\forward.hxx, Line 174 (before #include ) add: a. #include "odb/BaseDaoEnabled.hxx" 3- odb\no_id_object_result.hxx, Line 17, change (a to b): a. pointer_type p (object_traits::create ()); b. pointer_type p (object_traits::create (&db_)); 4- odb\simple-object-result.txx, Line 25, change (a to b): a. p = object_traits::create (); b. p = object_traits::create (&db_); 5- odb\view_result.txx, Line 18, change (a to b): a. pointer_type p (view_traits::create ()); b. pointer_type p (view_traits::create (&db_)); 6- odb\traits.hxx a. Line 44 & 60 & 76, change (i to ii): i. create () ii. create (odb::database* db = nullptr) b. Line 48 & 64, change (i to ii): i. return pointer_factory::create (); ii. return pointer_factory::create (db); c. Line 81, add: i. SetDaoEnabled::setDB(p, db); 7- Generated file "%(Filename)-odb.cxx"; replace (a) with (b) by using a tool after running odb.exe: a. access::object_factory::create () b. access::object_factory::create (&db) That?s it. And now I can easily access to db in my models if they are inherited from odb::BaseDaoEnabled. If the model is not inherited from odb::BaseDaoEnabled all things happens like before. In my project each instance of my model may be from different sqlite database and in the model I need to access to db for example to do a query or load another related object and so on. Best regards, Ali From boris at codesynthesis.com Fri Sep 18 02:14:38 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Sep 18 02:14:44 2015 Subject: [odb-users] BaseDaoEnabled for ODB In-Reply-To: References: Message-ID: Hi Ali, > I changed the odb code to add this feature. It works up to now and > I have not any problem yet, but I am not sure is it a good solution > or not? Is it possible for you to review it and inform me about > possible problems in it? Sorry, can't review it, it's just too messy. But I can suggest a much cleaner solution: The idea is to use ODB database operation callbacks (Section 14.1.7, "callback"). All that hacking you've done to make various parts of ODB call you setDB() -- there is actually support for this in ODB. Sometimes it pays to read the manual ;-). In any case, here is the outline (I hate that "DAO" term, so using a more meaningful names): #include #include struct database_object { mutable odb::database* db_ = nullptr; void init (odb::callback_event, odb::database& db) const { db_ = &db; } }; #pragma db object callback(init) struct object1: database_object { ... }; #pragma db object callback(init) struct object2: database_object { ... }; The really cool thing about this approach is that you can set the database not only on loads but also on persists and updates. And you can use the callback_event argument to detect erases and reset db_ back to nullptr, since the object is no longer persistent. Now, if you have a persistent common base for all your objects (for example, that defines the "standard" object id for your model), then you won't even need to repear that callback() pragma for every persistent class: #pragma db object abstract callback(init) struct database_object { #pragma db id auto std::uint64_t id; #pragma db transient mutable odb::database* db_ = nullptr; void init (odb::callback_event, odb::database& db) const { db_ = &db; } }; #pragma db object struct object1: database_object { ... }; #pragma db object struct object2: database_object { ... }; Boris From boris at codesynthesis.com Fri Sep 18 02:18:44 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Sep 18 02:18:50 2015 Subject: [odb-users] how to include compiles odb files in Subprojects of QtCreator In-Reply-To: <55FADB20.1070200@aeronav.avianet.cu> References: <55FADB20.1070200@aeronav.avianet.cu> Message-ID: Hi Erick, Erick Jeronimo writes: > How can i import/include compiled odb files (-odb.hxx,..) to > Subprojects in QtCreator without compile again the same files > already compiled in other subproject. I think you will get better help with this on QtCreator's forums or mailing lists. Having said that, have you considered putting the generated files into a (static) library and then linking it to the various "Subprojects"? Surely QtCreator should have support for something like that. Boris From erick.jeronimo at aeronav.avianet.cu Fri Sep 18 09:24:19 2015 From: erick.jeronimo at aeronav.avianet.cu (Erick Jeronimo) Date: Fri Sep 18 11:12:47 2015 Subject: [odb-users] how to include compiles odb files in Subprojects of QtCreator In-Reply-To: References: <55FADB20.1070200@aeronav.avianet.cu> Message-ID: <55FC1083.3010006@aeronav.avianet.cu> Hi Boris, thanks for your answer. I'll try with shared libraries instead of static libraries.. Thanks On 09/18/2015 02:18 AM, Boris Kolpackov wrote: > Hi Erick, > > Erick Jeronimo writes: > >> How can i import/include compiled odb files (-odb.hxx,..) to >> Subprojects in QtCreator without compile again the same files >> already compiled in other subproject. > I think you will get better help with this on QtCreator's forums > or mailing lists. Having said that, have you considered putting > the generated files into a (static) library and then linking it > to the various "Subprojects"? Surely QtCreator should have support > for something like that. > > Boris > > From christian at gsvitec.com Sat Sep 19 06:38:57 2015 From: christian at gsvitec.com (Christian Sell) Date: Sat Sep 19 06:39:01 2015 Subject: [odb-users] mapping complex, templatized value types Message-ID: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> Hello, I am trying to map custom value types using the value_traits approach mentioned in the manual and exemplified in the mapping example from odb-examples. I can succefully map a simple type like: class Data { string something; } but I am failing to map complex templatized types like: ::std::shared_ptr< ::FlexisBase::SimplePropertyImp< ::std::basic_string< char >, ::FlexisBase::NoValidation< ::std::basic_string< char >, 2 >, 2 > > I have defined value_traits for both types, and as I said, the first type is picked up correctly. The second already fails in the #pragma db value(X) type("VARCHAR") line. Question: what restrictions exist with regard to the types that can be mapped using this approach? What can I do to map the second type? thanks, Christian From a.pasternak at mt-robot.com Sat Sep 19 07:53:33 2015 From: a.pasternak at mt-robot.com (Andreas Pasternak MT-Robot AG) Date: Sat Sep 19 07:53:34 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> Message-ID: <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> Did you try an C++11 type alias? using SPI = ::std::shared_ptr< ::FlexisBase::SimplePr... #pragma db value(SPI ) type("VARCHAR") ----------------original message----------------- From: Christian Sell [christian@gsvitec.com ] To: odb-users@codesynthesis.com Date: Sat, 19 Sep 2015 12:38:57 +0200 (CEST) ------------------------------------------------- > Hello, > I am trying to map custom value types using the value_traits > approach mentioned > in the manual and exemplified in the mapping example from odb-examples. I can > succefully map a simple type like: > > class Data { > string something; > } > > but I am failing to map complex templatized types like: > ::std::shared_ptr< ::FlexisBase::SimplePropertyImp< > ::std::basic_string< char >, > ::FlexisBase::NoValidation< ::std::basic_string< char >, 2 >, 2 > > > > I have defined value_traits for both types, and as I said, the first type is > picked up correctly. The second already fails in the > > #pragma db value(X) type("VARCHAR") > > line. > > Question: what restrictions exist with regard to the types that can be mapped > using this approach? What can I do to map the second type? > > thanks, > Christian > > -- MT Robot AG Riedstrasse 16 CH-4222 Zwingen Tel. - +41 (0)61 775 20 20 Direkt - +41 (0)61 775 20 26 Mobile - +41 (0)76 489 21 16 Fax - +41 (0)61 775 20 21 Email - [ mailto:a.pasternak@mt-robot.com %20%20 -> a.pasternak@mt-robot.com ] Web - www.mt-robot.com Diese E-Mail k?nnte vertrauliche und/oder rechtlich gesch?tzte Informationen enthalten.Wenn Sie nicht der richtige Adressat sind oder diese E-Mail irrt?mlich erhalten haben, informieren Sie bitte sofort den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser E-Mail sind nicht gestattet. This e-mail may contain confidential and/or privileged information. If you are not the intended recipien From christian at gsvitec.com Sat Sep 19 08:21:35 2015 From: christian at gsvitec.com (Christian Sell) Date: Sat Sep 19 08:21:37 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> Message-ID: <2039437477.8287905.1442665295294.JavaMail.open-xchange@patina.store> sure did: unable to map C++ type '::DTA' used in data member 'data3' to a SQLite database type > Andreas Pasternak MT-Robot AG hat am 19. September > 2015 um 13:53 geschrieben: > > > Did you try an C++11 type alias? > > using SPI = ::std::shared_ptr< ::FlexisBase::SimplePr... > #pragma db value(SPI ) type("VARCHAR") > > ----------------original message----------------- > From: Christian Sell [christian@gsvitec.com ] > To: odb-users@codesynthesis.com Date: Sat, 19 Sep 2015 12:38:57 +0200 (CEST) > ------------------------------------------------- > > > > Hello, > > I am trying to map custom value types using the value_traits > > approach mentioned > > in the manual and exemplified in the mapping example from odb-examples. I > > can > > succefully map a simple type like: > > > > class Data { > > string something; > > } > > > > but I am failing to map complex templatized types like: > > ::std::shared_ptr< ::FlexisBase::SimplePropertyImp< > > ::std::basic_string< char >, > > ::FlexisBase::NoValidation< ::std::basic_string< char >, 2 >, 2 > > > > > > I have defined value_traits for both types, and as I said, the first type is > > picked up correctly. The second already fails in the > > > > #pragma db value(X) type("VARCHAR") > > > > line. > > > > Question: what restrictions exist with regard to the types that can be > > mapped > > using this approach? What can I do to map the second type? > > > > thanks, > > Christian > > > > > > > -- > > > MT Robot AG > > Riedstrasse 16 > > CH-4222 Zwingen > Tel. - +41 (0)61 775 20 20 > Direkt - +41 (0)61 775 20 26 > Mobile - +41 (0)76 489 21 16 > Fax - +41 (0)61 775 20 21 > Email - [ mailto:a.pasternak@mt-robot.com %20%20 -> > a.pasternak@mt-robot.com ] > Web - www.mt-robot.com > Diese E-Mail k?nnte vertrauliche und/oder rechtlich gesch?tzte > Informationen enthalten.Wenn Sie nicht der richtige Adressat sind oder > diese E-Mail irrt?mlich erhalten haben, informieren Sie bitte sofort > den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren > sowie die unbefugte Weitergabe dieser E-Mail sind nicht gestattet. > > This e-mail may contain confidential and/or privileged information. If > you are not the intended recipien > Christian Sell GS Vitec GmbH Im Ziegelhaus 6-8 D-63571 Gelnhausen mail: christian@gsvitec.com mobil: +49 (0) 173 5384289 Tel: +49 (0) 6051 601.26-90 Fax: +49 (0) 6051 601.26-91 From christian at gsvitec.com Sat Sep 19 09:01:48 2015 From: christian at gsvitec.com (Christian Sell) Date: Sat Sep 19 09:01:52 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> Message-ID: <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> an observation: template instances do not work, neither directly nor through alias or typedef, e.g.: using DTA = ::std::shared_ptr>; //NOT usable subclassing the template class does work: class DTA : public ::std::shared_ptr> {} this is of course no real solution. I still hope there is a workaround.. Christian > Andreas Pasternak MT-Robot AG hat am 19. September > 2015 um 13:53 geschrieben: > > > Did you try an C++11 type alias? > > using SPI = ::std::shared_ptr< ::FlexisBase::SimplePr... > #pragma db value(SPI ) type("VARCHAR") > > ----------------original message----------------- > From: Christian Sell [christian@gsvitec.com ] > To: odb-users@codesynthesis.com Date: Sat, 19 Sep 2015 12:38:57 +0200 (CEST) > ------------------------------------------------- > > > > Hello, > > I am trying to map custom value types using the value_traits > > approach mentioned > > in the manual and exemplified in the mapping example from odb-examples. I > > can > > succefully map a simple type like: > > > > class Data { > > string something; > > } > > > > but I am failing to map complex templatized types like: > > ::std::shared_ptr< ::FlexisBase::SimplePropertyImp< > > ::std::basic_string< char >, > > ::FlexisBase::NoValidation< ::std::basic_string< char >, 2 >, 2 > > > > > > I have defined value_traits for both types, and as I said, the first type is > > picked up correctly. The second already fails in the > > > > #pragma db value(X) type("VARCHAR") > > > > line. > > > > Question: what restrictions exist with regard to the types that can be > > mapped > > using this approach? What can I do to map the second type? > > > > thanks, > > Christian > > > > > > > -- > > > MT Robot AG > > Riedstrasse 16 > > CH-4222 Zwingen > Tel. - +41 (0)61 775 20 20 > Direkt - +41 (0)61 775 20 26 > Mobile - +41 (0)76 489 21 16 > Fax - +41 (0)61 775 20 21 > Email - [ mailto:a.pasternak@mt-robot.com %20%20 -> > a.pasternak@mt-robot.com ] > Web - www.mt-robot.com > Diese E-Mail k?nnte vertrauliche und/oder rechtlich gesch?tzte > Informationen enthalten.Wenn Sie nicht der richtige Adressat sind oder > diese E-Mail irrt?mlich erhalten haben, informieren Sie bitte sofort > den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren > sowie die unbefugte Weitergabe dieser E-Mail sind nicht gestattet. > > This e-mail may contain confidential and/or privileged information. If > you are not the intended recipien > Christian Sell GS Vitec GmbH Im Ziegelhaus 6-8 D-63571 Gelnhausen mail: christian@gsvitec.com mobil: +49 (0) 173 5384289 Tel: +49 (0) 6051 601.26-90 Fax: +49 (0) 6051 601.26-91 From boris at codesynthesis.com Sat Sep 19 09:55:06 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sat Sep 19 09:55:11 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> Message-ID: Hi Christian, Christian Sell writes: > template instances do not work, neither directly nor through > alias or typedef Strange, this should work and appear to work for me: $ cat test.hxx #include #include using int_pair = std::pair; #pragma db value(int_pair) type("TEXT") using shared_short_pair = std::shared_ptr>; #pragma db value(shared_short_pair) type("TEXT") #pragma db object struct object { #pragma db id int id; int_pair ip; std::pair ip1; std::shared_ptr sip; // Ok, shared_ptr is a wrapper (Section 7.3). shared_short_pair ssp; std::shared_ptr> ssp1; }; $ odb -d sqlite -s --std c++11 test.hxx Can you try to adjust this example to reproduce your problem? Boris From christian at gsvitec.com Sat Sep 19 11:21:09 2015 From: christian at gsvitec.com (Christian Sell) Date: Sat Sep 19 11:21:13 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> Message-ID: <562079123.8298655.1442676070066.JavaMail.open-xchange@patina.store> will try.. however, I just realized that I still was on 2.3 and therefore decided to quickly upgrade.. quickly.. first, I was not able to install libodb-qt, because it didnt find my valid Qt 5.5 install. All attempts to fix this via command line options failed. Then I installed the rest, ran my makefile, and got In file included from /usr/local/include/odb/forward.hxx:10:0, from /usr/local/include/odb/nullable.hxx:10, from /usr/local/include/odb/wrapper-traits.hxx:12, from :5: /opt/odb-2.4.0-x86_64-linux-gnu/lib/odb/x86_64-linux-gnu/include/c++/4.9.3/cstddef:51:11: error: ?::max_align_t? has not been declared so I am stuck for now.. > Boris Kolpackov hat am 19. September 2015 um 15:55 > geschrieben: > > > Hi Christian, > > Christian Sell writes: > > > template instances do not work, neither directly nor through > > alias or typedef > > Strange, this should work and appear to work for me: > > $ cat test.hxx > > #include > #include > > using int_pair = std::pair; > #pragma db value(int_pair) type("TEXT") > > using shared_short_pair = std::shared_ptr>; > #pragma db value(shared_short_pair) type("TEXT") > > #pragma db object > struct object > { > #pragma db id > int id; > > int_pair ip; > std::pair ip1; > > std::shared_ptr sip; // Ok, shared_ptr is a wrapper (Section 7.3). > > shared_short_pair ssp; > std::shared_ptr> ssp1; > }; > > $ odb -d sqlite -s --std c++11 test.hxx > > Can you try to adjust this example to reproduce your problem? > > Boris Christian Sell From christian at gsvitec.com Sat Sep 19 12:39:11 2015 From: christian at gsvitec.com (Christian Sell) Date: Sat Sep 19 12:39:14 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> Message-ID: <1608086312.8303521.1442680751599.JavaMail.open-xchange@patina.store> Hello Boris, I have been able to work around the max_align error by adding a #include at the top of the header file containing the mapped classes. This seems to be an issue with gcc versions. I then tried the stuff you gave, and it worked. I have looked into the issues with my classes, and it seems to me that the problem lies with the code generated by odb, which is not compilable for my classes (the set_value method is generated with 4 instead of 3 parameters). I have everything packaged in a small sample app, which I could mail to you. regards, Christian > Boris Kolpackov hat am 19. September 2015 um 15:55 > geschrieben: > > > Hi Christian, > > Christian Sell writes: > > > template instances do not work, neither directly nor through > > alias or typedef > > Strange, this should work and appear to work for me: > > $ cat test.hxx > > #include > #include > > using int_pair = std::pair; > #pragma db value(int_pair) type("TEXT") > > using shared_short_pair = std::shared_ptr>; > #pragma db value(shared_short_pair) type("TEXT") > > #pragma db object > struct object > { > #pragma db id > int id; > > int_pair ip; > std::pair ip1; > > std::shared_ptr sip; // Ok, shared_ptr is a wrapper (Section 7.3). > > shared_short_pair ssp; > std::shared_ptr> ssp1; > }; > > $ odb -d sqlite -s --std c++11 test.hxx > > Can you try to adjust this example to reproduce your problem? > > Boris Christian Sell GS Vitec GmbH Im Ziegelhaus 6-8 D-63571 Gelnhausen mail: christian@gsvitec.com mobil: +49 (0) 173 5384289 Tel: +49 (0) 6051 601.26-90 Fax: +49 (0) 6051 601.26-91 From christian at gsvitec.com Sat Sep 19 13:03:40 2015 From: christian at gsvitec.com (Christian Sell) Date: Sat Sep 19 13:03:42 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: <1608086312.8303521.1442680751599.JavaMail.open-xchange@patina.store> References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> <1608086312.8303521.1442680751599.JavaMail.open-xchange@patina.store> Message-ID: <1581296639.8304951.1442682220364.JavaMail.open-xchange@patina.store> never mind - I had the value_traits wrongly implemented. Template stuff can get quite confusing at times.. So the real problem lay with version 2.3 I presume and was fixed by the upgrade thanks > Christian Sell hat am 19. September 2015 um 18:39 > geschrieben: > > > Hello Boris, > > I have been able to work around the max_align error by adding a #include > at the top of the header file containing the mapped classes. This > seems to be an issue with gcc versions. > > I then tried the stuff you gave, and it worked. I have looked into the issues > with my classes, and it seems to me that the problem lies with the code > generated by odb, which is not compilable for my classes (the set_value method > is generated with 4 instead of 3 parameters). I have everything packaged in a > small sample app, which I could mail to you. > > regards, > Christian > > > > Boris Kolpackov hat am 19. September 2015 um 15:55 > > geschrieben: > > > > > > Hi Christian, > > > > Christian Sell writes: > > > > > template instances do not work, neither directly nor through > > > alias or typedef > > > > Strange, this should work and appear to work for me: > > > > $ cat test.hxx > > > > #include > > #include > > > > using int_pair = std::pair; > > #pragma db value(int_pair) type("TEXT") > > > > using shared_short_pair = std::shared_ptr>; > > #pragma db value(shared_short_pair) type("TEXT") > > > > #pragma db object > > struct object > > { > > #pragma db id > > int id; > > > > int_pair ip; > > std::pair ip1; > > > > std::shared_ptr sip; // Ok, shared_ptr is a wrapper (Section 7.3). > > > > shared_short_pair ssp; > > std::shared_ptr> ssp1; > > }; > > > > $ odb -d sqlite -s --std c++11 test.hxx > > > > Can you try to adjust this example to reproduce your problem? > > > > Boris > Christian Sell > > GS Vitec GmbH > Im Ziegelhaus 6-8 > D-63571 Gelnhausen > > mail: christian@gsvitec.com > mobil: +49 (0) 173 5384289 > > Tel: +49 (0) 6051 601.26-90 > Fax: +49 (0) 6051 601.26-91 > Christian Sell GS Vitec GmbH Im Ziegelhaus 6-8 D-63571 Gelnhausen mail: christian@gsvitec.com mobil: +49 (0) 173 5384289 Tel: +49 (0) 6051 601.26-90 Fax: +49 (0) 6051 601.26-91 From adanesh at noornet.net Sat Sep 19 13:29:07 2015 From: adanesh at noornet.net (=?utf-8?B?2LnZhNuMINiv2KfZhti0?=) Date: Sat Sep 19 13:29:24 2015 Subject: [odb-users] BaseDaoEnabled for ODB In-Reply-To: References: , Message-ID: <780031f9ffa84dadbd7ff39813f6cab0@exch.crcis.local> Hi Boris, Your solution is much better than I did. I used and enjoyed. :) Thanks, Ali ________________________________________ From: Boris Kolpackov Sent: Friday, September 18, 2015 10:44 AM To: ??? ???? Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] BaseDaoEnabled for ODB Hi Ali, > I changed the odb code to add this feature. It works up to now and > I have not any problem yet, but I am not sure is it a good solution > or not? Is it possible for you to review it and inform me about > possible problems in it? Sorry, can't review it, it's just too messy. But I can suggest a much cleaner solution: The idea is to use ODB database operation callbacks (Section 14.1.7, "callback"). All that hacking you've done to make various parts of ODB call you setDB() -- there is actually support for this in ODB. Sometimes it pays to read the manual ;-). In any case, here is the outline (I hate that "DAO" term, so using a more meaningful names): #include #include struct database_object { mutable odb::database* db_ = nullptr; void init (odb::callback_event, odb::database& db) const { db_ = &db; } }; #pragma db object callback(init) struct object1: database_object { ... }; #pragma db object callback(init) struct object2: database_object { ... }; The really cool thing about this approach is that you can set the database not only on loads but also on persists and updates. And you can use the callback_event argument to detect erases and reset db_ back to nullptr, since the object is no longer persistent. Now, if you have a persistent common base for all your objects (for example, that defines the "standard" object id for your model), then you won't even need to repear that callback() pragma for every persistent class: #pragma db object abstract callback(init) struct database_object { #pragma db id auto std::uint64_t id; #pragma db transient mutable odb::database* db_ = nullptr; void init (odb::callback_event, odb::database& db) const { db_ = &db; } }; #pragma db object struct object1: database_object { ... }; #pragma db object struct object2: database_object { ... }; Boris From christian at gsvitec.com Sun Sep 20 06:31:48 2015 From: christian at gsvitec.com (Christian Sell) Date: Sun Sep 20 06:31:52 2015 Subject: [odb-users] Lazy Relationships? Message-ID: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> Hello, just now I realize that when I load an object that has relationships, all relatioships are loaded as well (and that using plain select statements without join.. duh). This can obviously be a real performance issue. The only solution I have found so far is using a section. However, that requires a section instance variable in the mapped class, which is not easily done for me, since I am mapping library classes. We do, however, already have our own collection classes which I intend to make known to ODB using the collection_traits mechanism. These containers are also used to implement relationships (i.e., containers with shared pointers to mapped classes). My questions: - does the collection_traits mechanism allow us to implement relationships in the way described above? - if it does, is there a way to make relationship resolution lazy, such that the rlationship is only loaded on demand (e.g., when I say department->employees)? thanks, Christian From christian at gsvitec.com Mon Sep 21 05:30:20 2015 From: christian at gsvitec.com (Christian Sell) Date: Mon Sep 21 05:30:24 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: <1581296639.8304951.1442682220364.JavaMail.open-xchange@patina.store> References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> <1608086312.8303521.1442680751599.JavaMail.open-xchange@patina.store> <1581296639.8304951.1442682220364.JavaMail.open-xchange@patina.store> Message-ID: <1028539932.8637773.1442827820786.JavaMail.open-xchange@ptangptang.store> I have to again correct myself. The problem was that I was mapping long values, and ODB generates different method signatures for those (no buffer and size but only a value). The mapping example only contains code for string, so one has to employ investigative effort to find the solution christian > Christian Sell hat am 19. September 2015 um 19:03 > geschrieben: > > never mind - I had the value_traits wrongly implemented. Template stuff can > get quite confusing at times.. > > So the real problem lay with version 2.3 I presume and was fixed by the > upgrade > > thanks > > > Christian Sell hat am 19. September 2015 um 18:39 > > geschrieben: > > > > > > Hello Boris, > > > > I have been able to work around the max_align error by adding a #include > > at the top of the header file containing the mapped classes. This > > seems to be an issue with gcc versions. > > > > I then tried the stuff you gave, and it worked. I have looked into the > > issues > > with my classes, and it seems to me that the problem lies with the code > > generated by odb, which is not compilable for my classes (the set_value > > method > > is generated with 4 instead of 3 parameters). I have everything packaged in > > a > > small sample app, which I could mail to you. > > > > regards, > > Christian > > > > > > > Boris Kolpackov hat am 19. September 2015 um > > > 15:55 > > > geschrieben: > > > > > > > > > Hi Christian, > > > > > > Christian Sell writes: > > > > > > > template instances do not work, neither directly nor through > > > > alias or typedef > > > > > > Strange, this should work and appear to work for me: > > > > > > $ cat test.hxx > > > > > > #include > > > #include > > > > > > using int_pair = std::pair; > > > #pragma db value(int_pair) type("TEXT") > > > > > > using shared_short_pair = std::shared_ptr>; > > > #pragma db value(shared_short_pair) type("TEXT") > > > > > > #pragma db object > > > struct object > > > { > > > #pragma db id > > > int id; > > > > > > int_pair ip; > > > std::pair ip1; > > > > > > std::shared_ptr sip; // Ok, shared_ptr is a wrapper (Section > > > 7.3). > > > > > > shared_short_pair ssp; > > > std::shared_ptr> ssp1; > > > }; > > > > > > $ odb -d sqlite -s --std c++11 test.hxx > > > > > > Can you try to adjust this example to reproduce your problem? > > > > > > Boris > > Christian Sell > > > > GS Vitec GmbH > > Im Ziegelhaus 6-8 > > D-63571 Gelnhausen > > > > mail: christian@gsvitec.com > > mobil: +49 (0) 173 5384289 > > > > Tel: +49 (0) 6051 601.26-90 > > Fax: +49 (0) 6051 601.26-91 > > > Christian Sell > > GS Vitec GmbH > Im Ziegelhaus 6-8 > D-63571 Gelnhausen > > mail: christian@gsvitec.com > mobil: +49 (0) 173 5384289 > > Tel: +49 (0) 6051 601.26-90 > Fax: +49 (0) 6051 601.26-91 > Christian Sell GS Vitec GmbH Im Ziegelhaus 6-8 D-63571 Gelnhausen mail: christian@gsvitec.com mobil: +49 (0) 173 5384289 Tel: +49 (0) 6051 601.26-90 Fax: +49 (0) 6051 601.26-91 From christian at gsvitec.com Mon Sep 21 08:01:58 2015 From: christian at gsvitec.com (Christian Sell) Date: Mon Sep 21 08:02:02 2015 Subject: [odb-users] multi-file schema? Message-ID: <1102530626.8685727.1442836918203.JavaMail.open-xchange@ptangptang.store> Hello, I am trying to map a schema that is distributed over several header files. Right now I have one central application header which #includes a library header file. There is one class from that library header file which I want to map: main.h LocalObject #include LibraryObject now, since I cannot modify the library code, I am using a pragma-only epilogue file, which looks like: #include "main.h" #include "library.h" #pragma db model version(1, 1) #pragma db object(LibraryObject) #pragma db member(LibraryObject::name) I am invoking odb with the following command line: odb --std c++11 -x -fPIC -d sqlite --generate-query --generate-session --generate-schema --changelog changelog --schema-format separate --schema-name flexis --odb-epilogue-file pragamafile as a result I get a main_odb.cpp file which #includes a non-existent "library_odb.h" file and an empty schema Question: does ODB support mapping classes from different headers into one common schema? If yes, how? What am I doing wrong? thanks, Christian From christian at gsvitec.com Mon Sep 21 10:48:41 2015 From: christian at gsvitec.com (Christian Sell) Date: Mon Sep 21 10:48:47 2015 Subject: [odb-users] multi-file schema? In-Reply-To: <1102530626.8685727.1442836918203.JavaMail.open-xchange@ptangptang.store> References: <1102530626.8685727.1442836918203.JavaMail.open-xchange@ptangptang.store> Message-ID: <53276272.8736152.1442846921979.JavaMail.open-xchange@ptangptang.store> ok, I've gotten a litle further by adding the --at-once option to the odb command line: odb --std c++11 -x -fPIC -d sqlite --generate-query --generate-session --generate-schema --changelog changelog --schema-format separate --schema-name --at-once main-h this does generate code for LibraryObject into the cpp and h files, and everything is compilable. But still no tables for LibraryObject in the schema. ? Chris > Christian Sell hat am 21. September 2015 um 14:01 > geschrieben: > > > Hello, > > I am trying to map a schema that is distributed over several header files. > Right > now I have one central application header which #includes a library header > file. > There is one class from that library header file which I want to map: > > main.h > LocalObject > #include > LibraryObject > > now, since I cannot modify the library code, I am using a pragma-only epilogue > file, which looks like: > > #include "main.h" > #include "library.h" > > #pragma db model version(1, 1) > #pragma db object(LibraryObject) > #pragma db member(LibraryObject::name) > > > I am invoking odb with the following command line: > > odb --std c++11 -x -fPIC -d sqlite --generate-query --generate-session > --generate-schema --changelog changelog --schema-format separate --schema-name > flexis --odb-epilogue-file pragamafile > > > as a result I get a main_odb.cpp file which #includes a non-existent > "library_odb.h" file and an empty schema > > Question: does ODB support mapping classes from different headers into one > common schema? If yes, how? What am I doing wrong? > > thanks, > Christian > From boris at codesynthesis.com Mon Sep 21 10:51:15 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 21 10:51:17 2015 Subject: [odb-users] mapping complex, templatized value types In-Reply-To: <1028539932.8637773.1442827820786.JavaMail.open-xchange@ptangptang.store> References: <1934133047.8280601.1442659137534.JavaMail.open-xchange@patina.store> <20150919135333.EGroupware.3OBj12lW3Dc-phnDnrlsrbE@mail.mt-robot.com> <1313242852.8290421.1442667708750.JavaMail.open-xchange@patina.store> <1608086312.8303521.1442680751599.JavaMail.open-xchange@patina.store> <1581296639.8304951.1442682220364.JavaMail.open-xchange@patina.store> <1028539932.8637773.1442827820786.JavaMail.open-xchange@ptangptang.store> Message-ID: Christian Sell writes: > The mapping example only contains code for string, so one has to employ > investigative effort to find the solution ... or just look in /trait.hxx> for examples. Boris From Tim.Tao at akunacapital.com Mon Sep 21 09:09:50 2015 From: Tim.Tao at akunacapital.com (Tim Tao) Date: Mon Sep 21 10:52:16 2015 Subject: [odb-users] Index on subtable column "index" Message-ID: Hi ODB support, I got a question about ODB subtable, so when we declare a container, e.g vector, in an ODB object, it will create a subtable for this container and a new column "index" with it, which is a very good design I think, but I am wondering why ODB will also add an index on this "index" column, is there any performance consideration? To me this index seems useless since the subtable already has an index on its parent table's primary key. Looking forward to your reply Thanks! ________________________________ [http://www.akunacapital.com/images/akuna.png] Tim Tao | Junior Developer | www.akunacapital.com p: | m: | f: | tim.tao@akunacapital.com Please consider the environment, before printing this email. This electronic message contains information from Akuna Capital LLC that may be confidential, legally privileged or otherwise protected from disclosure. This information is intended for the use of the addressee only and is not offered as investment advice to be relied upon for personal or professional use. Additionally, all electronic messages are recorded and stored in compliance pursuant to applicable SEC rules. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, printing or any other use of, or any action in reliance on, the contents of this electronic message is strictly prohibited. If you have received this communication in error, please notify us by telephone at (312)994-4640 and destroy the original message. From boris at codesynthesis.com Mon Sep 21 11:01:36 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 21 11:01:39 2015 Subject: [odb-users] Index on subtable column "index" In-Reply-To: References: Message-ID: Hi Tim, Tim Tao writes: > I got a question about ODB subtable, so when we declare a container, > e.g vector, in an ODB object, it will create a subtable for this > container and a new column "index" with it, which is a very good > design I think, but I am wondering why ODB will also add an index > on this "index" column, is there any performance consideration? Yes, the SELECT statement that loads the elements of the container, has the 'ORDER BY index' clause. Boris From boris at codesynthesis.com Mon Sep 21 11:07:13 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 21 11:07:16 2015 Subject: [odb-users] multi-file schema? In-Reply-To: <53276272.8736152.1442846921979.JavaMail.open-xchange@ptangptang.store> References: <1102530626.8685727.1442836918203.JavaMail.open-xchange@ptangptang.store> <53276272.8736152.1442846921979.JavaMail.open-xchange@ptangptang.store> Message-ID: Hi Christian, Christian Sell writes: > ok, I've gotten a litle further by adding the --at-once option to the odb > command line: Take a look also at the 'definition' pragma (Section 4.1.11). Probably a more appropriate mechanism in this case. > odb --std c++11 -x -fPIC -d sqlite --generate-query --generate-session > --generate-schema --changelog changelog --schema-format separate --schema-name > --at-once main-h > > this does generate code for LibraryObject into the cpp and h files, and > everything is compilable. But still no tables for LibraryObject in the > schema. What *exactly* happens? You specified '--schema-format separate' which means the schema should be generated into a separate file, in your case, main-h-schema.cxx. Is this file not geneated? Is it generated but doesn't contain the schema? Boris From boris at codesynthesis.com Mon Sep 21 11:16:35 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 21 11:16:37 2015 Subject: [odb-users] Lazy Relationships? In-Reply-To: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> References: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> Message-ID: Hi Christian, Christian Sell writes: > just now I realize that when I load an object that has relationships, all > relatioships are loaded as well (and that using plain select statements > without join.. duh). See object loading views (Section 10.2) for the "duh" part. > This can obviously be a real performance issue. No kidding. How come we never thought about it..? Oh, wait a second, there is this Section 6.4, "Lazy Pointers" in Chapter 6, "Relatioships". Sounds almost exactly like the subject of this email... > We do, however, already have our own collection classes which I intend to > make known to ODB using the collection_traits mechanism. It's called container_traits, not collection_traits. Boris From christian at gsvitec.com Mon Sep 21 11:32:33 2015 From: christian at gsvitec.com (Christian Sell) Date: Mon Sep 21 11:32:37 2015 Subject: [odb-users] multi-file schema? In-Reply-To: References: <1102530626.8685727.1442836918203.JavaMail.open-xchange@ptangptang.store> <53276272.8736152.1442846921979.JavaMail.open-xchange@ptangptang.store> Message-ID: <364452775.8747101.1442849553178.JavaMail.open-xchange@ptangptang.store> > Take a look also at the 'definition' pragma (Section 4.1.11). Probably > a more appropriate mechanism in this case. the docs here talk about "value types", but I have a fully mapped class that resides in the library > What *exactly* happens? You specified '--schema-format separate' which > means the schema should be generated into a separate file, in your > case, main-h-schema.cxx. Is this file not geneated? Is it generated > but doesn't contain the schema? it doesn't matter what schema-format I choose. There are no CREATE TABLE statements anywhere for the mapped library class, although there is support code that refers to it in the generated C++ files. chris From christian at gsvitec.com Mon Sep 21 11:48:29 2015 From: christian at gsvitec.com (Christian Sell) Date: Mon Sep 21 11:48:33 2015 Subject: [odb-users] Lazy Relationships? In-Reply-To: References: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> Message-ID: <972643647.8750693.1442850509343.JavaMail.open-xchange@ptangptang.store> Hello Boris, > See object loading views (Section 10.2) for the "duh" part. the duh refers to the fact that a standard load operation which pulls data from multiple related tables does not use the obvious SQL optimization meachnisms. There may be ways to get the optimized SQL, but I see no reason why they shouldn't be employed transparently in the standard case as well. As an aside: I have spent roughly a decade of my worklife writing and using object/relational mapping tools for other languages (Smalltalk and Java), and that was the behaviour I got used to. > No kidding. How come we never thought about it..? Oh, wait a second, > there is this Section 6.4, "Lazy Pointers" in Chapter 6, "Relatioships". > Sounds almost exactly like the subject of this email... no, not kidding. I have of course read that chapter, and even after re-reading it I don't see how it (directly) relates to my request. I am talking about a to-N relationship which is lazily resolved, not a pointer (which, in my book, points to one object). Let me know if I overlooked something Christian From Tim.Tao at akunacapital.com Mon Sep 21 11:41:23 2015 From: Tim.Tao at akunacapital.com (Tim Tao) Date: Mon Sep 21 11:52:58 2015 Subject: [odb-users] Index on subtable column "index" In-Reply-To: References: , Message-ID: Hi Boris, Thanks for your reply. Another question about the subtable. I notice all the subtables don't have primary key. I don't know if I can use the combination of parent table's primary key and "index" as the primary key of the subtable? Is there any reason we don't want to do that. Thanks ! Tim ________________________________________ From: Boris Kolpackov Sent: Monday, September 21, 2015 10:01 AM To: Tim Tao Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Index on subtable column "index" Hi Tim, Tim Tao writes: > I got a question about ODB subtable, so when we declare a container, > e.g vector, in an ODB object, it will create a subtable for this > container and a new column "index" with it, which is a very good > design I think, but I am wondering why ODB will also add an index > on this "index" column, is there any performance consideration? Yes, the SELECT statement that loads the elements of the container, has the 'ORDER BY index' clause. Boris ________________________________ [http://www.akunacapital.com/images/akuna.png] Tim Tao | Junior Developer | www.akunacapital.com p: | m: | f: | tim.tao@akunacapital.com Please consider the environment, before printing this email. This electronic message contains information from Akuna Capital LLC that may be confidential, legally privileged or otherwise protected from disclosure. This information is intended for the use of the addressee only and is not offered as investment advice to be relied upon for personal or professional use. Additionally, all electronic messages are recorded and stored in compliance pursuant to applicable SEC rules. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, printing or any other use of, or any action in reliance on, the contents of this electronic message is strictly prohibited. If you have received this communication in error, please notify us by telephone at (312)994-4640 and destroy the original message. From christian at gsvitec.com Mon Sep 21 11:54:11 2015 From: christian at gsvitec.com (Christian Sell) Date: Mon Sep 21 11:54:13 2015 Subject: [odb-users] multi-file schema? In-Reply-To: References: <1102530626.8685727.1442836918203.JavaMail.open-xchange@ptangptang.store> <53276272.8736152.1442846921979.JavaMail.open-xchange@ptangptang.store> Message-ID: <1736438104.8752077.1442850851639.JavaMail.open-xchange@ptangptang.store> > What *exactly* happens? You specified '--schema-format separate' which > means the schema should be generated into a separate file, in your > case, main-h-schema.cxx. Is this file not geneated? Is it generated > but doesn't contain the schema? to be more specific with regard to your question: the schema file is generated (if I use separate), and it contains CREATE TABLE statements (e.g. for the schema_version table), but none for the library class chris From boris at codesynthesis.com Mon Sep 21 12:04:18 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 21 12:20:03 2015 Subject: [odb-users] multi-file schema? In-Reply-To: <1736438104.8752077.1442850851639.JavaMail.open-xchange@ptangptang.store> References: <1102530626.8685727.1442836918203.JavaMail.open-xchange@ptangptang.store> <53276272.8736152.1442846921979.JavaMail.open-xchange@ptangptang.store> <1736438104.8752077.1442850851639.JavaMail.open-xchange@ptangptang.store> Message-ID: Hi Christian, Christian Sell writes: > to be more specific with regard to your question: the schema file is > generated (if I use separate), and it contains CREATE TABLE statements > (e.g. for the schema_version table), but none for the library class Normally, it should be you who provides the test that reproduces the problem, so this is the last time: $ cat test.hxx struct object { int id; int value; }; $ cat test-mapping.hxx #include #pragma db object(object) definition #pragma db member(object::id) id auto $ odb -d sqlite -s --schema-format separate --std c++11 -I. --input-name test test-mapping.hxx $ cat test-schema.cxx [...] db.execute ("CREATE TABLE \"object\" (\n" " \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n" " \"value\" INTEGER NOT NULL)"); [...] Boris From a.pasternak at mt-robot.com Tue Sep 22 10:04:54 2015 From: a.pasternak at mt-robot.com (Andreas Pasternak MT-Robot AG) Date: Tue Sep 22 10:04:54 2015 Subject: [odb-users] Automatically persist / update relations Message-ID: <20150922160454.EGroupware.i7k-hBqYpI46nJDYIPlm17D@10.0.0.38> Hello all, I have: #pragma db object struct Val { short id; string value; }; #pragma db object struct Cont{ std::vector> vals_rel; } To persist all of Cont I have to write: Cont c; db.persist(c); for(val : vals_rel) db.persist(val); But I'd like that ODB checks all relations automatically and inserts / updates them. The background is that I get the Cont class via network inclusive all data referenced by pointers and the recieving client might not have the related database entries yet. Best regards, Andreas From boris at codesynthesis.com Tue Sep 22 10:39:15 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 22 10:39:18 2015 Subject: [odb-users] Automatically persist / update relations In-Reply-To: <20150922160454.EGroupware.i7k-hBqYpI46nJDYIPlm17D@10.0.0.38> References: <20150922160454.EGroupware.i7k-hBqYpI46nJDYIPlm17D@10.0.0.38> Message-ID: Hi Andreas, Andreas Pasternak MT-Robot AG writes: > But I'd like that ODB checks all relations automatically and inserts > / updates them. No, ODB doesn't do this. It would be too "magicy" to work reliably and with a reasonably-good performance. For example, how does ODB know that the object is not yet persistent? Similarly, how would it know whether the object has changed (and thus needs to be updated)? On the other hand, if you make a few application-specific assumptions, this should be pretty easy to implement yourself. For example, you can use 0 as a special "not persistent" object id (auto ids always start from 1). You can also have a flag that keeps track of whether the object has changed. The final ingredient is the database operation callback (Section 14.1.7 in the manual). In it, you can check and update/persist all the relationships of an object, if necessary. Boris From boris at codesynthesis.com Tue Sep 22 10:42:24 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 22 10:42:25 2015 Subject: [odb-users] Index on subtable column "index" In-Reply-To: References: Message-ID: Hi Tim, Tim Tao writes: > Another question about the subtable. Please in the future start another thread with proper subject for "another question". See the posting guidelines for details: http://www.codesynthesis.com/support/posting-guidelines.xhtml > I notice all the subtables don't have primary key. I don't > know if I can use the combination of parent table's primary > key and "index" as the primary key of the subtable? Is there > any reason we don't want to do that. No, the object id and index pair would be unique so could be a primary key. Boris From boris at codesynthesis.com Tue Sep 22 10:54:56 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 22 10:54:59 2015 Subject: [odb-users] Lazy Relationships? In-Reply-To: <972643647.8750693.1442850509343.JavaMail.open-xchange@ptangptang.store> References: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> <972643647.8750693.1442850509343.JavaMail.open-xchange@ptangptang.store> Message-ID: Hi Christian, Christian Sell writes: > the duh refers to the fact that a standard load operation which pulls data from > multiple related tables does not use the obvious SQL optimization meachnisms. > There may be ways to get the optimized SQL, but I see no reason why they > shouldn't be employed transparently in the standard case as well. There are reasons. Firstly, in most non-trivial applications most relationships will be lazy, at least this is what we advocate. Secondly, consider a to-many relationship: If you JOIN the relationship data to the same SELECT statement, you are going to fetch N copies of the object. Maybe not a big deal unless N is large or you have a couple of massive BLOBs in the object. So, as you can see, this is not as clear cut as you make it sound. And the "ODB way", in such situations, is not to make any assumptions and instead give you the mechanisms and control to do it either way (See the "Object Loading Views" Section for how to get the behavior that you advocate). > I am talking about a to-N relationship which is lazily resolved, not > a pointer (which, in my book, points to one object). Let me know if > I overlooked something Say you have: std::vector> objects; In this setup the object ids for all the pointed-to objects will be loaded eagerly, but not the objects themselves. To load the objects, you will have to load them explicitly by calling load() on each element (lazy_ptr). Now, you may want to get even lazier and not even load object ids. This you can only do by placing 'objects' into a lazy-loaded section. In fact, the chapter on sections talks about this two-level laziness. Boris From christian at gsvitec.com Tue Sep 22 11:32:17 2015 From: christian at gsvitec.com (Christian Sell) Date: Tue Sep 22 11:32:21 2015 Subject: [odb-users] Lazy Relationships? In-Reply-To: References: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> <972643647.8750693.1442850509343.JavaMail.open-xchange@ptangptang.store> Message-ID: <1890784003.8968373.1442935938142.JavaMail.open-xchange@ptangptang.store> > Secondly, consider a to-many relationship: If you JOIN the > relationship data to the same SELECT statement, you are going to > fetch N copies of the object. outer join. It's been done before. Fetching ids only is another performance killer (N+1 problem). Of course there must be switches to allow adaptation to the concrete data model (BLOBs etc.). But hey, it is as it is - my application is not a big data cruncher. > Now, you may want to get even lazier and not even load object ids. > This you can only do by placing 'objects' into a lazy-loaded section. > In fact, the chapter on sections talks about this two-level laziness. yes, and in fact, I mentioned sections as the only way I had found to achieve "full lazyness". However, this is not feasible because, as I said, I am mapping classes that I cannot modify. Therefore my question was if I could achieve the same with custom relationship (container) and accompanying container_traits chris From Tim.Tao at akunacapital.com Tue Sep 22 13:33:16 2015 From: Tim.Tao at akunacapital.com (Tim Tao) Date: Tue Sep 22 14:43:31 2015 Subject: [odb-users] ODB query Message-ID: Hi Boris, I got a question about ODB query statement, suppose I have the following odb objects: #pragma db object struct A{ string name; } #pragma db object struct B{ std::shared_ptr ptr; } Is there any way we can query table B by using condition ptr->name == "Tom" ? Since A is a pointer in table B...I dont know how to write the query statement, I tried db->query(query::name == "Tom") but got no lucky. Thanks, Tim ________________________________ [http://www.akunacapital.com/images/akuna.png] Tim Tao | Junior Developer | www.akunacapital.com p: | m: | f: | tim.tao@akunacapital.com Please consider the environment, before printing this email. This electronic message contains information from Akuna Capital LLC that may be confidential, legally privileged or otherwise protected from disclosure. This information is intended for the use of the addressee only and is not offered as investment advice to be relied upon for personal or professional use. Additionally, all electronic messages are recorded and stored in compliance pursuant to applicable SEC rules. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, printing or any other use of, or any action in reliance on, the contents of this electronic message is strictly prohibited. If you have received this communication in error, please notify us by telephone at (312)994-4640 and destroy the original message. From markus at markusklemm.net Wed Sep 23 02:50:46 2015 From: markus at markusklemm.net (Markus Klemm) Date: Wed Sep 23 02:50:59 2015 Subject: [odb-users] ODB query In-Reply-To: References: Message-ID: <629BD919-A49F-4976-B9BF-BF45523A8352@markusklemm.net> Forgot to send this to the list: > Am 22.09.2015 um 23:27 schrieb Markus Klemm : > > I'm not sure, since I'm writing this in the tram, but (query::A::name == "Tom") should do the trick. > > Regards/Mit freundlichen Gr??en > > Markus Klemm > > Gesendet via Mobiltelefon > >> Am 22.09.2015 um 19:33 schrieb Tim Tao : >> >> (query::name == "Tom") From Tim.Tao at akunacapital.com Tue Sep 22 19:38:41 2015 From: Tim.Tao at akunacapital.com (Tim Tao) Date: Wed Sep 23 11:28:17 2015 Subject: [odb-users] update object without caching the query result Message-ID: Hi ODB users, Is there any way we can update an object without caching the query result ? I query the database and load() each result, it seems like this will cache the result in the application memory which is unnecessary..... Any solutions? Thanks, Tim ________________________________ [http://www.akunacapital.com/images/akuna.png] Tim Tao | Junior Developer | www.akunacapital.com p: | m: | f: | tim.tao@akunacapital.com Please consider the environment, before printing this email. This electronic message contains information from Akuna Capital LLC that may be confidential, legally privileged or otherwise protected from disclosure. This information is intended for the use of the addressee only and is not offered as investment advice to be relied upon for personal or professional use. Additionally, all electronic messages are recorded and stored in compliance pursuant to applicable SEC rules. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, printing or any other use of, or any action in reliance on, the contents of this electronic message is strictly prohibited. If you have received this communication in error, please notify us by telephone at (312)994-4640 and destroy the original message. From boris at codesynthesis.com Wed Sep 23 11:34:08 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 23 11:34:09 2015 Subject: [odb-users] ODB query In-Reply-To: References: Message-ID: Hi Tim, Tim Tao writes: > Is there any way we can query table B by using condition ptr->name == "Tom"? Yes, that's exactly how you would do it: A::ptr->name == "Tom". As always, the manual is your friend. Quoting from Chapter 6, "Relationships": " We can also use data members from pointed-to objects in database queries (Chapter 4, "Querying the Database"). For each pointer in a persistent class, the query class defines a smart pointer-like member that contains members corresponding to the data members in the pointed-to object. We can then use the access via a pointer syntax (->) to refer to data members in pointed-to objects. For example, the query class for the employee object contains the employer member (its name is derived from the employer_ pointer) which in turn contains the name member (its name is derived from the employer::name_ data member of the pointed-to object). As a result, we can use the query::employer->name expression while querying the database for the employee objects. For example, the following transaction finds all the employees of Example Inc that have the Doe last name: typedef odb::query query; typedef odb::result result; session s; transaction t (db.begin ()); result r (db.query ( query::employer->name == "Example Inc" && query::last == "Doe")); for (result::iterator i (r.begin ()); i != r.end (); ++i) cout << i->first_ << " " << i->last_ << endl; t.commit (); A query class member corresponding to a non-inverse (Section 6.2, "Bidirectional Relationships") object pointer can also be used as a normal member that has the id type of the pointed-to object. For example, the following query locates all the employee objects that don't have an associated employer object: result r (db.query (query::employer.is_null ())); " Boris From christian at gsvitec.com Wed Sep 23 11:51:41 2015 From: christian at gsvitec.com (Christian Sell) Date: Wed Sep 23 11:51:44 2015 Subject: [odb-users] custom relationship containers? Message-ID: <540420223.9211626.1443023501886.JavaMail.open-xchange@ptangptang.store> hello, after having successfully introduced my own custom container class by implementing the appropriate value_trais template, I would now like to also use this container in relationships (i.e. the container holds shared_ptrs to a mapped class). However, I am getting the meanwhile well-known error error: unable to map C++ type '::FlexisBase::SharedPtrVectorProperty< ::flexis_data::Recording >' used in data member 'recordings' to a SQLite database type info: use '#pragma db type' to specify the database type just to make sure: is it possible to use custom containers in relationships? What might I be doing wrong? thanks, Christian From boris at codesynthesis.com Wed Sep 23 12:05:05 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 23 12:05:07 2015 Subject: [odb-users] custom relationship containers? In-Reply-To: <540420223.9211626.1443023501886.JavaMail.open-xchange@ptangptang.store> References: <540420223.9211626.1443023501886.JavaMail.open-xchange@ptangptang.store> Message-ID: Hi Christian, Christian Sell writes: > after having successfully introduced my own custom container class by > implementing the appropriate value_trais template, I would now like to > also use this container in relationships (i.e. the container holds > shared_ptrs to a mapped class). The containers and relationships features are orthogonal, you should be able to use a container to store pointers to objects without doing anything special. > However, I am getting the meanwhile well-known error > > error: unable to map C++ type '::FlexisBase::SharedPtrVectorProperty< > ::flexis_data::Recording >' used in data member 'recordings' to a SQLite > database type Well, this looks more like a specialized container that implicitly stores its elements as shared_ptr's. But I think you should still be able to use it with ODB. Just make sure that value_type in the container_traits specialization is shared_ptr, not just T. Boris From boris at codesynthesis.com Wed Sep 23 12:20:54 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 23 12:20:56 2015 Subject: [odb-users] Lazy Relationships? In-Reply-To: <1890784003.8968373.1442935938142.JavaMail.open-xchange@ptangptang.store> References: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> <972643647.8750693.1442850509343.JavaMail.open-xchange@ptangptang.store> <1890784003.8968373.1442935938142.JavaMail.open-xchange@ptangptang.store> Message-ID: Hi Christian, Christian Sell writes: > yes, and in fact, I mentioned sections as the only way I had found to achieve > "full lazyness". However, this is not feasible because, as I said, I am mapping > classes that I cannot modify. Therefore my question was if I could achieve the > same with custom relationship (container) and accompanying container_traits ODB needs a place to store the state of the section somewhere (is it loaded? etc). What you could try to do is hide the section data member inside the container. Here is an outline: #include template struct sectioned_vector { odb::section s; }; #pragma db object struct object { #pragma db id int id; #pragma db member(s) virtual(odb::section) load(lazy) access(v.s) #pragma db section(s) sectioned_vector v; }; Kind of cool, actually. Boris From christian at gsvitec.com Wed Sep 23 12:22:59 2015 From: christian at gsvitec.com (Christian Sell) Date: Wed Sep 23 12:23:02 2015 Subject: [odb-users] custom relationship containers? In-Reply-To: References: <540420223.9211626.1443023501886.JavaMail.open-xchange@ptangptang.store> Message-ID: <54375196.9217765.1443025379954.JavaMail.open-xchange@ptangptang.store> > Well, this looks more like a specialized container that implicitly > stores its elements as shared_ptr's. But I think you should still > be able to use it with ODB. Just make sure that value_type in the > container_traits specialization is shared_ptr, not just T. correct, that's what it is. However, I now realize that SharedPtrVectorProperty is a class (should have been an alias) for which I have no container_traits. I have now switched to VectorProperty> where VectorProperty is known via container_traits, and Recording is mapped. As a result, I get a load of compile errors from ODB generated code, starting with error: 'index_type' in 'odb::access::object_traits_impl::recordings_traits::container_traits_type {aka class odb::access::container_traits > >}' does not name a type typedef container_traits_type::index_type index_type; ^ error: 'value_type' in 'odb::access::object_traits_impl::recordings_traits::container_traits_type {aka class odb::access::container_traits > >}' does not name a type typedef container_traits_type::value_type value_type; any hints? Christian From christian at gsvitec.com Wed Sep 23 12:26:37 2015 From: christian at gsvitec.com (Christian Sell) Date: Wed Sep 23 12:26:40 2015 Subject: [odb-users] Lazy Relationships? In-Reply-To: References: <696336520.8341178.1442745108397.JavaMail.open-xchange@patina.store> <972643647.8750693.1442850509343.JavaMail.open-xchange@ptangptang.store> <1890784003.8968373.1442935938142.JavaMail.open-xchange@ptangptang.store> Message-ID: <1884972911.9218519.1443025597553.JavaMail.open-xchange@ptangptang.store> > Kind of cool, actually. cool, indeed! I'll give it a try asap Christian From boris at codesynthesis.com Wed Sep 23 12:33:08 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 23 12:33:10 2015 Subject: [odb-users] custom relationship containers? In-Reply-To: <54375196.9217765.1443025379954.JavaMail.open-xchange@ptangptang.store> References: <540420223.9211626.1443023501886.JavaMail.open-xchange@ptangptang.store> <54375196.9217765.1443025379954.JavaMail.open-xchange@ptangptang.store> Message-ID: Hi Christian, Christian Sell writes: > typedef container_traits_type::index_type index_type; Looks like your container_traits specialization does not define types that it should. Check libodb/odb/std-vector-traits.hxx for an example. Also make sure that the header that defines tit is actually included into the generated header files (--hxx-prologue). Boris From finjulhich at gmail.com Thu Sep 24 06:45:32 2015 From: finjulhich at gmail.com (MM) Date: Thu Sep 24 06:45:40 2015 Subject: [odb-users] aggregate or dis-aggregate a data member Message-ID: Hello, I have a need similar to this case from the manual: consider the need to aggregate or dis-aggregate a data member: #pragma db object class person { ... #pragma db transient std::pair name_; #pragma db member(first) virtual(std::string) access(name_.first) #pragma db member(last) virtual(std::string) access(name_.second) }; except that in my case, I have: class D { public: const std::string& get_type() const; const std::uint64_t& get_id() const; }; class C { public: const D* d() const; void d(const D&); private: const D* d_; }; const D* get_D( const std::string& type, std::uint64_t id ); so, I need the d member to map to 2 columns in the table, and the 2 columns in the table to map back to a single d object, obtained through the get_D() free function. I apologize for asking on the list, and I think the answer is quite straight forward, but I just can't see it :-( Currently I have: #pragma db object(C) abstract definition #pragma db member(C::d) transient #pragma db member(C::dtype) virtual(std::string)\ get(this.d()? this.d()->get_type(): std::string())\ set() #pragma db member(C::did) virtual(std::uint64_t)\ get(this.d()? this.d()->get_id(): std::uint64_t())\ set() For the setting part, I would need both columns to then do the get_D() call. Rds, MM From mne at qosmotec.com Thu Sep 24 07:12:43 2015 From: mne at qosmotec.com (Marcel Nehring) Date: Thu Sep 24 07:13:32 2015 Subject: AW: [odb-users] many-to-many with two FKs In-Reply-To: References: Message-ID: <46674fc64d224d5095c01d15f645e953@QEX.qosmotec.com> Hi Boris, sorry, I didn't test that. Because the example in section 6.2.3 of the ODB manual does not create two FKs (is this a bug in the documentation?) and because for my code the CREATE TABLE command also does not I thought that is not done by default. However, while trying to generate a small code example that reproduces my problem I discovered that ODB later uses an ALTER TABLE command to add the second FK. This is because of the order in which tables get created. So the resulting table structure does indeed use two FKs. Sorry for any inconvenience. Regards, Marcel -----Urspr?ngliche Nachricht----- Von: Boris Kolpackov [mailto:boris@codesynthesis.com] Gesendet: Donnerstag, 17. September 2015 16:57 An: Marcel Nehring Cc: odb-users@codesynthesis.com Betreff: Re: [odb-users] many-to-many with two FKs Hi Marcel, Marcel Nehring writes: > Instead of > > CREATE TABLE project ( > name VARCHAR (255) NOT NULL PRIMARY KEY); > > CREATE TABLE employee ( > id BIGINT UNSIGNED NOT NULL PRIMARY KEY); > > CREATE TABLE employee_projects ( > object_id BIGINT UNSIGNED NOT NULL, > value VARCHAR (255) NOT NULL REFERENCES project (name)); > > I would like > > [...] > > CREATE TABLE employee_projects ( > object_id BIGINT UNSIGNED NOT NULL REFERENCES employee (id), value > VARCHAR (255) NOT NULL REFERENCES project (name)); And that's pretty much what I get: $ cat test.hxx #include #pragma db object struct project { #pragma db id int id; }; #pragma db object struct employee { #pragma db id int id; std::vector projects; }; $ odb -d oracle -s test.hxx $ cat test.sql CREATE TABLE "project" ( "id" NUMBER(10) NOT NULL PRIMARY KEY); CREATE TABLE "employee" ( "id" NUMBER(10) NOT NULL PRIMARY KEY); CREATE TABLE "employee_projects" ( "object_id" NUMBER(10) NOT NULL, "index" NUMBER(20) NOT NULL, "value" NUMBER(10) NULL, CONSTRAINT "employee_projects_object_id_fk" FOREIGN KEY ("object_id") REFERENCES "employee" ("id") ON DELETE CASCADE, CONSTRAINT "employee_projects_value_fk" FOREIGN KEY ("value") REFERENCES "project" ("id") DEFERRABLE INITIALLY DEFERRED); Boris From christian at gsvitec.com Thu Sep 24 10:26:08 2015 From: christian at gsvitec.com (Christian Sell) Date: Thu Sep 24 10:26:10 2015 Subject: [odb-users] access cached instances of a certain type? Message-ID: <714566761.9410136.1443104768215.JavaMail.open-xchange@ptangptang.store> Hello, for reason of not breaking existing API I cannot hand out shared_ptrs to my (lightweight) mapped objects. I therefore need to determine the persistence state explicitly. Here's the sequence vector v = persistenceManager.getMyClasses(); //change objects in v, add new ones persistenceManager.saveMyClasses(v); in order to detect newly added objects, I would like to ask the object cache (rather than maintaining my own). I think would need a way to get all cached MyClass objects and check by id whether the passed-in objects match or not... I did not find such API on odb::session, so I thought I'd ask thanks, Christian From boris at codesynthesis.com Thu Sep 24 11:12:36 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 24 11:12:37 2015 Subject: [odb-users] many-to-many with two FKs In-Reply-To: <46674fc64d224d5095c01d15f645e953@QEX.qosmotec.com> References: <46674fc64d224d5095c01d15f645e953@QEX.qosmotec.com> Message-ID: Hi Marcel, Marcel Nehring writes: > Because the example in section 6.2.3 of the ODB manual does not > create two FKs (is this a bug in the documentation?) Yes, fixed. Thanks for pointing it out. Boris From picserez at gmail.com Thu Sep 24 08:29:12 2015 From: picserez at gmail.com (Erez Pics) Date: Thu Sep 24 11:14:56 2015 Subject: [odb-users] Query Result Problem Message-ID: Hi Boris, I am performing an aggregated count grouped query, somehow I get an extra first row with invalid data, the rest of the result is as expected. ////////////////////////////////////////////////////// // this is the expected result from SQLite ////////////////////////////////////////////////////// 0|2 1|3 2|1 ////////////////////////////////////////////////////// // this is the result I get from ODB ////////////////////////////////////////////////////// 0|1 // <<< this is the problem 0|2 1|3 2|1 We have seen the result of 0|1 in different combinations of data, even if the first row should be 0|1 we get it twice, not sure why it happens, maybe something is wrong with my syntax. I will be very happy to hear what you think. [all information to reproduce the problem is in the text attached] Thank you very very much, Erez. -------------- next part -------------- ////////////////////////////////////////////////////// // these are the actual SQL tables ////////////////////////////////////////////////////// CREATE TABLE person_data ( person_id INTEGER PRIMARY KEY NOT NULL, gender char(1) default 'U' ); CREATE TABLE person_set ( person_set_id INTEGER PRIMARY KEY AUTOINCREMENT, delete_flag tinyint UNSIGNED default '0', -- soft erase flag person_id INT NOT NULL, FOREIGN KEY(person_id) REFERENCES person_data(person_id) ON DELETE CASCADE ON UPDATE CASCADE ); CREATE TABLE person_lang_data ( person_lang_data_id INTEGER PRIMARY KEY AUTOINCREMENT, person_set_id INT NOT NULL, data_language TINYINT UNSIGNED NOT NULL default '0', first_name varchar(255) default '', last_name varchar(255) default '', FOREIGN KEY(person_set_id) REFERENCES person_set(person_set_id) ON DELETE CASCADE ON UPDATE CASCADE ); ////////////////////////////////////////////////////// // these are the ODB classes for the above tables ////////////////////////////////////////////////////// #pragma db object table("person_data") pointer(shared_ptr) session class CPersonData { public: protected: // default empty constructor for ODB CPersonData() { } #pragma db id column("person_id") type("INT") long m_person_id; #pragma db column("gender") type("char(1)") default("U") char m_gender; // this is the inversed relationship side of the one to many #pragma db value_not_null inverse(m_person_id) std::vector > m_vecPersonSet; }; #pragma db object table("person_set") pointer(shared_ptr) session class CPersonSet { public: protected: // default empty constructor for ODB CPersonSet(void) { } friend class odb::access; #pragma db id auto column("person_set_id") type("INT") long m_person_set_id; #pragma db column("delete_flag") type("TINYINT UNSIGNED") default(0) short m_delete_flag; // this is the many side of the relationship with CPersonData #pragma db not_null weak_ptr m_person_id; // this is the inversed relationship side of the one to many #pragma db value_not_null inverse(m_person_set_id) std::vector > m_vecLangData; }; #pragma db object table("person_lang_data") pointer(shared_ptr) session class CPersonLangData { public: protected: // default empty constructor for ODB CPersonLangData() { } friend class odb::access; #pragma db id auto column("person_lang_data_id") type("INT") long m_person_lang_data_id; #pragma db not_null weak_ptr m_person_set_id; #pragma db column("data_language") type("TINYINT UNSIGNED") default(0) int m_data_language; #pragma db column("first_name") type("VARCHAR(255)") default("") string m_first_name; #pragma db column("last_name") type("VARCHAR(255)") default("") string m_last_name; }; ////////////////////////////////////////////////////// // this is the data in the tables ////////////////////////////////////////////////////// INSERT INTO "person_data" VALUES(1,'M'); INSERT INTO "person_data" VALUES(2,'F'); INSERT INTO "person_data" VALUES(3,'M'); INSERT INTO "person_data" VALUES(4,'F'); INSERT INTO "person_set" VALUES(1,0,1); INSERT INTO "person_set" VALUES(2,0,2); INSERT INTO "person_set" VALUES(3,0,3); INSERT INTO "person_set" VALUES(4,0,4); INSERT INTO "person_set" VALUES(5,0,1); INSERT INTO "person_lang_data" VALUES(1,1,0,'eee',''); INSERT INTO "person_lang_data" VALUES(2,1,1,'eee',''); INSERT INTO "person_lang_data" VALUES(3,3,1,'eee',''); INSERT INTO "person_lang_data" VALUES(4,4,1,'eee',''); INSERT INTO "person_lang_data" VALUES(5,1,2,'eee',''); INSERT INTO "person_lang_data" VALUES(6,5,0,'eee',''); INSERT INTO "person_lang_data" VALUES(7,4,0,'eee',''); ////////////////////////////////////////////////////// // this is the query I am executing ////////////////////////////////////////////////////// SELECT person_lang_data.data_language,COUNT(DISTINCT person_set.person_id) FROM person_lang_data JOIN person_set ON person_lang_data.person_set_id = person_set.person_set_id GROUP BY data_language; ////////////////////////////////////////////////////// // this is the ODB syntax for the query above ////////////////////////////////////////////////////// #pragma db view object(CPersonSet) \ object(CPersonLangData: CPersonSet::m_person_set_id == CPersonLangData::m_person_set_id) \ query((?) + "GROUP BY" + CPersonLangData::m_data_language) struct view_persons_per_langauges { #pragma db column(CPersonLangData::m_data_language) int data_language; #pragma db column("count (distinct " + CPersonSet::m_person_id + ")") long count_persons; }; ////////////////////////////////////////////////////// // this is the expected result from SQLite ////////////////////////////////////////////////////// 0|2 1|3 2|1 ////////////////////////////////////////////////////// // this is the result I get from ODB ////////////////////////////////////////////////////// 0|1 // <<< this is the problem 0|2 1|3 2|1 From boris at codesynthesis.com Thu Sep 24 11:26:26 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 24 11:26:26 2015 Subject: [odb-users] update object without caching the query result In-Reply-To: References: Message-ID: Hi Tim, Tim Tao writes: > Is there any way we can update an object without caching the > query result ? > > I query the database and load() each result, it seems like this > will cache the result in the application memory which is unnecessary. There is a "query result", i.e., what's returned by the call to query(), which, for some databases, may involve caching of the raw data. When you call load() (presumably on result::iterator), you load the "object". When you say "will cache the result", which one do you refer to? Also, it is always a good idea to show the code fragment. Boris From boris at codesynthesis.com Thu Sep 24 11:36:34 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 24 11:36:35 2015 Subject: [odb-users] aggregate or dis-aggregate a data member In-Reply-To: References: Message-ID: Hi, MM writes: > class D > { public: > const std::string& get_type() const; > const std::uint64_t& get_id() const; > }; class C { > public: > const D* d() const; > void d(const D&); > private: > const D* d_; > }; > const D* get_D( const std::string& type, std::uint64_t id ); > > so, I need the d member to map to 2 columns in the table, and the 2 columns > in the table to map back to a single d object, obtained through the get_D() > free function. > > Currently I have: > > #pragma db object(C) abstract definition > #pragma db member(C::d) transient > #pragma db member(C::dtype) virtual(std::string)\ > get(this.d()? this.d()->get_type(): std::string())\ > set() > #pragma db member(C::did) virtual(std::uint64_t)\ > get(this.d()? this.d()->get_id(): std::uint64_t())\ > set() > > For the setting part, I would need both columns to then do the > get_D() call. Right, and that's the reason why your approach will not work: ODB will supply you the columns separately but you need them both at the same time. The way to handle this is with a composite value. Something along these lines: #pragma db value struct D_Image { #pragma db column("dtype") std::string type; #pragma db column("did") std::uint64_t id; }; #pragma db member(C::d) virtual(D_Image) column("") \ get(D_Image{this.d ()->get_type (), this.d ()->get_id ()}) \ set(this.d (get_D ((?).type, (?).id)) Boris From Tim.Tao at akunacapital.com Thu Sep 24 11:35:38 2015 From: Tim.Tao at akunacapital.com (Tim Tao) Date: Thu Sep 24 11:37:29 2015 Subject: [odb-users] update object without caching the query result In-Reply-To: References: , Message-ID: Hi Boris, Thanks for your reply. The following is the code fragment: using query = odb::query; using result = odb::result; result r(db->query(some conditions here)); for(result::iterator::iterator i (r.begin()); i != r.end(); ++i){ shared_ptr ptr = i.load(); ptr->field = new_value; db->update(ptr); } So in this way I have to cache each result which seems unnecessary to me since I don't need them in the future once I finished updating I wonder if there is any way I can update the results without loading them to cache ? By the way, I am using postgres Thanks, Tim ________________________________________ From: Boris Kolpackov Sent: Thursday, September 24, 2015 10:26 AM To: Tim Tao Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] update object without caching the query result Hi Tim, Tim Tao writes: > Is there any way we can update an object without caching the > query result ? > > I query the database and load() each result, it seems like this > will cache the result in the application memory which is unnecessary. There is a "query result", i.e., what's returned by the call to query(), which, for some databases, may involve caching of the raw data. When you call load() (presumably on result::iterator), you load the "object". When you say "will cache the result", which one do you refer to? Also, it is always a good idea to show the code fragment. Boris ________________________________ [http://www.akunacapital.com/images/akuna.png] Tim Tao | Junior Developer | www.akunacapital.com p: | m: | f: | tim.tao@akunacapital.com Please consider the environment, before printing this email. This electronic message contains information from Akuna Capital LLC that may be confidential, legally privileged or otherwise protected from disclosure. This information is intended for the use of the addressee only and is not offered as investment advice to be relied upon for personal or professional use. Additionally, all electronic messages are recorded and stored in compliance pursuant to applicable SEC rules. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, printing or any other use of, or any action in reliance on, the contents of this electronic message is strictly prohibited. If you have received this communication in error, please notify us by telephone at (312)994-4640 and destroy the original message. From boris at codesynthesis.com Thu Sep 24 11:43:44 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 24 11:43:45 2015 Subject: [odb-users] Query Result Problem In-Reply-To: References: Message-ID: Hi Erez, Erez Pics writes: > SELECT person_lang_data.data_language,COUNT(DISTINCT person_set.person_id) > FROM person_lang_data JOIN person_set ON person_lang_data.person_set_id = > person_set.person_set_id GROUP BY data_language; > > #pragma db view object(CPersonSet) \ > object(CPersonLangData: CPersonSet::m_person_set_id == CPersonLangData::m_person_set_id) \ > query((?) + "GROUP BY" + CPersonLangData::m_data_language) One thing I noticed is that in the SELECT statement you JOIN person_set on person_lang_data while in the view, you join CPersonLangData on CPersonSet. Could this be the reason for the different results? Also, I suggest that you enable statement tracing and check the actual statement that is being executed for this view. Boris From boris at codesynthesis.com Thu Sep 24 11:50:48 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 24 11:50:49 2015 Subject: [odb-users] access cached instances of a certain type? In-Reply-To: <714566761.9410136.1443104768215.JavaMail.open-xchange@ptangptang.store> References: <714566761.9410136.1443104768215.JavaMail.open-xchange@ptangptang.store> Message-ID: Hi Christian, Christian Sell writes: > I think would need a way to get all cached MyClass objects and check > by id whether the passed-in objects match or not... I did not find > such API on odb::session, so I thought I'd ask Did you see this? namespace odb { class session { // Low-level object cache access (iteration, etc). // public: typedef std::map, details::type_info_comparator> type_map; typedef std::map database_map; database_map& map () {return db_map_;} const database_map& map () const {return db_map_;} }; } This is the start of the rabbit hole and you can go as deep as you would like. Also note that you can provide a custom session implementation (see odb-tests/common/session/custom/). Boris From boris at codesynthesis.com Thu Sep 24 11:58:01 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Sep 24 11:58:01 2015 Subject: [odb-users] update object without caching the query result In-Reply-To: References: Message-ID: Hi Tim, Tim Tao writes: > using query = odb::query; > using result = odb::result; > > result r(db->query(some conditions here)); > > for(result::iterator::iterator i (r.begin()); i != r.end(); ++i){ > shared_ptr ptr = i.load(); > ptr->field = new_value; > db->update(ptr); > } > > So in this way I have to cache each result which seems unnecessary > to me since I don't need them in the future once I finished updating Assuming A is not a session-enabled object and you don't have active odb::session somewhere up the stack, nothing is cached here. On each iteration, one object is loaded, updated, and freed. If you do have a session and A is session-enabled but you don't want to cache just this set of objects, then there are a couple of ways you can do it. First is to load the data into a stack- allocated object: for(result::iterator::iterator i (r.begin()); i != r.end(); ++i){ A a; i.load(a); a.field = new_value; db->update(a); } The other way is to temporarily "suspend" the session: odb::session& s (odb::session::current ()); odb::session::reset_current (); // "Suspend". for(result::iterator::iterator i (r.begin()); i != r.end(); ++i){ ... } odb::session::current (s); // "Resume". Boris From picserez at gmail.com Thu Sep 24 12:13:02 2015 From: picserez at gmail.com (Erez Pics) Date: Fri Sep 25 01:24:39 2015 Subject: [odb-users] Query Result Problem In-Reply-To: References: Message-ID: Hi Boris, Wow, you are right :-) Thank you very very much, as always you have great advice for any question. I am unsure how to make this an inner join instead of the default left join, the ODB compiler does not approve the syntax I use, can you please advice how to make the view to be an inner join ? Thank you, Erez. On Thu, Sep 24, 2015 at 6:43 PM, Boris Kolpackov wrote: > Hi Erez, > > Erez Pics writes: > >> SELECT person_lang_data.data_language,COUNT(DISTINCT person_set.person_id) >> FROM person_lang_data JOIN person_set ON person_lang_data.person_set_id = >> person_set.person_set_id GROUP BY data_language; >> >> #pragma db view object(CPersonSet) \ >> object(CPersonLangData: CPersonSet::m_person_set_id == CPersonLangData::m_person_set_id) \ >> query((?) + "GROUP BY" + CPersonLangData::m_data_language) > > One thing I noticed is that in the SELECT statement you JOIN person_set > on person_lang_data while in the view, you join CPersonLangData on > CPersonSet. Could this be the reason for the different results? > > Also, I suggest that you enable statement tracing and check the actual > statement that is being executed for this view. > > Boris From finjulhich at gmail.com Fri Sep 25 06:11:58 2015 From: finjulhich at gmail.com (MM) Date: Fri Sep 25 06:12:06 2015 Subject: [odb-users] aggregate or dis-aggregate a data member In-Reply-To: References: Message-ID: On 24 September 2015 at 16:36, Boris Kolpackov wrote: > Hi, > > MM writes: > > > class D > > { public: > > const std::string& get_type() const; > > const std::uint64_t& get_id() const; > > }; class C { > > public: > > const D* d() const; > > void d(const D&); > > private: > > const D* d_; > > }; > > const D* get_D( const std::string& type, std::uint64_t id ); > > > > so, I need the d member to map to 2 columns in the table, and the 2 > columns > > in the table to map back to a single d object, obtained through the > get_D() > > free function. > > > > Currently I have: > > > > #pragma db object(C) abstract definition > > #pragma db member(C::d) transient > > #pragma db member(C::dtype) virtual(std::string)\ > > get(this.d()? this.d()->get_type(): std::string())\ > > set() > > #pragma db member(C::did) virtual(std::uint64_t)\ > > get(this.d()? this.d()->get_id(): std::uint64_t())\ > > set() > > > > For the setting part, I would need both columns to then do the > > get_D() call. > > Right, and that's the reason why your approach will not work: ODB > will supply you the columns separately but you need them both at > the same time. > > The way to handle this is with a composite value. Something along > these lines: > > #pragma db value > struct D_Image > { > #pragma db column("dtype") > std::string type; > > #pragma db column("did") > std::uint64_t id; > }; > > #pragma db member(C::d) virtual(D_Image) column("") \ > get(D_Image{this.d ()->get_type (), this.d ()->get_id ()}) \ > set(this.d (get_D ((?).type, (?).id)) > > Boris > Thanks, the composite value solution does it. Rds, From finjulhich at gmail.com Fri Sep 25 06:16:18 2015 From: finjulhich at gmail.com (MM) Date: Fri Sep 25 06:16:25 2015 Subject: [odb-users] persist non-member containers Message-ID: I have a global single process-wide std::unordered_map. >From the manual, i see the container needs to be a member of a persisted class for odb to handle it. Also, that the key cannot be an object pointer. The D instances are stored in a global boost::ptr_xxx container. There is a 1-to-1 equivalence between a D instance and a std::pair. Given a D I get a unique pair, given the pair I can get a D uniquely. What sort of work around is possible if I cannot change my global container? Rds, From christian at gsvitec.com Fri Sep 25 06:42:12 2015 From: christian at gsvitec.com (Christian Sell) Date: Fri Sep 25 06:42:16 2015 Subject: [odb-users] access cached instances of a certain type? In-Reply-To: References: <714566761.9410136.1443104768215.JavaMail.open-xchange@ptangptang.store> Message-ID: <192648142.9544550.1443177732703.JavaMail.open-xchange@ptangptang.store> > > I think would need a way to get all cached MyClass objects and check > > by id whether the passed-in objects match or not... I did not find > > such API on odb::session, so I thought I'd ask > > Did you see this? I surely saw it when I inspected the session API, but was appalled by the low-level nature. After having fumbled for an hour or two, I can confirm that initial impression ;). At least I know that once I am done nobody will question my indispensability.. My currently remaining problem is: how do I obtain a key from an object? thanks, Christian From christian at gsvitec.com Fri Sep 25 06:58:30 2015 From: christian at gsvitec.com (Christian Sell) Date: Fri Sep 25 06:58:33 2015 Subject: [odb-users] access cached instances of a certain type? In-Reply-To: <192648142.9544550.1443177732703.JavaMail.open-xchange@ptangptang.store> References: <714566761.9410136.1443104768215.JavaMail.open-xchange@ptangptang.store> <192648142.9544550.1443177732703.JavaMail.open-xchange@ptangptang.store> Message-ID: <426002012.9548340.1443178710852.JavaMail.open-xchange@ptangptang.store> > My currently remaining problem is: how do I obtain a key from an object? ok, got it. It's in the generated code, obviously: ::odb::access::object_traits::id(myobj) thanks, Chris From boris at codesynthesis.com Fri Sep 25 09:58:36 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Sep 25 09:58:35 2015 Subject: [odb-users] Query Result Problem In-Reply-To: References: Message-ID: Hi Erez, Erez Pics writes: > I am unsure how to make this an inner join instead of the default left > join, the ODB compiler does not approve the syntax I use, can you > please advice how to make the view to be an inner join ? Just search the manual. Is it really easier to write an email than open the manual, hit Ctrl-F, and type "inner join"? There is even an example: #pragma db view object(employer) \ object(country inner: employer::name == country::name) struct employer_named_country { shared_ptr e; shared_ptr c; }; Boris From boris at codesynthesis.com Fri Sep 25 10:04:19 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Sep 25 10:04:19 2015 Subject: [odb-users] persist non-member containers In-Reply-To: References: Message-ID: Hi, MM writes: > What sort of work around is possible if I cannot change my global > container? The same workaround that you've been using for a while now: virtual members. With virtual members, the actual data can be anywhere as long as you can provide suitable accessors/modifiers. So if you create an object with a virtual data member that always returns your global container, and you only persist a single instance of this object, then that should do the trick. Boris From christian at gsvitec.com Fri Sep 25 14:05:28 2015 From: christian at gsvitec.com (Christian Sell) Date: Fri Sep 25 14:05:31 2015 Subject: [odb-users] query for composite value? Message-ID: <763869791.9271410.1443204328825.JavaMail.open-xchange@omgreatgod.store> Hello, I have a mapped class with a composite key, like: struct OverlayGroup { struct Key { unsigned sourceId; string name; Key(unsigned sourceId=0, string name="") : sourceId(sourceId), name(name) {} bool operator<(const Key &other) const { return sourceId == other.sourceId ? name < other.name : sourceId < other.sourceId; } } key; string description; } and I would like to query for the name (which is embedd inside the Key value class). How? thanks, Chris From christian at gsvitec.com Fri Sep 25 14:13:22 2015 From: christian at gsvitec.com (Christian Sell) Date: Fri Sep 25 14:13:24 2015 Subject: [odb-users] query for composite value? In-Reply-To: <763869791.9271410.1443204328825.JavaMail.open-xchange@omgreatgod.store> References: <763869791.9271410.1443204328825.JavaMail.open-xchange@omgreatgod.store> Message-ID: <1753914102.9272241.1443204802223.JavaMail.open-xchange@omgreatgod.store> never mind. A look at the "composite" example shows that the syntax is query_t::key.name == name > Christian Sell hat am 25. September 2015 um 20:05 > geschrieben: > > > Hello, > > I have a mapped class with a composite key, like: > > > struct OverlayGroup > { > struct Key { > unsigned sourceId; > string name; > > Key(unsigned sourceId=0, string name="") : sourceId(sourceId), name(name) {} > > bool operator<(const Key &other) const { > return sourceId == other.sourceId ? name < other.name : sourceId < > other.sourceId; > } > } key; > > string description; > } > > and I would like to query for the name (which is embedd inside the Key value > class). How? > > thanks, > Chris > Christian Sell GS Vitec GmbH Im Ziegelhaus 6-8 D-63571 Gelnhausen mail: christian@gsvitec.com mobil: +49 (0) 173 5384289 Tel: +49 (0) 6051 601.26-90 Fax: +49 (0) 6051 601.26-91 From christian at gsvitec.com Mon Sep 28 05:23:19 2015 From: christian at gsvitec.com (Christian Sell) Date: Mon Sep 28 05:23:23 2015 Subject: [odb-users] odb persistence in a library Message-ID: <1793361386.9709959.1443432199513.JavaMail.open-xchange@patina.store> Hello, we would like to implement persistence functionality as a shared library module which would hold mappings for the common classes and also provide an extension interface through which new mappings can be introduced. The idea is that these application-specific classes would extend the schema of the library module, such that the application classes get stored in the same database. My question is whether this is considered a supported use case, or if there are issues we may be running into. Specifically, I am uncertain about the implications for schema creation and schema migration (can 2 schemas that reside in the same database be migrated independently) Christian From picserez at gmail.com Fri Sep 25 10:27:54 2015 From: picserez at gmail.com (Erez Pics) Date: Mon Sep 28 11:52:50 2015 Subject: [odb-users] Query Result Problem In-Reply-To: References: Message-ID: Hi Boris, Thank you for your answer, I did research the manual, it seems that to perform an inner join I need to add the "inner" right after the second table and before the ":" But I got an error : 'error: ')' expected at the end of db pragma object', maybe I am missing something, The only change I did was adding the inner directive, this is what I mean: ////////////////////////////////////////////////////// // this is the original ODB syntax [works by ODB compiler] ////////////////////////////////////////////////////// #pragma db view object(CPersonSet) \ object(CPersonLangData: CPersonSet::m_person_set_id == CPersonLangData::m_person_set_id) \ query((?) + "GROUP BY" + CPersonLangData::m_data_language) struct view_persons_per_langauges { #pragma db column(CPersonLangData::m_data_language) int data_language; #pragma db column("count (distinct " + CPersonSet::m_person_id + ")") long count_persons; }; ////////////////////////////////////////////////////// // this is the original ODB syntax [with inner directive, ODB compiler gives an error] ////////////////////////////////////////////////////// #pragma db view object(CPersonSet) \ object(CPersonLangData inner: CPersonSet::m_person_set_id == CPersonLangData::m_person_set_id) \ query((?) + "GROUP BY" + CPersonLangData::m_data_language) struct view_persons_per_langauges { #pragma db column(CPersonLangData::m_data_language) int data_language; #pragma db column("count (distinct " + CPersonSet::m_person_id + ")") long count_persons; }; Thank you, Erez. On Fri, Sep 25, 2015 at 4:58 PM, Boris Kolpackov wrote: > Hi Erez, > > Erez Pics writes: > >> I am unsure how to make this an inner join instead of the default left >> join, the ODB compiler does not approve the syntax I use, can you >> please advice how to make the view to be an inner join ? > > Just search the manual. Is it really easier to write an email than > open the manual, hit Ctrl-F, and type "inner join"? There is even > an example: > > #pragma db view object(employer) \ > object(country inner: employer::name == country::name) > struct employer_named_country > { > shared_ptr e; > shared_ptr c; > }; > > Boris From boris at codesynthesis.com Mon Sep 28 11:55:15 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 28 11:55:11 2015 Subject: [odb-users] Query Result Problem In-Reply-To: References: Message-ID: Hi Erez, Erez Pics writes: > But I got an error : 'error: ')' expected at the end of db pragma > object', maybe I am missing something, JOIN type support is only available in ODB 2.4.0. Which version are you using? Boris From boris at codesynthesis.com Mon Sep 28 12:35:03 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Sep 28 12:35:00 2015 Subject: [odb-users] Set Query timeout In-Reply-To: References: Message-ID: Hi Fredrik, Fredrik Strand writes: > I'm currently using a query object to call a stored procedure in SQL server. > > So this approach is only usable with prepared queries? Yes, that's correct. Note, however, that a non-prepared query is a special case of the more general prepared query mechanism (i.e, it behaves as if the query was prepared, executed, and then released). So anything you can do with a non-prepared query you can do with a prepared one. > Would be really nice to have a generic way to set query timeouts > since it's probably a must have in enterprise applications. I agree, if there was (1) a natural place to specify it in the ODB API and (2) uniform support for it across databases. Specifically, regarding (1), for a simple (i.e., non-prepared) query there is no notion of a (user-visible) statement. There is just a query condition and a call to execute the query. Specifying the timeout as part of the query condition doesn't feel right. So that leaves us to passing the timeout to the query() call. Which brings us to (2): what do we do for databases that don't support timeouts (like SQLite). Also, timeout is just one "tunable" of a query. What if tomorrow someone else wants something different? Do we add another overload of query()? On the other hand, with a prepared query, you get the notion of a statement which you can resolve all the way down to the underlying database handle and tune it in any way you want. And if you want the simple query()-like interface, it is pretty easy to wrap into a function, for example: #include #include #include #include template odb::result query_with_timeout (const odb::query& q, odb::mssql::database& db, unsigned short timeout) { using query = odb::query; using prep_query = odb::prepared_query; prep_query pq (db.prepare_query ("temp-query", q)); // Set timeout. // // ... as in the previous email. return pq.execute (); } Then, in client code, instead of: result r = db.query (query::age > 18); You do: result r = query_with_timeout (query::age > 18, db, 10); Boris From finjulhich at gmail.com Mon Sep 28 14:10:54 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 28 14:11:10 2015 Subject: [odb-users] libcutl repo not exported Message-ID: fatal: remote error: access denied or repository not exported: /odb/libcutl/libcutl.git I am trying to build the odb compiler from git rather than from distrib (tar file) by reading the INSTALL-GIT. libcutl is required (version 1.9.0) but I have only 1.8.3 on my fedora. Rds, From finjulhich at gmail.com Mon Sep 28 14:57:54 2015 From: finjulhich at gmail.com (MM) Date: Mon Sep 28 14:58:01 2015 Subject: [odb-users] Re: libcutl repo not exported In-Reply-To: References: Message-ID: On 28 September 2015 at 19:10, MM wrote: > fatal: remote error: access denied or repository not exported: > /odb/libcutl/libcutl.git > > I am trying to build the odb compiler from git rather than from distrib > (tar file) by reading the INSTALL-GIT. libcutl is required (version 1.9.0) > but I have only 1.8.3 on my fedora. > > Rds, > I managed to install libcutl 1.9 through fedora copr. I have the 'build' and 'cli' installed in /usr/local/ and all the other deps specififed in INSTALL and INSTALL-GIT. I now follow INSTALL-GIT and just do a make inside the odb directory. It seems this file options.hxx is not generated, even odb/odb/odb.cxx:38:27: fatal error: odb/options.hxx: No such file or directory so I just ran cli options.cli myself, but then that fails: cannot make target 'cli' Rds, From picserez at gmail.com Mon Sep 28 14:28:30 2015 From: picserez at gmail.com (Erez Pics) Date: Tue Sep 29 10:16:17 2015 Subject: [odb-users] Query Result Problem In-Reply-To: References: Message-ID: Hi Boris, We are using ODB 2.3.0. 1) Does upgrading to ODB 2.4.0 is the only fix to get inner join ? 2) Assuming we will upgrade, do we need to pay special attention or be ready to handle specific issues with our existing code that use ODB 2.3.0 ? Thank you, Erez. On Mon, Sep 28, 2015 at 6:55 PM, Boris Kolpackov wrote: > Hi Erez, > > Erez Pics writes: > >> But I got an error : 'error: ')' expected at the end of db pragma >> object', maybe I am missing something, > > JOIN type support is only available in ODB 2.4.0. Which version are > you using? > > Boris From boris at codesynthesis.com Tue Sep 29 10:38:59 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 29 10:38:57 2015 Subject: [odb-users] odb persistence in a library In-Reply-To: <1793361386.9709959.1443432199513.JavaMail.open-xchange@patina.store> References: <1793361386.9709959.1443432199513.JavaMail.open-xchange@patina.store> Message-ID: Hi Christian, Christian Sell writes: > My question is whether this is considered a supported use case, or if > there are issues we may be running into. Specifically, I am uncertain > about the implications for schema creation and schema migration (can > 2 schemas that reside in the same database be migrated independently) Yes, if you give them different names (--schema-name), they will end up completely independently versioned. If you take closer look, you will see that the schema creation/migration API has the optional scheme name argument throughout. The only restriction is that if you want to use different versions for different schemas, then the corresponding object models should be independent (i.e., you won't be able to #include headers that have '#pragma db model version' for one object model into another). In fact, Section 13.1 has this to say on the subject: "It is also possible to have multiple object models within the same application that have different versions. Such models must be independent, that is, no headers from one model shall include a header from another. You will also need to assign different schema names to each model with the --schema-name ODB compiler option." Boris From boris at codesynthesis.com Tue Sep 29 10:50:29 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Sep 29 10:50:26 2015 Subject: [odb-users] Re: libcutl repo not exported In-Reply-To: References: Message-ID: Hi, MM writes: > fatal: remote error: access denied or repository not exported: > /odb/libcutl/libcutl.git I wonder when will you learn to tell what you have actually done (i.e. the *exact* commands that you ran) that triggered the error? In fact, enough is enough. From now on, I will be ignoring your questions that don't include this information. In any case, both: git clone git://scm.codesynthesis.com/libcutl/libcutl.git git clone http://scm.codesynthesis.com/libcutl/libcutl.git As suggested on: http://scm.codesynthesis.com/?p=libcutl/libcutl.git;a=summary Work for me. > I now follow INSTALL-GIT and just do a make inside the odb directory. It > seems this file options.hxx is not generated, even > > odb/odb/odb.cxx:38:27: fatal error: odb/options.hxx: No such file or > directory When you ran make for the first time, you should have been asked a bunch of questions, including whether you would like to use the development build of cli (you should answer 'no') and where cli is (you should answer '/usr/local/bin/cli'). After that, the build process should generate options.?xx without problems. If this still doesn't work, provide *complete* and *precise* log of what you have done and the output you have observed. Boris From christian at gsvitec.com Tue Sep 29 11:01:18 2015 From: christian at gsvitec.com (Christian Sell) Date: Tue Sep 29 11:01:21 2015 Subject: [odb-users] odb persistence in a library In-Reply-To: References: <1793361386.9709959.1443432199513.JavaMail.open-xchange@patina.store> Message-ID: <1050331374.178577.1443538878594.JavaMail.open-xchange@ptangptang.store> > "It is also possible to have multiple object models within the same > application that have different versions. Such models must be independent, > that is, no headers from one model shall include a header from another. > You will also need to assign different schema names to each model with > the --schema-name ODB compiler option." ah, thanks, thats what I needed to hear (rsp. read). I always had the plan to read the manual completely, but haven't gotten that far yet. Right now I am instead reading the qur'an in order to be prepared for the chaos that's impending in our country ;) Christian From finjulhich at gmail.com Tue Sep 29 16:13:54 2015 From: finjulhich at gmail.com (MM) Date: Tue Sep 29 16:14:01 2015 Subject: [odb-users] persist non-member containers In-Reply-To: References: Message-ID: On 25 September 2015 at 15:04, Boris Kolpackov wrote: > Hi, > > MM writes: > > > What sort of work around is possible if I cannot change my global > > container? > > The same workaround that you've been using for a while now: virtual > members. With virtual members, the actual data can be anywhere as > long as you can provide suitable accessors/modifiers. So if you > create an object with a virtual data member that always returns > your global container, and you only persist a single instance of > this object, then that should do the trick. > > Boris > Thank you. I have implemented successfully this approach for 1 global container. Another global container is bigger in number of elements as it contains history as well. As the query statement I use loads the single instance of the wrapper object, which then populates the global container while loading. Is it possible in this case to use a view to filter on what is loaded for the global container itself? Rds, From boris at codesynthesis.com Wed Sep 30 10:21:16 2015 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Sep 30 10:21:11 2015 Subject: [odb-users] persist non-member containers In-Reply-To: References: Message-ID: Hi, MM writes: > Is it possible in this case to use a view to filter on what is loaded for > the global container itself? Not currently, though there are plans to add support for JOIN'ing containers onto views. In the meantime, perhaps you could make the elements of the container into full-fledged objects. Then you could control what gets loaded with a simple query. Boris From christian at gsvitec.com Wed Sep 30 12:44:37 2015 From: christian at gsvitec.com (Christian Sell) Date: Wed Sep 30 12:44:40 2015 Subject: [odb-users] odb persistence in a library In-Reply-To: References: <1793361386.9709959.1443432199513.JavaMail.open-xchange@patina.store> Message-ID: <359492180.430846.1443631477487.JavaMail.open-xchange@ptangptang.store> Hello, still working on the "persistence in library" subject. Here's a problem I encountered during my first test run: we have an abstract, polymorphic superclass that is mapped inside the library. Now we want to allow the user of the library to extend the object model by adding new subclasses, which should also be made persistent AND be accessible through the same polymorphic relationship. Graphically: Library Class1 polymorphic id name Class2 extends Class1 Class3 id vector poly_container LibraryUser Class4 extends Class1 this immediately fails during odb compilation of the LibraryUser files, because odb complains that Class4 does not designate an object id. The reason is obvious - odb doesn't know that Class1 has been mapped polymorphically elsewhere. Can this situation be solved somehow? thanks, Christian