From rene at catatonic.dk Fri Nov 2 08:36:12 2012 From: rene at catatonic.dk (Rene Jensen) Date: Fri Nov 2 08:31:32 2012 Subject: [odb-users] How to make a "lazy" QList? In-Reply-To: References: Message-ID: > On a more conceptual level, what seems to be the ultimate goal is >> to have the ability to segment data members into lazy-loadable >> sections. Supporting lazy loading for simple members will require >> a separate statement for each member, if we do it member-by-member. >> This is a significant overhead. So grouping members into as few >> sections as possible is a good idea. Maybe something along these >> lines: >> >> class Author >> { >> >> odb::lazy_section publications; >> >> #pragma db lazy(publications) >> QList > authorsBooks; >> >> #pragma db lazy(publications) >> vector > authorsArticles; >> >> }; >> >> if (!A->publications.loaded ()) >> A->publications.load (); // Loads authorsBooks and authorsArticles. >> >> Just some thoughts. >> >> Boris >> > > > This is an utterly brilliant idea in every conceivable way that I can > immediately think of. > Cheers > > > Hi again Boris. Have you given any further thoughts to this? Automatic loading and saving of lists of objects is increasingly becoming a pain. The other day I had to change a simple property on an object containing a QList> This was over a remote MySQL connection, and ODB started to go through the complex operation of executing a ton of INSERT statements, one at a time. I'm reading the manual right now, but I can't seem to find a trick in the existing documentation. Best regards, Rene Jensen From boris at codesynthesis.com Fri Nov 2 09:42:47 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Nov 2 09:10:15 2012 Subject: [odb-users] How to make a "lazy" QList? In-Reply-To: References: Message-ID: Hi Rene, Rene Jensen writes: > Have you given any further thoughts to this? Automatic loading and saving > of lists of objects is increasingly becoming a pain. Yes, I think it is generally a good idea, perhaps also combined with change tracking. Unfortunately (or furtunately; depends on how you look at it I guess) there is a lot of other "generally good ideas" as well as features requested by paying customer that are competing with this. For example, right now, we are working on multi-database support. I will try my best to squeeze this into the next release but cannot really promise anything. The only workaround that I could think of is rather dirty. The idea is to create another persistent class with a subset of data members but which is mapped to the same table. You can then use this data member to update only a section of the class. In fact, with virtual data members you can create a thin wrapper class for this. Here is an example: #pragma db object struct person { #pragma db id auto unisgned int id_; std::string name_; unisgned int age_; }; #pragma db object table("person") struct person_name { person_name (person& p): p_ (p) {} #pragma db member(id) virtual(unsigned int) id access(p_.id_) #pragma db member(name) virtual(std::string) access(p_.name_) #pragma db transient person& p_; }; Then, in your code, when you are ready to update person's name, you do: person p; ... p.name_ = "John Doe"; db.update (person_name (p)); In a sesne, this is like a view but it works for updating. Pretty cool, actually; virtual data members are a very powerful feature. Boris From rene at catatonic.dk Fri Nov 2 12:30:20 2012 From: rene at catatonic.dk (Rene Jensen) Date: Fri Nov 2 12:25:39 2012 Subject: [odb-users] How to make a "lazy" QList? In-Reply-To: References: Message-ID: On Fri, Nov 2, 2012 at 2:42 PM, Boris Kolpackov wrote: > Hi Rene, > > Rene Jensen writes: > > > Have you given any further thoughts to this? Automatic loading and saving > > of lists of objects is increasingly becoming a pain. > > Yes, I think it is generally a good idea, perhaps also combined with > change tracking. > ... ... > In fact, with virtual data members you can create a thin wrapper class > for this. Here is an example: > > > ... > > p.name_ = "John Doe"; > > db.update (person_name (p)); > > In a sesne, this is like a view but it works for updating. Pretty cool, > actually; virtual data members are a very powerful feature. > You are probably on to something here. I will try to go on with this and see how much work it entails. When driving home, I further considered your original suggestion using sections. The _real_ problem is not solved yet, which is the lack of fine grained update control over collections. If the penalty of adding a member to a QList already holding 2000 elements is that 2001 sql inserts are being executed, then there is no trick to do it fast. I'm pretty sure that you have given this problem a huge amount of thought. I remember reading either in the docs or on the mailing list about the problem too and the lack of sensible solutions. Presented like that, I see that the problem also touches on a the lack of a standard "signal-emitting" Qt collection or similar in std: Something that would react when you inserted or removed a single element. Much like Django's RelatedManager functioning as a collection: https://docs.djangoproject.com/en/1.4/ref/models/relations/ Best regards, Rene Jensen From isaaclascasas at gmail.com Sat Nov 3 13:58:17 2012 From: isaaclascasas at gmail.com (Isaac Lascasas) Date: Sat Nov 3 13:53:28 2012 Subject: [odb-users] Problems linking libodb-mysql with vs2012 Message-ID: Hello I am trying to build libodb-mysql-vc11 but I have a lot of unresolved externals from mysql. I have installed the windows mysql package from www.mysql.com. Visual studio points to the provided mysql libs under /Connector C 6.0.2/lib/debug. It seems that these prebuilt libraries don't play well with vc11 or that I'm missing something important. I was able to build libodb but I'm stucked in libodb-mysql. I wonder if there is a reliable way to build the mysql connector for vc11 because I have downloaded the sources and I can't find proper visual studio solutions. Output: Creating library ..\..\lib\odb-mysql-d.lib and object ..\..\lib\odb-mysql-d.exp 1>connection.obj : error LNK2019: unresolved external symbol _mysql_num_rows@4 referenced in function "public: virtual unsigned __int64 __thiscall odb::mysql::connection::execute(char const *,unsigned int)" (?execute@connection@mysql@odb@@UAE_KPBDI@Z) 1>connection.obj : error LNK2019: unresolved external symbol _mysql_field_count@4 referenced in function "public: virtual unsigned __int64 __thiscall odb::mysql::connection::execute(char const *,unsigned int)" (?execute@connection@mysql@odb@@UAE_KPBDI@Z) 1>connection.obj : error LNK2019: unresolved external symbol _mysql_affected_rows@4 referenced in function "public: virtual unsigned __int64 __thiscall odb::mysql::connection::execute(char const *,unsigned int)" (?execute@connection@mysql@odb@@UAE_KPBDI@Z) 1>connection.obj : error LNK2019: unresolved external symbol _mysql_errno@4referenced in function "public: __thiscall odb::mysql::connection::connection(class odb::mysql::database &)" (??0connection@mysql@odb@@QAE@AAVdatabase@12@@Z) 1>error.obj : error LNK2001: unresolved external symbol _mysql_errno@4 [...] 1>C:\Users\Isaac Lascasas\Desktop\odb_2_1_0\libodb-mysql-2.1.0\odb\mysql\..\..\bin\odb-mysql-d-2.1-vc11.dll : fatal error LNK1120: 37 unresolved externals ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== Regards, Isaac Lascasas. From boris at codesynthesis.com Mon Nov 5 05:29:21 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Nov 5 04:55:55 2012 Subject: [odb-users] Problems linking libodb-mysql with vs2012 In-Reply-To: References: Message-ID: Hi Isaac, Isaac Lascasas writes: > I am trying to build libodb-mysql-vc11 but I have a lot of unresolved > externals from mysql. I have installed the windows mysql package from > www.mysql.com. Visual studio points to the provided mysql libs under > /Connector C 6.0.2/lib/debug. I just tried this and it works perfectly for me. Here is what I did: 1. Download mysql-connector-c-noinstall-6.0.2-win32.zip from mysql.com. 2. Unpack it and point VC++ Include directory to the 'include' sub- directory inside and VC++ Library directory to the 'lib' sub- directory. Note that I don't have 'debug' under 'lib' like you do. 3. Build Win32/Debug libodb-mysql. Some things that might cause this: 1. Library architecture mismatch (i.e., you have 64-bit MySQL libraries but building 32-bit libodb-mysql). 2. Older version of MySQL headers and/or libraries are somewhere on your computer that are used instead. The easy way to check this is to rename the 'include' and 'lib' directories (one at a time) and make sure that you get compilation and linker errors saying that the respective files are not found. Boris From boris at codesynthesis.com Mon Nov 5 07:43:51 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Nov 5 07:10:25 2012 Subject: [odb-users] How to make a "lazy" QList? In-Reply-To: References: Message-ID: Hi Rene, Rene Jensen writes: > When driving home, I further considered your original suggestion using > sections. The _real_ problem is not solved yet, which is the lack of fine > grained update control over collections. If the penalty of adding a member > to a QList already holding 2000 elements is that 2001 sql inserts are being > executed, then there is no trick to do it fast. Yes, that's true. > Presented like that, I see that the problem also touches on a the lack of a > standard "signal-emitting" Qt collection or similar in std: Something that > would react when you inserted or removed a single element. Well, that would be only half of the problem. The other half is the modification of the element value in place. Consider: std::vector v = ... int& x = v[0]; // Vector has no idea whether we will modify x or not. x++; So a solution would be a custom, change-tracking container (with QList of std::vector-like interface) that is provided by ODB. Such a container would (a) track element insertions/deletions and translate them to the corresponding minimum set of INSERT/ERASE statements on update and (b) not allow (or at least restrict) in-place element modifications so that it can keep track of these as well. In other words: odb::vector v = ... if (v[0] == 0) {...} // Ok, we have const operator[]. int& x = v[0]; // Error; no non-const operator[]. int& x = v.modify (0); // Get reference for modification. x++; v.replace (0, 123); // Replace value. I think it won't be too difficult to add odb::vector and odb::qt::QList with this functionality. We have pretty much all the infrastructure for this and all that is left is to implement that change tracking logic carefully. Maybe, we should also support lazy loading this way: it won't be as general-purpose as sections but it will definitely be more natural to use and much easier to implement. Would you consider using odb::qt::QList with change tracking support instead of QList? Boris From jneuhart at tlirr.com Mon Nov 5 16:09:20 2012 From: jneuhart at tlirr.com (Jordan J. Neuhart) Date: Tue Nov 6 04:00:42 2012 Subject: [odb-users] Sorted Query Results Message-ID: <681FA42AB546F84C8CFDFCAA6D89A62803CAC0D9@husker.tlirr.local> Greetings, This has probably already been asked in the past, but I can't find anything out about it from the documentation. Is it possible to have a query return a result set sorted by a particular database column (similar to the "ORDER BY" SQL clause), or is all sorting to take place on the in-memory side using, for example, std::sort? Many thanks, Jordan Neuhart Database Administrator T-L Irrigation Co. P.O. Box 1047 151 East Hwy 6 & AB Road Hastings, NE 68902-1047 office: 402-462-4128 ext. 264 800-330-4264 ext. 264 cell: 402-217-1377 email: jjn@tlirr.com From boris at codesynthesis.com Tue Nov 6 05:19:58 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 6 04:46:19 2012 Subject: [odb-users] Sorted Query Results In-Reply-To: <681FA42AB546F84C8CFDFCAA6D89A62803CAC0D9@husker.tlirr.local> References: <681FA42AB546F84C8CFDFCAA6D89A62803CAC0D9@husker.tlirr.local> Message-ID: Hi Jordan, Jordan J. Neuhart writes: > Is it possible to have a query return a result set sorted by a > particular database column (similar to the "ORDER BY" SQL clause) Yes, you can add the ORDER BY clause as shown below (based on the person object from the hello example): db->query ((query::first == "John") + "ORDER BY" + query::age); We are also planning to add some syntactic sugar around this in one of the future versions so that you would be able to write something like this: db->query ((query::first == "John") + order_by (query::age)); Boris From jneuhart at tlirr.com Tue Nov 6 09:00:37 2012 From: jneuhart at tlirr.com (Jordan J. Neuhart) Date: Tue Nov 6 09:00:30 2012 Subject: [odb-users] Sorted Query Results Message-ID: <681FA42AB546F84C8CFDFCAA6D89A62803CAC113@husker.tlirr.local> Boris, Thanks again for clarifying things for me. I think ODB is going to work well for my project. Jordan -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Tuesday, November 06, 2012 4:20 AM To: Jordan J. Neuhart Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Sorted Query Results Hi Jordan, Jordan J. Neuhart writes: > Is it possible to have a query return a result set sorted by a > particular database column (similar to the "ORDER BY" SQL clause) Yes, you can add the ORDER BY clause as shown below (based on the person object from the hello example): db->query ((query::first == "John") + "ORDER BY" + query::age); We are also planning to add some syntactic sugar around this in one of the future versions so that you would be able to write something like this: db->query ((query::first == "John") + order_by (query::age)); Boris From isaaclascasas at gmail.com Tue Nov 6 10:11:05 2012 From: isaaclascasas at gmail.com (Isaac Lascasas) Date: Tue Nov 6 10:05:55 2012 Subject: [odb-users] Problems linking libodb-mysql with vs2012 In-Reply-To: References: Message-ID: Thank you. I got it working by building the connector myself from source with windows cmake. I still don't understand what was going on. I did what you said also and it still failed. Windows development really needs some revamp. Regards. Isaac Lascasas. 2012/11/5 Boris Kolpackov > Hi Isaac, > > Isaac Lascasas writes: > > > I am trying to build libodb-mysql-vc11 but I have a lot of unresolved > > externals from mysql. I have installed the windows mysql package from > > www.mysql.com. Visual studio points to the provided mysql libs under > > /Connector C 6.0.2/lib/debug. > > I just tried this and it works perfectly for me. Here is what I did: > > 1. Download mysql-connector-c-noinstall-6.0.2-win32.zip from mysql.com. > > 2. Unpack it and point VC++ Include directory to the 'include' sub- > directory inside and VC++ Library directory to the 'lib' sub- > directory. Note that I don't have 'debug' under 'lib' like you > do. > > 3. Build Win32/Debug libodb-mysql. > > Some things that might cause this: > > 1. Library architecture mismatch (i.e., you have 64-bit MySQL > libraries but building 32-bit libodb-mysql). > > 2. Older version of MySQL headers and/or libraries are somewhere > on your computer that are used instead. The easy way to check > this is to rename the 'include' and 'lib' directories (one at > a time) and make sure that you get compilation and linker > errors saying that the respective files are not found. > > Boris > From ststrou at sandia.gov Tue Nov 6 12:56:30 2012 From: ststrou at sandia.gov (Stroud, Sean T) Date: Tue Nov 6 12:51:43 2012 Subject: [odb-users] Support for boost::posix_time::ptime Message-ID: <8EDFC8F388A1E44BB67C9BAA57091F9E285E3E6C@EXMB03.srn.sandia.gov> Hi, According to section ?19.5.3 PostgreSQL Database Type Mapping? in the ODB manual, the default mapping for posix_time::ptime is TIMESTAMP. However, the ODB compiler complains about the following: #ifndef TEST_CLASS_H #define TEST_CLASS_H #include #include "boost/date_time/posix_time/posix_time.hpp" #pragma db value class Test_Class { public: Test_Class(); private: friend class odb::access; boost::posix_time::ptime m_time; }; #endif % odb ?d pgsql ?q test_class.h test_class.h:15:30: error: unable to map C++ type '::boost::posix_time::ptime' used in data member 'm_time' to a database type test_class.h:15:30: info: use '#pragma db type' to specify the database type To fix this, I tried placing #pragma db type(?timestamp?) on the m_time data member. The odb compiler no longer complained, however when I try to compile the generated code I get errors: /home/ststrou/ODB2.1_install/include/odb/pgsql/traits.hxx: In static member function ???static void odb::pgsql::default_value_traits >::set_image(typename odb::pgsql::image_traits::image_type&, bool&, T) [with T = boost::posix_time::ptime, odb::pgsql::database_type_id ID = id_timestamp]???: test_class-odb.cxx:83: instantiated from here /home/ststrou/ODB2.1_install/include/odb/pgsql/traits.hxx:374: error: invalid cast from type ???boost::posix_time::ptime??? to type ???long long int??? /home/ststrou/ODB2.1_install/include/odb/pgsql/traits.hxx: In static member function ???static void odb::pgsql::default_value_traits >::set_value(T&, const typename odb::pgsql::image_traits::image_type&, bool) [with T = boost::posix_time::ptime, odb::pgsql::database_type_id ID = id_timestamp]???: test_class-odb.cxx:106: instantiated from here /home/ststrou/ODB2.1_install/include/odb/pgsql/traits.hxx:365: error: invalid conversion from ???long long int??? to ???boost::date_time::special_values??? /home/ststrou/ODB2.1_install/include/odb/pgsql/traits.hxx:365: error: initializing argument 1 of ???boost::posix_time::ptime::ptime(boost::date_time::special_values)? It apparently does not know how to map a ptime to a timestamp. What am I doing wrong? Sean From boris at codesynthesis.com Tue Nov 6 13:50:45 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 6 13:17:02 2012 Subject: [odb-users] Support for boost::posix_time::ptime In-Reply-To: <8EDFC8F388A1E44BB67C9BAA57091F9E285E3E6C@EXMB03.srn.sandia.gov> References: <8EDFC8F388A1E44BB67C9BAA57091F9E285E3E6C@EXMB03.srn.sandia.gov> Message-ID: Hi Sean, Stroud, Sean T writes: > According to section ?19.5.3 PostgreSQL Database Type Mapping? in the > ODB manual, the default mapping for posix_time::ptime is TIMESTAMP. > > [...] > > % odb ?d pgsql ?q test_class.h You need to enable the Boost date-time sub-profile: odb ?d pgsql -p boost/date-time ?q test_class.h See Section "19.5 Date Time Library" for details. Boris From rene at catatonic.dk Tue Nov 6 13:30:32 2012 From: rene at catatonic.dk (Rene Jensen) Date: Tue Nov 6 13:25:19 2012 Subject: [odb-users] How to make a "lazy" QList? In-Reply-To: References: Message-ID: Hi Boris On Mon, Nov 5, 2012 at 1:43 PM, Boris Kolpackov wrote: > Hi Rene, > > Presented like that, I see that the problem also touches on a the lack of > a > > standard "signal-emitting" Qt collection or similar in std: Something > that > > would react when you inserted or removed a single element. > > Well, that would be only half of the problem. The other half is the > modification of the element value in place. Consider: > > std::vector v = ... > > int& x = v[0]; // Vector has no idea whether we will modify x or not. > > x++; > > So a solution would be a custom, change-tracking container (with QList > of std::vector-like interface) that is provided by ODB. Such a container > would (a) track element insertions/deletions and translate them to the > corresponding minimum set of INSERT/ERASE statements on update and (b) > not allow (or at least restrict) in-place element modifications so that > it can keep track of these as well. In other words: > > odb::vector v = ... > > if (v[0] == 0) {...} // Ok, we have const operator[]. > > int& x = v[0]; // Error; no non-const operator[]. > > int& x = v.modify (0); // Get reference for modification. > x++; > > v.replace (0, 123); // Replace value. > > I think it won't be too difficult to add odb::vector and odb::qt::QList > with this functionality. We have pretty much all the infrastructure for > this and all that is left is to implement that change tracking logic > carefully. Maybe, we should also support lazy loading this way: it > won't be as general-purpose as sections but it will definitely be > more natural to use and much easier to implement. > > Would you consider using odb::qt::QList with change tracking support > instead of QList? > > Boris > Hi Boris. You raise a very good question. I had to give it some thought. Could we split the matter in two? 1) Keeping the items 2) Adding, removing, modifying the items - "managing" them. The former is currently handled by known collections - QList, std::vector etc. The latter not at all currently. I suppose we can agree on these two claims: ad 1) Items should be stored in such a way that existing API's can make use of them. ad 2) If the user has direct access to a well-known QList, std::vector... then there is no way to know what he has done, thus update means: REMOVE ALL, INSERT ALL Basically I see two ways of organizing the code: Put (1) inside (2). In you suggestion it would mean having an odb::qt::QList as the manager which internally manages a traditional QList. For purposes of reading, the user would be able to gain access to the stored QList. Put (1) next to (2). Here it would mean something like struct Test { #pragma db transient QList nameList; #pragma db manages (nameList) odb::collectionmanager > nameManager; } Test t; // Modify nameList through the manager only t.nameManager.load_all(); t.nameManager.append ("Hello"); t.nameManager.update(); // Use t.nameList directly for read-only purposes foreach (QString name, t.nameList) { qDebug() << name; } ... Your version might make just as much sense, if not more: struct Test { // Use a template specialization which internally uses QList... odb::collectionmanager > names; } Test t; // The manager for QList mimics QList here and there, just for convenience. t.names.append ("World"); // Get read/write access to specific item QString& S = t.names[10]; S.replace ("Hello", "Hi"); // Get read-access to the QList. foreach (QString S, t.names.getList()) { qDebug() << S; } As long as the user can A) control which underlying collection type is used, and B) gain at least read-only access to that collection, then I will certainly use it. Best regards, Rene Jensen From ststrou at sandia.gov Tue Nov 6 14:29:17 2012 From: ststrou at sandia.gov (Stroud, Sean T) Date: Tue Nov 6 14:24:25 2012 Subject: [EXTERNAL] Re: [odb-users] Support for boost::posix_time::ptime In-Reply-To: References: <8EDFC8F388A1E44BB67C9BAA57091F9E285E3E6C@EXMB03.srn.sandia.gov> Message-ID: <8EDFC8F388A1E44BB67C9BAA57091F9E285E3EE1@EXMB03.srn.sandia.gov> Oh, right - thanks! Sean -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Tuesday, November 06, 2012 11:51 AM To: Stroud, Sean T Cc: odb-users@codesynthesis.com Subject: [EXTERNAL] Re: [odb-users] Support for boost::posix_time::ptime Hi Sean, Stroud, Sean T writes: > According to section ?19.5.3 PostgreSQL Database Type Mapping? in the > ODB manual, the default mapping for posix_time::ptime is TIMESTAMP. > > [...] > > % odb ?d pgsql ?q test_class.h You need to enable the Boost date-time sub-profile: odb ?d pgsql -p boost/date-time ?q test_class.h See Section "19.5 Date Time Library" for details. Boris From boris at codesynthesis.com Wed Nov 7 08:43:42 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Nov 7 08:09:40 2012 Subject: [odb-users] How to make a "lazy" QList? In-Reply-To: References: Message-ID: Hi Rene, Rene Jensen writes: > I suppose we can agree on these two claims: > ad 1) Items should be stored in such a way that existing API's can make use > of them. > ad 2) If the user has direct access to a well-known QList, std::vector... > then there is no way to know what he has done, thus update means: REMOVE > ALL, INSERT ALL Yes, that makes sense. > Put (1) inside (2). In you suggestion it would mean having an > odb::qt::QList as the manager which internally manages a traditional > QList. For purposes of reading, the user would be able to gain access > to the stored QList. Yes, that is the idea. I think we can support what I would call "const inheritance" from QList by providing an implicit conversion operator to const QList&. This way odb::QList would behave as if it was derived from QList's const interface. > Put (1) next to (2). I don't think this is a good idea from the safety point of view. It is too easy to forget that all modifications has to go through the manager and modify the container directly. > As long as the user can A) control which underlying collection type is > used, I think this will just complicate things since in each case we would want to mimic the original container's interface as closely as possible. Why not just have odb::QList which is based on QList, std::vector which is based on std::vector, etc? This way ODB versions are just drop-in replacements for Qt/standard containers. Boris From rene at catatonic.dk Wed Nov 7 09:33:46 2012 From: rene at catatonic.dk (Rene Jensen) Date: Wed Nov 7 09:28:27 2012 Subject: [odb-users] How to make a "lazy" QList? In-Reply-To: References: Message-ID: > Put (1) inside (2). In you suggestion it would mean having an > > odb::qt::QList as the manager which internally manages a traditional > > QList. For purposes of reading, the user would be able to gain access > > to the stored QList. > > Yes, that is the idea. I think we can support what I would call "const > inheritance" from QList by providing an implicit conversion operator > to const QList&. This way odb::QList would behave as if it was derived > from QList's const interface. > > > As long as the user can A) control which underlying collection type is > > used, > > I think this will just complicate things since in each case we would want > to mimic the original container's interface as closely as possible. Why > not just have odb::QList which is based on QList, std::vector which is > based on std::vector, etc? This way ODB versions are just drop-in > replacements for Qt/standard containers. > I'm not sure I can figure out exactly what you mean by "odb::QList which is based on QList". Nevertheless I think we agree. If I declare an odb::QList, I can gain const access to a real QList If I declare an odb::std::vector, I can gain const access to a real std::vector What else could I possibly want :-) Well, you *could* of course alleviate the need for that section solution we discussed. If ODB could figure out that "managed" collections should NOT be automatically loaded, then 99% of the superfluous database fetching could be eliminated: struct Shipment { ... #pragma db managed // Not really needed, I know odb::QList m_parcels; } QSharedPointer S= ... S.m_parcels.load_all() // NOW we load all foreign keys. In fact also all parcels from the parcel table // Cast to get a QList... checkAllParcels ( (const QList) S.m_parcels); S.m_parcels[0].weight = 20 Best regards, Rene Jensen From rene at catatonic.dk Wed Nov 7 01:00:27 2012 From: rene at catatonic.dk (Rene Jensen) Date: Wed Nov 7 09:31:37 2012 Subject: [odb-users] Sessions are not useful for application-wide purposes Message-ID: Hi Boris. Here is another post highlighting a problem that application designers have. I am not even sure that you want ODB to server a purpose matching what I describe. On with it... A typical GUI program will usually make a distinction between models and views. Obviously model classes will relate to ODB in some way. Specifically: - Model classes are kept alive for very long time, some as long as the application lives - They will integrate different aspects depending on which third party libraries are involved. I my case they derive from QObject and uses Qt's meta property system. - They carry identity. No two objects with the same identify should exist in the memory of the program at any time - They should be resource managed: Certainly the entire database cannot fit into memory at once Views (for me those are Qt forms) are responsible for holding one or more model classes alive. Views can stay alive for a short or long period depending on the user. Such demands doesn't rhyme well with ODB's concept of sessions. Again, the problems sessions solve are: 1) They provide a way to ensure the same entity is not loaded twice. 2) They keep objects cached in memory. The latter presents a problem: The obvious way to control uniqueness of classes in memory would be to use an application-wide session. But that would keep all touched objects alive forever. FIRST SOLUTION: Invent a "weak session cache", i.e. one that consists of weak pointers (raising issues of atomicity of checks etc... but usually GUI programs has just one GUI thread and a bunch of isolated workers). With such a session, you could achieve (1) but leave it to the model AND view classes to handle (2). SECOND SOLUTION: Let ODB use external factories for creating objects. Those factories could communicate with an application-wide pool of weak pointers that was under user control THIRD SOLUTION: Use inner structs for database data and only store pointers to those in the model classes. That way the application code can keep its own tables for converting those proxy-objects to real model classes when needed. This is the solution I was forced to go with. I don't like it because there is a huge maintenance burden and only a small gain in freedom. What do you think? Best regards, Rene From boris at codesynthesis.com Thu Nov 8 10:04:46 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Nov 8 09:30:23 2012 Subject: [odb-users] Sessions are not useful for application-wide purposes In-Reply-To: References: Message-ID: Hi Rene, Rene Jensen writes: > Such demands doesn't rhyme well with ODB's concept of sessions. Again, the > problems sessions solve are: > > 1) They provide a way to ensure the same entity is not loaded twice. > 2) They keep objects cached in memory. Well, the second just follows from the first. I.e., we need to keep objects around if we want to avoid loading them from the database all the time. > The latter presents a problem: The obvious way to control uniqueness of > classes in memory would be to use an application-wide session. But that > would keep all touched objects alive forever. The session as implemented in ODB (i.e., odb::session) wasn't designed for this purpose. Rather, its goal is to help with the so-called "application transactions", i.e., an application unit of work that can span multiple database transactions. For example: 1. Start a db transaction and load the Plane object. 2. Show the use available seats and wait for selection. 3. Start another transaction and update the Plane object (sitting in the cache) with selected seats. In this example we would create a session at the beginning and then destroy it at the end. So session is normally longer-lived than a single transaction but is still relatively short-lived. Specifically, odb::session is not particularly suitable as an application-wide, long-lived object cache because: 1. as you have mentioned, there is no control over how long objects are retained in the cache, 2. but also, odb::session is not thread-safe So it looks to me that instead of trying to re-purpose odb::session for what it wasn't made, it would be easier to just provide your own application-wide cache where you can control object lifetime, etc. In fact, there is nothing that prevents you from doing this right now. You can always check such a cache before calling database::load(). The only potential issue that I see is recursive object loading. To address this we could probably provide a way to integrate such custom cache into ODB so that it is automatically queried from within load() (i.e., we can define a session interface and make odb::session just one possible implementation). Another option would be to provide another variant of session that is thread-safe and allows for user control of object retention (e.g., a callback that is called before every insertion that allows you to evict some objects). > FIRST SOLUTION: > Invent a "weak session cache", i.e. one that consists of weak pointers > (raising issues of atomicity of checks etc... but usually GUI programs has > just one GUI thread and a bunch of isolated workers). With such a session, > you could achieve (1) but leave it to the model AND view classes to handle > (2). We cannot assume (a) that all smart pointers used as object pointers have weak counterparts and (b) there are no multi-threading issued (i.e., that all applications are like yours ;-)). > SECOND SOLUTION: > Let ODB use external factories for creating objects. Those factories could > communicate with an application-wide pool of weak pointers that was under > user control Well, that sounds pretty much the same as the custom session approach. > THIRD SOLUTION: > Use inner structs for database data and only store pointers to those in the > model classes. That way the application code can keep its own tables for > converting those proxy-objects to real model classes when needed. > This is the solution I was forced to go with. I don't like it because there > is a huge maintenance burden and only a small gain in freedom. Yes, that doesn't sound very clean. I assume you looked at the pimpl example which would probably make this a bit more palatable. Boris From longguang.xiao at 163.com Tue Nov 13 09:37:45 2012 From: longguang.xiao at 163.com (=?GBK?B?0KTB+rni?=) Date: Tue Nov 13 10:01:01 2012 Subject: [odb-users] help for ODB Message-ID: <239b38f4.10841.13afa3457cd.Coremail.longguang.xiao@163.com> hi, I want to execute native SQL statements of "SELECT", but the api (unsigned long long execute) is not supported the result of "SELECT". In LIBODB-MYSQL, the aip (unsigned long long connection::execute) call function mysql_store_result of MySQL to get data from database,but the rowset MYSQL_RES is not stored. May I use ODB to get the rowset of executing native SQL statements of "SELECT"? Thanks. lgxiao From boris at codesynthesis.com Tue Nov 13 10:39:11 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 13 10:03:18 2012 Subject: [odb-users] help for ODB In-Reply-To: <239b38f4.10841.13afa3457cd.Coremail.longguang.xiao@163.com> References: <239b38f4.10841.13afa3457cd.Coremail.longguang.xiao@163.com> Message-ID: Hi, longguang.xiao@163.com writes: > May I use ODB to get the rowset of executing native SQL statements > of "SELECT"? Yes, for that you would use a view, specifically a native view. See Section 9.5, "Native Views" in the ODB manual for details. Boris From longguang.xiao at 163.com Wed Nov 14 08:25:47 2012 From: longguang.xiao at 163.com (=?GBK?B?0KTB+rni?=) Date: Wed Nov 14 08:47:56 2012 Subject: [odb-users] help for ODB In-Reply-To: References: <239b38f4.10841.13afa3457cd.Coremail.longguang.xiao@163.com> Message-ID: <24ea6c1b.1fdb3.13aff18d099.Coremail.longguang.xiao@163.com> Thank you very much ? At 2012-11-13 23:39:11,"Boris Kolpackov" wrote: >Hi, > >longguang.xiao@163.com writes: > >> May I use ODB to get the rowset of executing native SQL statements >> of "SELECT"? > >Yes, for that you would use a view, specifically a native view. See >Section 9.5, "Native Views" in the ODB manual for details. > >Boris > From reza.jahanbakhshi at gmail.com Sat Nov 17 03:26:42 2012 From: reza.jahanbakhshi at gmail.com (Reza Jahanbakhshi) Date: Sat Nov 17 03:20:06 2012 Subject: [odb-users] SQL LIKE clause equivalent in ODB Message-ID: Hi, What is sql LIKE clause equivalent in ODB queries? Thanks, From boris at codesynthesis.com Sat Nov 17 15:01:50 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sat Nov 17 14:24:42 2012 Subject: [odb-users] SQL LIKE clause equivalent in ODB In-Reply-To: References: Message-ID: Hi Reza, Reza Jahanbakhshi writes: > What is sql LIKE clause equivalent in ODB queries? There is no syntactic sugar for this clause yet, however, you can use the native fragment. For example: query q (query::first + "LIKE" + query::_val ("J%")); Or: std::string like = ...; query q (query::first + "LIKE" + query::_val (like)); Boris From magnus.granqvist at tailormade.se Tue Nov 20 07:11:49 2012 From: magnus.granqvist at tailormade.se (Magnus Granqvist) Date: Tue Nov 20 07:21:59 2012 Subject: [odb-users] ODB compiler for oracle, double qoutes SQL statements Message-ID: Hi, The odb compiler generates oracle SQL code like this: "SELECT "boost_employee"."id" FROM "boost_employee" WHERE "boost_employee"."employer"=:1" This is not valid to run towards a oracle database as far as I know and when exeuting this SQL I get an ora error . TIs this a bug or is there some switch to odb to get around this? I guess the SQL should look something like this, i.e. there shouldn't be any double quotes in the string. "SELECT boost_employee.id FROM boost_employee WHERE boost_employee.employer=:1" Br, Magnus ___________________________________ Magnus Granqvist System Developer TailorMade Mobile: +46 70 449 54 40 Direct: + 46 8 5220 54 40 E-mail: magnus.granqvist@tailormade.se Web: www.tailormadeglobal.com Esplanaden 3A, SE-172 67 Sundbyberg, Sweden Fax: +46 8 29 36 56 Phone: +46 8 562 454 00 TailorMade develop and implement billing solutions for the telco and utility industries. We have 15 years of experience with installations in 15 countries. We focus on delivering innovative billing solutions that can increase flexibility and add new capabilities to the existing Billing / CIS systems. P Please consider the environment before printing this e-mail -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.png Type: image/png Size: 10461 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20121120/be2ea465/image001.png From boris at codesynthesis.com Tue Nov 20 08:25:00 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 20 07:47:02 2012 Subject: [odb-users] ODB compiler for oracle, double qoutes SQL statements In-Reply-To: References: Message-ID: <20121120132500.GA6337@onega.codesynthesis.com> Hi Magnus, Magnus Granqvist writes: > The odb compiler generates oracle SQL code like this: > > "SELECT "boost_employee"."id" FROM "boost_employee" WHERE > "boost_employee"."employer"=:1" > > This is not valid to run towards a oracle database as far as I know > and when exeuting this SQL I get an ora error. As far as I know, identifier quoting is legal in Oracle. In fact, it is required if you use a keyword as a table or column name or if you want to preserve case (Oracle upper-cases all the unquoted identifiers by default). So ODB-generated queries are and were always quoted and we never had any issues with that. What exactly is the error code and message that you are getting? One common situation where you would get an error trying to execute an ODB-generated query is if the corresponding tables haven't been created. Boris From prokher at gmail.com Tue Nov 20 08:10:19 2012 From: prokher at gmail.com (Alexander A. Prokhorov) Date: Tue Nov 20 08:03:22 2012 Subject: [odb-users] Polymorphic bug? Message-ID: <50AB813B.2050903@gmail.com> Hello, Boris. We have encountered a problem with new odb polyporphic inheritance feature that completely blocks any further development. Thing is, any fields in derived class that are "bigger" than a certain threshold fail to load from database (SQLite). Simplified example is attached. Used libraries: Qt 4 Odb 2.1.0 SQLite 3.7.11 Thanks in advance. -------------- next part -------------- A non-text attachment was scrubbed... Name: odbsaveload.tar.gz Type: application/x-gzip Size: 4493 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20121120/f9a332a0/odbsaveload.tar.bin From magnus.granqvist at tailormade.se Tue Nov 20 08:08:57 2012 From: magnus.granqvist at tailormade.se (Magnus Granqvist) Date: Tue Nov 20 08:04:15 2012 Subject: =?us-ascii?Q?RE=3A_=5Bodb-users=5D_ODB_compiler_for_oracle=2C_do?= =?us-ascii?Q?uble_qoutes_SQL=09statements?= In-Reply-To: <20121120132500.GA6337@onega.codesynthesis.com> Message-ID: <47C16AE8-E85F-4CFD-B100-770C40054EFF@tailormade.se> Hi, In my tests I run the following query: SELECT "dagsmproduct"."oidval","dagsmproduct"."msisdn" FROM "dagsmproduct" The table exists in my database. But I get "ORA-00942: table or view does not exist". If I run the same query in sqlplus command line tool I also get ORA-00942. If I manually edit the generate file and remove the double quotes the query works from the test application: const char access::object_traits< ::dagsmproduct >::query_statement[] = "SELECT " "\"dagsmproduct\".\"oidval\"," "\"dagsmproduct\".\"msisdn\"" " FROM \"dagsmproduct\"" " "; To const char access::object_traits< ::dagsmproduct >::query_statement[] = "SELECT " "dagsmproduct.oidval," "dagsmproduct.msisdn" " FROM dagsmproduct" " "; But I think I see why this is happening now, the table must be created with quotes to support the SQL. This could be a problem developing for existing production databases that is not created with qoutes CREATE TABLE "dagsmproduct" ( "oidval" RAW(16), "msisdn" VARCHAR2(512) NOT NULL PRIMARY KEY); /Magnus -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: den 20 november 2012 14:25 To: Magnus Granqvist Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] ODB compiler for oracle, double qoutes SQL statements Hi Magnus, Magnus Granqvist writes: > The odb compiler generates oracle SQL code like this: > > "SELECT "boost_employee"."id" FROM "boost_employee" WHERE > "boost_employee"."employer"=:1" > > This is not valid to run towards a oracle database as far as I know > and when exeuting this SQL I get an ora error. As far as I know, identifier quoting is legal in Oracle. In fact, it is required if you use a keyword as a table or column name or if you want to preserve case (Oracle upper-cases all the unquoted identifiers by default). So ODB-generated queries are and were always quoted and we never had any issues with that. What exactly is the error code and message that you are getting? One common situation where you would get an error trying to execute an ODB-generated query is if the corresponding tables haven't been created. Boris From boris at codesynthesis.com Tue Nov 20 08:48:56 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 20 08:11:35 2012 Subject: [odb-users] ODB compiler for oracle, double qoutes SQL?statements In-Reply-To: <47C16AE8-E85F-4CFD-B100-770C40054EFF@tailormade.se> References: <20121120132500.GA6337@onega.codesynthesis.com> <47C16AE8-E85F-4CFD-B100-770C40054EFF@tailormade.se> Message-ID: Hi Magnus, Magnus Granqvist writes: > But I think I see why this is happening now, the table must be created > with quotes to support the SQL. Yes, in other words, the tables were created without quoting and Oracle uppercased them. > This could be a problem developing for existing production databases > that is not created with qoutes > > CREATE TABLE "dagsmproduct" ( > "oidval" RAW(16), > "msisdn" VARCHAR2(512) NOT NULL PRIMARY KEY); In this case it is probably best to assign custom table/column names that correspond exactly to the existing names. This way, also, you can use more descriptive C++ names that follow your naming convention. For example: #pragma db object table("DAGSMPRODUCT") class DagSmProduct { ... #pragma db type("RAW(16)") column("OIDVAL") char oid_val[16]; #pragma db id column("MSISDN") std::string ms_isdn; }; Boris From magnus.granqvist at tailormade.se Tue Nov 20 08:30:46 2012 From: magnus.granqvist at tailormade.se (Magnus Granqvist) Date: Tue Nov 20 08:37:48 2012 Subject: =?us-ascii?Q?RE=3A_=5Bodb-users=5D_ODB_compiler_for_oracle=2C_do?= =?us-ascii?Q?uble_qoutes=09SQL=3Fstatements?= In-Reply-To: Message-ID: <9120325D-643D-4C75-9939-A742372FE26A@tailormade.se> Thanks, it works. Br, Magnus -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: den 20 november 2012 14:49 To: Magnus Granqvist Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] ODB compiler for oracle, double qoutes SQL?statements Hi Magnus, Magnus Granqvist writes: > But I think I see why this is happening now, the table must be created > with quotes to support the SQL. Yes, in other words, the tables were created without quoting and Oracle uppercased them. > This could be a problem developing for existing production databases > that is not created with qoutes > > CREATE TABLE "dagsmproduct" ( > "oidval" RAW(16), > "msisdn" VARCHAR2(512) NOT NULL PRIMARY KEY); In this case it is probably best to assign custom table/column names that correspond exactly to the existing names. This way, also, you can use more descriptive C++ names that follow your naming convention. For example: #pragma db object table("DAGSMPRODUCT") class DagSmProduct { ... #pragma db type("RAW(16)") column("OIDVAL") char oid_val[16]; #pragma db id column("MSISDN") std::string ms_isdn; }; Boris From boris at codesynthesis.com Tue Nov 20 11:15:59 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 20 10:37:57 2012 Subject: [odb-users] Polymorphic bug? In-Reply-To: <50AB813B.2050903@gmail.com> References: <50AB813B.2050903@gmail.com> Message-ID: Hi Alexander, Alexander A. Prokhorov writes: > We have encountered a problem with new odb polyporphic inheritance > feature that completely blocks any further development. > Thing is, any fields in derived class that are "bigger" than a certain > threshold fail to load from database (SQLite). Indeed this is a bug. I tracked it down and it is now fixed. The bug is in the ODB compiler so if you would like, I can build you a bug fix binary. Let me know which platform you need. And thanks for reporting it and for the test case! Boris From prokher at gmail.com Tue Nov 20 12:23:10 2012 From: prokher at gmail.com (Alexander A. Prokhorov) Date: Tue Nov 20 12:16:11 2012 Subject: [odb-users] Polymorphic bug? In-Reply-To: References: <50AB813B.2050903@gmail.com> Message-ID: <50ABBC7E.10008@gmail.com> Dear Boris, thanks for fast response. Could we just apply your patch to version 2.1.0 and rebuild it ourselves? Is this the patch we need? http://scm.codesynthesis.com/?p=odb/odb.git;a=commitdiff;h=e5f6d58885c6555a576bcc53b82797fdc6f241bf Best regards, Alexander. On 20.11.2012 20:15, Boris Kolpackov wrote: > Hi Alexander, > > Alexander A. Prokhorov writes: > >> We have encountered a problem with new odb polyporphic inheritance >> feature that completely blocks any further development. >> Thing is, any fields in derived class that are "bigger" than a certain >> threshold fail to load from database (SQLite). > Indeed this is a bug. I tracked it down and it is now fixed. The bug > is in the ODB compiler so if you would like, I can build you a bug > fix binary. Let me know which platform you need. > > And thanks for reporting it and for the test case! > > Boris From boris at codesynthesis.com Tue Nov 20 14:29:49 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 20 13:51:45 2012 Subject: [odb-users] Polymorphic bug? In-Reply-To: <50ABBC7E.10008@gmail.com> References: <50AB813B.2050903@gmail.com> <50ABBC7E.10008@gmail.com> Message-ID: Hi Alexander, Alexander A. Prokhorov writes: > Could we just apply your patch to version 2.1.0 and rebuild it ourselves? Yes, that would be even better! > Is this the patch we need? Yes, that's the one. Boris From tony at rightsoft.com.au Tue Nov 20 16:35:13 2012 From: tony at rightsoft.com.au (Tony Rietwyk) Date: Tue Nov 20 16:28:10 2012 Subject: [odb-users] ODB compiler for oracle, double qoutes SQL?statements In-Reply-To: References: <20121120132500.GA6337@onega.codesynthesis.com> <47C16AE8-E85F-4CFD-B100-770C40054EFF@tailormade.se> Message-ID: <001501cdc766$ec9fce20$c5df6a60$@rightsoft.com.au> Hi Boris, I believe Firebird database may be in the same boat - the server uppercases non-quoted names. Quoted names should only be generated if required. Qt uses the 'QString QSqlDriver.escapeIdentifier' function in its driver interface to quote each name only if necessary. Maybe ODB needs something similar - possibly even just a regex for valid id's, and only quote the id if that doesn't match? Looks like this would save a lot of ugly quoting in the generated code. Regards, Tony > Sent: Wednesday, 21 November 2012 12:49 AM > > Hi Magnus, > > Magnus Granqvist writes: > > > But I think I see why this is happening now, the table must be created > > with quotes to support the SQL. > > Yes, in other words, the tables were created without quoting and Oracle > uppercased them. > > > > This could be a problem developing for existing production databases > > that is not created with qoutes > > > > CREATE TABLE "dagsmproduct" ( > > "oidval" RAW(16), > > "msisdn" VARCHAR2(512) NOT NULL PRIMARY KEY); > > In this case it is probably best to assign custom table/column names that > correspond exactly to the existing names. This way, also, you can use more > descriptive C++ names that follow your naming convention. > For example: > > #pragma db object table("DAGSMPRODUCT") > class DagSmProduct > { > ... > > #pragma db type("RAW(16)") column("OIDVAL") > char oid_val[16]; > > #pragma db id column("MSISDN") > std::string ms_isdn; > }; > > Boris From prokher at gmail.com Wed Nov 21 04:25:45 2012 From: prokher at gmail.com (Alexander A. Prokhorov) Date: Wed Nov 21 04:18:41 2012 Subject: [odb-users] Polymorphic bug? In-Reply-To: References: <50AB813B.2050903@gmail.com> <50ABBC7E.10008@gmail.com> Message-ID: <50AC9E19.6060801@gmail.com> Dear Boris, we have tried to rebuild generator itself, but, it looks like non-trivial procedure (especially in windows). Actually, I made a mistake. I thought we use self built version, but no, we use prebuilt ODB compiler. (We've only rebuilt libodb-2.1.0 , libodb-boost-2.1.0 , libodb-qt-2.1.0 , libodb-sqlite-2.1.0 to disable TLS, cause there were some issues.) So, it would be great if you share win32/linux32/linux64 executables with us. Thanks in advance, Alexander. On 20.11.2012 23:29, Boris Kolpackov wrote: > Hi Alexander, > > Alexander A. Prokhorov writes: > >> Could we just apply your patch to version 2.1.0 and rebuild it ourselves? > Yes, that would be even better! > > >> Is this the patch we need? > Yes, that's the one. > > Boris From boris at codesynthesis.com Wed Nov 21 07:11:29 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Nov 21 06:33:16 2012 Subject: [odb-users] ODB compiler for oracle, double qoutes SQL?statements In-Reply-To: <001501cdc766$ec9fce20$c5df6a60$@rightsoft.com.au> References: <20121120132500.GA6337@onega.codesynthesis.com> <47C16AE8-E85F-4CFD-B100-770C40054EFF@tailormade.se> <001501cdc766$ec9fce20$c5df6a60$@rightsoft.com.au> Message-ID: Hi Tony, Tony Rietwyk writes: > Maybe ODB needs something similar - possibly even just a regex for > valid id's, and only quote the id if that doesn't match? I believe that would open a can of worms. IMO, this whole idea of Oracle being case sensitive yet converting all unquoted identifiers to upper case is a misfeature, to put it mildly. Consistently quoting all the identifiers everywhere seems like the most straightforward way to sidestep all this mess. If we only quote keywords, not only will we have to maintain a list of all known keywords for each database, but we will also have an inconsistency of non-keywords being converted to upper case while quoted keywords keeping their original case. Consider: CREATE TABLE Chair ...; CREATE TABLE "Table" ...; The first table will be called CHAIR while the second -- Table. Perhaps a better solution would be to provide an option which instructs the ODB compiler to convert all the database identifiers to upper case. While ODB internally will still use quotes, one will be able to write custom SQL without quoting and rely on Oracle to implicitly uppercase the identifiers. What do you think? Boris From boris at codesynthesis.com Wed Nov 21 07:35:39 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Nov 21 06:57:21 2012 Subject: [odb-users] Polymorphic bug? In-Reply-To: <50AC9E19.6060801@gmail.com> References: <50AB813B.2050903@gmail.com> <50ABBC7E.10008@gmail.com> <50AC9E19.6060801@gmail.com> Message-ID: Hi Alexander, Alexander A. Prokhorov writes: > So, it would be great if you share win32/linux32/linux64 executables > with us. I will be releasing 2.1.1 bug-fix release with all the binaries shortly. Boris From tony at rightsoft.com.au Wed Nov 21 08:51:40 2012 From: tony at rightsoft.com.au (Tony Rietwyk) Date: Wed Nov 21 08:44:33 2012 Subject: [odb-users] ODB compiler for oracle, double qoutes SQL?statements In-Reply-To: References: <20121120132500.GA6337@onega.codesynthesis.com> <47C16AE8-E85F-4CFD-B100-770C40054EFF@tailormade.se> <001501cdc766$ec9fce20$c5df6a60$@rightsoft.com.au> Message-ID: <001e01cdc7ef$55c2e6c0$0148b440$@rightsoft.com.au> Hi Boris, > Sent: Wednesday, 21 November 2012 11:11 PM > > If we only quote keywords, not only will we have to maintain a list of all > known keywords for each database, but we will also have an inconsistency of > non-keywords being converted to upper case while quoted keywords > keeping their original case. You are quite right. I was only thinking of the 'spaces in names' case for quoting. > Perhaps a better solution would be to provide an option which instructs the > ODB compiler to convert all the database identifiers to upper case. While > ODB internally will still use quotes, one will be able to write custom SQL > without quoting and rely on Oracle to implicitly uppercase the identifiers. > > What do you think? > > Boris That sounds a good idea. Tony From boris at codesynthesis.com Thu Nov 22 02:32:16 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Nov 22 01:53:48 2012 Subject: [odb-users] SELECT FOR UPDATE support In-Reply-To: References: Message-ID: Hi Magnus, Magnus Granqvist writes: > Does ODB support pessimistic Locking with "SELECT ... FOR UPDATE"? > With current ORM layer we can specify optimistic or pessimistic mode > for the database connection. We can also in runtime override this for > tables we doesn't need to lock (for read only tables for instance). > For some long running batch processes we doesn't want to get an > optimistic exception in the middle of the transaction. In this case > we do select ... for update and waits if given row already is locked. > > When executing code like this we need to specify if the select > statements will do "for update" or not: > > auto_ptr jane (db.load (jane_id)); > > odb::result r (db->query ()); > result r (db->query (query::first == "John" && > query::last == "Doe")); There is no direct support for this yet (i.e., there is no load_for_update() or query_for_update()). The tricky part with adding such support is that ODB caches and reuses prepared statements so we cannot just add the FOR UPDATE suffix to the normal load() statement on demand. Instead, we would have to prepare and cache a separate statement. At the same time, it is quite easy to achieve this functionality with query by simply adding the FOR UPDATE suffix. For example: result r (db->query ( (query::first == "John" && query::last == "Doe") + "FOR UPDATE OF" + query::id )); The OF" + query::id part is only necessary if you have object relationships (without it all the JOIN'ed rows will also be locked). We can also emulate load() with query and thus add FOR UPDATE: result r ( db.query ( (query::id == jane_id) + "FOR UPDATE OF" + query::id )); if (!r.empty ()) auto_ptr jane (r.begin ().load ()); Boris From boris at codesynthesis.com Thu Nov 22 07:30:09 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Nov 22 06:51:33 2012 Subject: [odb-users] ODB 2.1.1 released Message-ID: Hi, We have released ODB 2.1.1. This is a bug fix-only release without any new features or backwards-incompatible changes. Specifically, a number of bugs have been fixed in each database runtime as well as the ODB compiler. We would like to thank everyone who reported bugs, suggested fixes, as well as tested early versions of this release. Source code and pre-compiled binary packages for this release are available from the ODB Download page: http://www.codesynthesis.com/products/odb/download.xhtml SHA1 checksums for the files in this release are as follows: 6eeb5725bd64caa2a7ec31383bd5dcf87be5103f libodb-2.1.1.tar.bz2 3b017c840b58469279fc5cb8077faf232c5c95a2 libodb-2.1.1.tar.gz 020ee687fe51eefdef445e3ff78e20d4337e8154 libodb-2.1.1.zip 307018aac11f5f494eab00b6b29277bf02b683d9 libodb-boost-2.1.1.tar.bz2 c7f44dc52b74f89715d4fa73b27d046c954cfcee libodb-boost-2.1.1.tar.gz 9a2a04d8161c318de64e18063ccaa8c0429a50e5 libodb-boost-2.1.1.zip a3468f9ff8db883929c3aa3f02b4cdc5024b16dd libodb-mssql-2.1.1.tar.bz2 73c0895cb81ffc8cef5beef926ab16094316ce59 libodb-mssql-2.1.1.tar.gz c4494b132c51378f38c70c0c93e3172591f588c5 libodb-mssql-2.1.1.zip 43758a4df6a248d5aa4093e581de3d8f7930e52b libodb-mysql-2.1.1.tar.bz2 50ee465fa12b73e6be0d01f3265c314fe4946968 libodb-mysql-2.1.1.tar.gz 46f911c62b7dc9a57c7b7bcec7ab1feb41d9ebc2 libodb-mysql-2.1.1.zip a6a01bdfab6eb84eae41342621ef4f5e5f499e5d libodb-oracle-2.1.1.tar.bz2 a35d0b57afa5545789829833b33bc8c9c8d6aada libodb-oracle-2.1.1.tar.gz 7b989619a448fe6aa8732eae92f14fb70dd22aec libodb-oracle-2.1.1.zip 3c3e9fb765cd2f299c99f15efd19a307e8c2c4a3 libodb-pgsql-2.1.1.tar.bz2 7b7df5d06ec29d21ec50aa8e201963bdd32953cd libodb-pgsql-2.1.1.tar.gz ffc7ff9a9b8a267c375d0aac678f2253eafab245 libodb-pgsql-2.1.1.zip 448ac658193fbec4b011194a013523a49f636c75 libodb-qt-2.1.1.tar.bz2 881d978ed650bf07fbaba506bdf2637f77b0bc66 libodb-qt-2.1.1.tar.gz 3cfcf8c9710f300cee24a04425c44dcc26b3bb01 libodb-qt-2.1.1.zip 1e466babf8127d7a2d92a1c503b7e79b257eb8c9 libodb-sqlite-2.1.1.tar.bz2 cc48669fae0e6ec017c943f36c7ab39608e5f002 libodb-sqlite-2.1.1.tar.gz 24dd4c29ae87c2cdfab30751c129d824dcde1505 libodb-sqlite-2.1.1.zip d0f16d8088008b4e176026799c5ac531e241af7c odb-2.1.1-i686-linux-gnu.tar.bz2 1ac8f4dd103be218bbf0db2b124f64512765a26d odb-2.1.1-i686-macosx.tar.bz2 9a51b9bb0e0467712820ac26c5941721d4d57d54 odb-2.1.1-i686-solaris.tar.bz2 86678ec3969a93e4cef789d78c7899b614bfe697 odb-2.1.1-i686-windows.zip 2a77d8b83e36a0c23ca5764ec52ffda79618aa92 odb-2.1.1-sparc-solaris.tar.bz2 f3a85f20cf9961644bf393029e5f9f7c136307a3 odb-2.1.1.tar.bz2 068533d2bb88cee860b173591bfed595e9638444 odb-2.1.1.tar.gz 523404d7e760f750f77fd81939909470443b9497 odb-2.1.1-x86_64-linux-gnu.tar.bz2 84c6d994bc49fe8a8314f4697ee71f9d42a1f10a odb-2.1.1.zip dc50ea2ced005214efe617bae868739967a41392 odb-examples-2.1.1.tar.bz2 ead30321431e3e793f1765e09844ea2fa49ded9d odb-examples-2.1.1.tar.gz 9286ad99ce2842d3838310e3fe3da5040e715f8c odb-examples-2.1.1.zip 69e3f0220942cd453ad150b4094428fc26b6ea06 odb-tests-2.1.1.tar.bz2 6d68f43256211c14de108a53a3511c9dda95f01d odb-tests-2.1.1.tar.gz 61d29cfe7a3576d86ac119de3f5059c6b7ec1d7f odb-tests-2.1.1.zip Enjoy, Boris From prokher at gmail.com Thu Nov 22 09:51:53 2012 From: prokher at gmail.com (Alexander A. Prokhorov) Date: Thu Nov 22 09:44:39 2012 Subject: [odb-users] Polymorphic bug? In-Reply-To: References: <50AB813B.2050903@gmail.com> <50ABBC7E.10008@gmail.com> <50AC9E19.6060801@gmail.com> Message-ID: <50AE3C09.6000208@gmail.com> Dear Boris, that is great. Just curious, when will 2.1.1 happen? ;) On 21.11.2012 16:35, Boris Kolpackov wrote: > Hi Alexander, > > Alexander A. Prokhorov writes: > >> So, it would be great if you share win32/linux32/linux64 executables >> with us. > I will be releasing 2.1.1 bug-fix release with all the binaries shortly. > > Boris From prokher at gmail.com Thu Nov 22 09:52:31 2012 From: prokher at gmail.com (Alexander A. Prokhorov) Date: Thu Nov 22 09:45:16 2012 Subject: [odb-users] Polymorphic bug? In-Reply-To: <50AE3C09.6000208@gmail.com> References: <50AB813B.2050903@gmail.com> <50ABBC7E.10008@gmail.com> <50AC9E19.6060801@gmail.com> <50AE3C09.6000208@gmail.com> Message-ID: <50AE3C2F.6050109@gmail.com> Sorry, I see it is already here. On 22.11.2012 18:51, Alexander A. Prokhorov wrote: > Dear Boris, > > that is great. Just curious, when will 2.1.1 happen? ;) > > On 21.11.2012 16:35, Boris Kolpackov wrote: >> Hi Alexander, >> >> Alexander A. Prokhorov writes: >> >>> So, it would be great if you share win32/linux32/linux64 executables >>> with us. >> I will be releasing 2.1.1 bug-fix release with all the binaries shortly. >> >> Boris > From Davide.Anastasia at qualitycapital.com Mon Nov 26 09:53:38 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Mon Nov 26 09:46:19 2012 Subject: [odb-users] Store a tree in ODB Message-ID: <6989CEDF160F9A42A3F5FF832CBAA72C2623A6@exbe19.nasstar-t1.net> Hi, I want to store a tree inside a database table: every tuple can be the father of several other tuples (in a sort of tree-shaped data structure). Would something like this work? class Node { // ... private: odb:: boost::lazy_shared_ptr< Node> m_father; } Can also a child relationship be realized in this way? Cheers, Davide Anastasia Analyst, Research & Development Quality Capital Management Ltd. QCM House * Horizon Business Village No. 1 Brooklands Road Weybridge * Surrey KT13 0TJ United Kingdom Tel: +44 (0) 1932 334 400 Fax: +44 (0) 1932 334 415 Email: Davide.Anastasia@QualityCapital.com www.qualitycapital.com ________________________________ This email and any attachments are confidential and intended solely for the use of the individual(s) to whom it is addressed. Any views or opinions presented are solely those of the author and do not necessarily represent those of Quality Capital Management Ltd. If you are not the intended recipient, be advised that you have received this email in error and that any use, dissemination, printing, forwarding or copying of this email is strictly prohibited. Please contact the sender if you have received this email in error. You should also be aware that emails are susceptible to interference and you should not assume that the contents of this email originated from the sender above or that they have been accurately reproduced in their original form. Quality Capital Management Ltd is authorised and regulated by the Financial Services Authority in the UK and is a member of the National Futures Association in the US. ________________________________ From boris at codesynthesis.com Mon Nov 26 11:00:53 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Nov 26 10:21:03 2012 Subject: [odb-users] Store a tree in ODB In-Reply-To: <6989CEDF160F9A42A3F5FF832CBAA72C2623A6@exbe19.nasstar-t1.net> References: <6989CEDF160F9A42A3F5FF832CBAA72C2623A6@exbe19.nasstar-t1.net> Message-ID: Hi Davide, Davide Anastasia writes: > I want to store a tree inside a database table: every tuple can be the > father of several other tuples (in a sort of tree-shaped data > structure). > > Would something like this work? > > class Node > { > //... > private: > odb:: boost::lazy_shared_ptr< Node> m_father; > } Yes, there is no technical reason why this won't work. Self-references are supported by ODB. How practical this will be is another question, though. Every "navigation" from child to parent or the other way around will require a database query. If that's too slow then a database- specific data type (e.g., ltree in PostgreSQL) or a custom binary representation of a tree (stored as BLOB) might be the alternatives. > Can also a child relationship be realized in this way? Yes, though you would need to use a weak pointer for one of the references. And probably make one of them inverse (it is a bidirectional relationship). Boris From Davide.Anastasia at qualitycapital.com Tue Nov 27 05:09:48 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Tue Nov 27 05:01:51 2012 Subject: [odb-users] Store a tree in ODB References: <6989CEDF160F9A42A3F5FF832CBAA72C2623A6@exbe19.nasstar-t1.net> Message-ID: <6989CEDF160F9A42A3F5FF832CBAA72C2623CE@exbe19.nasstar-t1.net> Hi Boris, We don't need to query often to know the structure of the tree, so a self-referencing table is absolutely fine for our aim. However, my suggested solution will enforce a foreign key in the m_father relation, and I am not sure whether I can put a null value in there for the root of the tree (DBMS might refuse this value, am I right?). I've slightly rethink this solution in this way: Class Node { //... Private: std::vector< odb::boost::lazy_shared_ptr< Node > > m_children; }; In this way I am actually generating a supplementary table that stores the tree structure, which I can navigate both ways to discover for each node either its father or its children. Does that sound like a more reasonable approach? Best, Davide -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: 26 November 2012 16:01 To: Davide Anastasia Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Store a tree in ODB Hi Davide, Davide Anastasia writes: > I want to store a tree inside a database table: every tuple can be the > father of several other tuples (in a sort of tree-shaped data > structure). > > Would something like this work? > > class Node > { > //... > private: > odb:: boost::lazy_shared_ptr< Node> m_father; } Yes, there is no technical reason why this won't work. Self-references are supported by ODB. How practical this will be is another question, though. Every "navigation" from child to parent or the other way around will require a database query. If that's too slow then a database- specific data type (e.g., ltree in PostgreSQL) or a custom binary representation of a tree (stored as BLOB) might be the alternatives. > Can also a child relationship be realized in this way? Yes, though you would need to use a weak pointer for one of the references. And probably make one of them inverse (it is a bidirectional relationship). Boris From Davide.Anastasia at qualitycapital.com Tue Nov 27 05:14:16 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Tue Nov 27 05:06:20 2012 Subject: [odb-users] Enforcing primary key in 1-N relationship Message-ID: <6989CEDF160F9A42A3F5FF832CBAA72C2623D0@exbe19.nasstar-t1.net> Hi, the manual [1] describes how to obtain a table-in-the-middle in a 1-N relationship using the "inverse" keyword. I wonder whether there is a method to enforce that every value in the "employer_employees" table is also primary key (avoid duplication). Best, Davide [1] http://www.codesynthesis.com/products/odb/doc/manual.xhtml#6.2.2 From boris at codesynthesis.com Tue Nov 27 07:58:10 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 27 07:18:05 2012 Subject: [odb-users] Store a tree in ODB In-Reply-To: <6989CEDF160F9A42A3F5FF832CBAA72C2623CE@exbe19.nasstar-t1.net> References: <6989CEDF160F9A42A3F5FF832CBAA72C2623A6@exbe19.nasstar-t1.net> <6989CEDF160F9A42A3F5FF832CBAA72C2623CE@exbe19.nasstar-t1.net> Message-ID: Hi Davide, Davide Anastasia writes: > However, my suggested solution will enforce a foreign key in the > m_father relation, and I am not sure whether I can put a null value > in there for the root of the tree (DBMS might refuse this value, am > I right?). You can store NULL in the pointer as long as you don't declare the pointer not_null. > I've slightly rethink this solution in this way: > > Class Node > { > //... > Private: > std::vector< odb::boost::lazy_shared_ptr< Node > > m_children; > }; > > In this way I am actually generating a supplementary table that stores > the tree structure, which I can navigate both ways to discover for each > node either its father or its children. Does that sound like a more > reasonable approach? The additional table seems wasteful to me, especially since you can achieve the same functionality without it: #pragma db object class Node { odb::boost::lazy_shared_ptr< Node > m_parent; #pragma db inverse(m_parent) std::vector< odb::boost::lazy_weak_ptr< Node > > m_children; }; Boris From boris at codesynthesis.com Tue Nov 27 08:07:38 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Nov 27 07:27:32 2012 Subject: [odb-users] Enforcing primary key in 1-N relationship In-Reply-To: <6989CEDF160F9A42A3F5FF832CBAA72C2623D0@exbe19.nasstar-t1.net> References: <6989CEDF160F9A42A3F5FF832CBAA72C2623D0@exbe19.nasstar-t1.net> Message-ID: Hi Davide, Davide Anastasia writes: > I wonder whether there is a method to enforce that every value in the > "employer_employees" table is also primary key (avoid duplication). At the moment the only way that I can think of is manually via the ALTER TABLE ADD CONSTRAINT statement. Boris From Davide.Anastasia at qualitycapital.com Tue Nov 27 07:50:25 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Tue Nov 27 07:42:36 2012 Subject: [odb-users] Enforcing primary key in 1-N relationship References: <6989CEDF160F9A42A3F5FF832CBAA72C2623D0@exbe19.nasstar-t1.net> Message-ID: <6989CEDF160F9A42A3F5FF832CBAA72C2623E2@exbe19.nasstar-t1.net> Would you consider this as a feature request? :) Cheers, D. -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: 27 November 2012 13:08 To: Davide Anastasia Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] Enforcing primary key in 1-N relationship Hi Davide, Davide Anastasia writes: > I wonder whether there is a method to enforce that every value in the > "employer_employees" table is also primary key (avoid duplication). At the moment the only way that I can think of is manually via the ALTER TABLE ADD CONSTRAINT statement. Boris From Davide.Anastasia at qualitycapital.com Tue Nov 27 09:07:58 2012 From: Davide.Anastasia at qualitycapital.com (Davide Anastasia) Date: Tue Nov 27 09:00:23 2012 Subject: [odb-users] update on key duplicate Message-ID: <6989CEDF160F9A42A3F5FF832CBAA72C2623F9@exbe19.nasstar-t1.net> Hi, Me again today! Is there a way to perform something like: "INSERT ... ON DUPLICATE KEY UPDATE" with ODB? Best, Davide From boris at codesynthesis.com Wed Nov 28 08:57:45 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Nov 28 08:17:23 2012 Subject: [odb-users] Enforcing primary key in 1-N relationship In-Reply-To: <6989CEDF160F9A42A3F5FF832CBAA72C2623E2@exbe19.nasstar-t1.net> References: <6989CEDF160F9A42A3F5FF832CBAA72C2623D0@exbe19.nasstar-t1.net> <6989CEDF160F9A42A3F5FF832CBAA72C2623E2@exbe19.nasstar-t1.net> Message-ID: Hi Davide, Davide Anastasia writes: > Would you consider this as a feature request? :) Yes, this is on our TODO though with a fairly low priority. The way I currently see this being handled in the future is through the set containers. std::vector does not prohibit duplicate elements while std::set does. So, in the future, if you use std::set, ODB will automatically generate the constraint on the resulting table. Boris From boris at codesynthesis.com Wed Nov 28 09:03:26 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Nov 28 08:23:01 2012 Subject: [odb-users] update on key duplicate In-Reply-To: <6989CEDF160F9A42A3F5FF832CBAA72C2623F9@exbe19.nasstar-t1.net> References: <6989CEDF160F9A42A3F5FF832CBAA72C2623F9@exbe19.nasstar-t1.net> Message-ID: Hi Davide, Davide Anastasia writes: > Is there a way to perform something like: > > "INSERT ... ON DUPLICATE KEY UPDATE" > > with ODB? No. ODB caches and re-uses prepared statements so adding "modifiers" like this won't be easy (unless you want it applied for every INSERT). You can also first do a load(), check if the key is the same, and then use either insert() or update(). Boris From hurdad at gmail.com Wed Nov 28 23:44:18 2012 From: hurdad at gmail.com (Alex Hurd) Date: Thu Nov 29 04:03:33 2012 Subject: [odb-users] RPM .spec file for libodb Message-ID: I couldn't find an rpm so I created a spec file. See attached. -------------- next part -------------- A non-text attachment was scrubbed... Name: libodb.spec Type: application/octet-stream Size: 1202 bytes Desc: not available Url : http://codesynthesis.com/pipermail/odb-users/attachments/20121128/c87361fe/libodb.obj From boris at codesynthesis.com Thu Nov 29 04:51:47 2012 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Nov 29 04:11:06 2012 Subject: [odb-users] RPM .spec file for libodb In-Reply-To: References: Message-ID: Hi Alex, Alex Hurd writes: > I couldn't find an rpm so I created a spec file. See attached. Thanks for sharing, that's helpful. Of course, ideally, we would like to see the complete ODB packaged and in the official Fedora/RHEL repositories. If anyone is interested in doing this, they will have "priority" support from us ;-). Boris