From boris at codesynthesis.com Fri Aug 1 06:14:20 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Aug 1 06:19:39 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> References: <015e8e73bec14aa982c48ad15ba4e7b3@QEX.qosmotec.com> <60d0da4d602943c6b28317d64452335c@QEX.qosmotec.com> <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> Message-ID: Hi Marcel, Marcel Nehring writes: > So I would have to split all my persistent template classes into two? > A template part and a none template part? Actually I would like to > avoid that since it would mean a blow up in my number of classes. > However, if I understand you correctly this would only be a possible > optimization to reduce code size and to avoid the need to respecify > pragmas for every instantiation? Yes, that's correct. For example, if your id member is in the template, then you will have to specify: #pragma db member(some_base:::m_id) id auto for every instantiation. However, if the type of m_id does not depend on the template argument, then you can put it into a non-template base class and specify the id pragma only once. You also don't have to have a separate non-template base for every template base. I would imagine in a typical situation you would have the same types for the id and version members for all (or most) of your classes. So you could place them into a single non-template base and use it for all of your templates. > However, yes, it would be great if you could build a pre-release binary. Here is the 2.4.0.a3 pre-release: http://codesynthesis.com/~boris/tmp/odb/pre-release/ The NEWS file entry: * Support for defining persistent objects as instantiations of C++ class templates, similar to composite value types. For details, refer to Section 15.2, "Persistent Class Template Instantiations" in the ODB manual. Let me know if there are any problems. Boris From sean.clarke at sec-consulting.co.uk Sun Aug 3 13:32:12 2014 From: sean.clarke at sec-consulting.co.uk (Sean Clarke) Date: Sun Aug 3 13:32:20 2014 Subject: [odb-users] PostgreSQL NUMERIC(dec,prec) Message-ID: Hi, just playing with ODB and so far I have been pretty impressed at the ease of use and performance. I am just prototyping part of an existing Java/Hibernate app and have hit a problem with NUMERIC support (or lack of it). I have seen some postings from late 2012 that suggest a collection of custom classes/templates/traits - is this still the case? I am kind of surprised there is not a built in conversion from NUMERIC(x,y) to double. I have played with the the "#pragma db map type("regex") as("subst") [to("subst")] [from("subst")]" substitution, but can't seem to get it to work. Any quick/simple pointers to get me moving in? I have created a temp column and converted the NUMERIC to DOUBLE PRECISION in the Db and it works fine - but not only are there a lot of NUMERIC columns across a great many tables, but I kind of liked the DB storing financial info in fixed format. Regards Sean From boris at codesynthesis.com Mon Aug 4 03:48:02 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Aug 4 03:53:24 2014 Subject: [odb-users] PostgreSQL NUMERIC(dec,prec) In-Reply-To: References: Message-ID: Hi Sean, Sean Clarke writes: > I am kind of surprised there is not a built in conversion from > NUMERIC(x,y) to double. In the general case NUMERIC(x,y) doesn't map to double without loss. Also, implementing this conversion from the PG's binary representation of NUMERIC to double will probably be non-trivial, to say the least. > I have played with the the "#pragma db map type("regex") as("subst") > [to("subst")] [from("subst")]" substitution, but can't seem to get it to > work. The pgsql/custom test in the odb-tests package has a couple of examples, including for NUMERIC. Something like this should work: // Map NUMERIC PostgreSQL type to DOUBLE PRECISION. This will allow us // to extract it to C++ double. // #pragma db map type("NUMERIC *(\\(.+\\))?") \ as("DOUBLE PRECISION") \ to("(?)::NUMERIC$1") \ from("(?)::DOUBLE PRECISION") Then in your persistent classes: #pragma db type("NUMERIC (6, 4)") double member; Boris From mne at qosmotec.com Tue Aug 5 12:32:05 2014 From: mne at qosmotec.com (Marcel Nehring) Date: Tue Aug 5 12:32:29 2014 Subject: AW: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <015e8e73bec14aa982c48ad15ba4e7b3@QEX.qosmotec.com> <60d0da4d602943c6b28317d64452335c@QEX.qosmotec.com> <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> Message-ID: <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> Hi Boris, I tried the new version you build for me - thanks for that. However, either I did not fully understand how to use it, or it does not work properly. I modified your example a bit by removing the class called "derived". In case I specify the id pragma only once I get a "no data member designated as an object id" error. The error is issued for the line with the typedef. For the version pragma it suffices to specify it only once in the "base_data" class. Am I missing something? The code looks like the one below. Regards, Marcel #pragma db object abstract optimistic struct base_data { #pragma db id auto unsigned long id; #pragma db version unsigned long version; }; template struct base : public base_data { T x; }; typedef base base_derived; #pragma db object(base_derived) //#pragma db member(base_derived::id) id auto //uncomment to resolve error //#pragma db member(base_derived::version) version //this is not needed From sean.clarke at sec-consulting.co.uk Tue Aug 5 15:05:38 2014 From: sean.clarke at sec-consulting.co.uk (Sean Clarke) Date: Tue Aug 5 15:05:46 2014 Subject: [odb-users] PostgreSQL NUMERIC(dec,prec) In-Reply-To: References: Message-ID: Thanks Boris, that works a treat!! I was probably there with the pattern matching, but I didn't have the numeric pragma. Regards Sean Clarke --------------------------------------------- SEC Consulting Limited Phone: +44 (0)23 8040 5599 Website: http://www.sec-consulting.co.uk On 4 Aug 2014 08:53, "Boris Kolpackov" wrote: > Hi Sean, > > Sean Clarke writes: > > > I am kind of surprised there is not a built in conversion from > > NUMERIC(x,y) to double. > > In the general case NUMERIC(x,y) doesn't map to double without loss. > Also, implementing this conversion from the PG's binary representation > of NUMERIC to double will probably be non-trivial, to say the least. > > > > I have played with the the "#pragma db map type("regex") as("subst") > > [to("subst")] [from("subst")]" substitution, but can't seem to get it to > > work. > > The pgsql/custom test in the odb-tests package has a couple of examples, > including for NUMERIC. Something like this should work: > > // Map NUMERIC PostgreSQL type to DOUBLE PRECISION. This will allow us > // to extract it to C++ double. > // > #pragma db map type("NUMERIC *(\\(.+\\))?") \ > as("DOUBLE PRECISION") \ > to("(?)::NUMERIC$1") \ > from("(?)::DOUBLE PRECISION") > > Then in your persistent classes: > > #pragma db type("NUMERIC (6, 4)") > double member; > > Boris > From boris at codesynthesis.com Wed Aug 6 05:23:02 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 6 05:28:24 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> References: <015e8e73bec14aa982c48ad15ba4e7b3@QEX.qosmotec.com> <60d0da4d602943c6b28317d64452335c@QEX.qosmotec.com> <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> Message-ID: Hi Marcel, Marcel Nehring writes: > #pragma db object abstract optimistic > struct base_data > { > #pragma db id auto > unsigned long id; > > #pragma db version > unsigned long version; > }; > > template > struct base : public base_data > { > T x; > }; > > typedef base base_derived; > #pragma db object(base_derived) > //#pragma db member(base_derived::id) id auto //uncomment to resolve error > //#pragma db member(base_derived::version) version //this is not needed What happens here is quite interesting: Since base_derived is not actually used (e.g., derived from), the C++ compiler does not instantiate the template. In other words, from the C++ compiler's point of view, the above typedef is semantically equivalent to a forward declaration: class base_derived; As a result, when ODB gets a chance to look at the AST, it doesn't "see" that base_derived actually inherits from base_data which in turn defines the object id. A workaround for this problem would be to explicitly instantiate the otherwise unused templates for the ODB compiler: typedef base base_derived; #pragma db object(base_derived) #ifdef ODB_COMPILER template struct base; #endif I am also trying to see if there an automatic way to do this during the ODB compilation. Will let you know what I find. Boris From boris at codesynthesis.com Wed Aug 6 06:28:20 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 6 06:33:43 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <015e8e73bec14aa982c48ad15ba4e7b3@QEX.qosmotec.com> <60d0da4d602943c6b28317d64452335c@QEX.qosmotec.com> <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> Message-ID: Hi Marcel, Ok, I've fixed it so the explicit template instantiation is no longer necessary. I replaced the 2.4.0.a3 Windows binary with the fixed one so that you don't need to rebuild the runtimes: http://codesynthesis.com/~boris/tmp/odb/pre-release/odb-2.4.0.a3-i686-windows.zip Let me know if there are any other issues. Boris From Mikhail.Tomilov at infotecs.ru Fri Aug 8 04:58:21 2014 From: Mikhail.Tomilov at infotecs.ru (Tomilov.Mikhail) Date: Fri Aug 8 08:56:12 2014 Subject: [odb-users] Get real error reason from object_already_persistent Message-ID: <53E4912D.20901@infotecs.ru> Hello! We use postgresql with ODB. Lets consider the following problem. I need to insert a row into users table, which has unique constraint on "login" field and some FK. If I insert row with duplicate login field I get object_already_persistent exception. AFAIK object_already_persistent exception is thrown when any postgresql constraint fails. It could be PK constraint, unique constraint, FK constraint. Can I determine real reason for my case to pass correct error code to client? It would be natural to get database error info from odb::object_already_persistent exception. Thanks From newzai at vip.qq.com Fri Aug 8 10:06:43 2014 From: newzai at vip.qq.com (=?gb18030?B?s8LQobrp?=) Date: Fri Aug 8 14:10:49 2014 Subject: [odb-users] centos C++ ORM ODB connect to MSSQL 2005 Message-ID: I had install unixODB & freetds , and configure the ODBC DSN in /etc/odbc.ini file , also add freetds driver in /etc/odbcinit.ini. ODB example connection to MSSQL error. but OTL sucessfull. OTL using DSN, ODB can't using DSN..what can't do??? From boris at codesynthesis.com Mon Aug 11 05:56:13 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Aug 11 06:01:35 2014 Subject: [odb-users] Get real error reason from object_already_persistent In-Reply-To: <53E4912D.20901@infotecs.ru> References: <53E4912D.20901@infotecs.ru> Message-ID: Hi Mikhail, Tomilov.Mikhail writes: > I need to insert a row into users table, which has unique constraint > on "login" field and some FK. If I insert row with duplicate login > field I get object_already_persistent exception. AFAIK > object_already_persistent exception is thrown when any postgresql > constraint fails. It could be PK constraint, unique constraint, FK > constraint. Can I determine real reason for my case to pass correct > error code to client? > > It would be natural to get database error info from > odb::object_already_persistent exception. The issue is described in Section 19.5.3, "Unique Constraint Violations" in the ODB manual: "Due to the granularity of the PostgreSQL error codes, it is impossible to distinguish between the duplicate primary key and other unique constraint violations. As a result, when making an object persistent, the PostgreSQL ODB runtime will translate all unique constraint violation errors to the object_already_persistent exception." There is also an informative thread that goes into more details and discusses possible solutions: http://www.codesynthesis.com/pipermail/odb-users/2012-September/000785.html On the second thought, the _pkey suffix idea doesn't sound bad. It is rarely that anyone assigns an explicit constraint name to the primary key. Would you be willing to test the fix? Boris From boris at codesynthesis.com Mon Aug 11 06:01:19 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Aug 11 06:06:41 2014 Subject: [odb-users] centos C++ ORM ODB connect to MSSQL 2005 In-Reply-To: References: Message-ID: Hi, ??? writes: > I had install unixODB & freetds , and configure the ODBC DSN in > /etc/odbc.ini file, also add freetds driver in /etc/odbcinit.ini. > > ODB example connection to MSSQL error. but OTL sucessfull. > OTL using DSN, ODB can't using DSN..what can't do??? ODB only supports SQL Server Native Client ODBC driver (which is, BTW, the only way forward when it comes to connecting to SQL Server, according to Microsoft). The good news is there is one for Linux. You can read more about it here: http://www.codesynthesis.com/~boris/blog/2011/12/02/microsoft-sql-server-odbc-driver-linux/ Boris From lidia at lemur-soft.com Wed Aug 13 05:21:30 2014 From: lidia at lemur-soft.com (Lidia Kalinovsky) Date: Wed Aug 13 05:21:37 2014 Subject: [odb-users] one-to-many relationship question Message-ID: Hello Is it possible to make contained classes ( means one-to-many relationship ) to be loaded with some condition (means, have query for contained ) ? For example: Let's say we have 2 classes: #pragma db... class A { bool hidden; }; #pragma db... class B { bool hidden; #pragma db unordered std::vector manyA; } to load objects of B, i use typedef odb::query queryT; queryT q; if (!fullLoading) q = queryT(queryT::hidden != true ); typename odb::core::result r (m_DB->query(q,true)); This way i have only Bs with hidden=0. Is it possible to have some condition for loaded A's objects inside manyA vector inside pragma (means, at compilation) ? inside dynamic query ? ( i need only A's with hidden=0. condition is constant and i could have a many contained vectors inside container). Thanks and regards. Lidia -- Software integration and outsourcing services, Lemur-Soft, Giv'at Nili Israel, 37825 Phone : (+972) 545748325 Fax : (+972) 775345383 Email : lidia@lemur-soft.com Web: www.lemur-soft.com From philip.ethier at gmail.com Tue Aug 12 14:31:45 2014 From: philip.ethier at gmail.com (Philip Ethier) Date: Wed Aug 13 06:57:36 2014 Subject: [odb-users] Altering column from integer to double precision Message-ID: ODB, When trying the odb compile I get an error saying the change from int to double is not yet handled automatically. I'm using a postgres database. So I came up with the following approach, do you think it will work correctly? Is this the recommended way to do the alter? 1 remove the int member var, odb compile with updated version 2 add the double member var, odb compile with updated version 3 write manual alter sql to change the column type from int to double precision 4 SQL to update the schema_version version column to the latest 5 start the program, and make sure to not run the pre and post migration sql Any thoughts are much appreciated! Thank you, From mne at qosmotec.com Wed Aug 13 07:44:05 2014 From: mne at qosmotec.com (Marcel Nehring) Date: Wed Aug 13 07:44:55 2014 Subject: AW: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <015e8e73bec14aa982c48ad15ba4e7b3@QEX.qosmotec.com> <60d0da4d602943c6b28317d64452335c@QEX.qosmotec.com> <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> Message-ID: <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> Hi, I ran into another problem that looks like it is related to this topic. One of my template classes has a member of type std::map>. ODB could not persist this automatically, so I put the following inside the class' definition: typedef std::pair Item; #pragma db value(Item) And changed the member declaration to std::map However, this too does not work and gives me a "unable to instantiate composite value class template" error for the typedef line. Any ideas? Regards, Marcel From boris at codesynthesis.com Wed Aug 13 07:50:28 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 13 07:55:49 2014 Subject: [odb-users] one-to-many relationship question In-Reply-To: References: Message-ID: Hi Lidia, Lidia Kalinovsky writes: > #pragma db... > class A > { > bool hidden; > }; > > #pragma db... > class B > { > bool hidden; > > #pragma db unordered > std::vector manyA; > } > > to load objects of B, i use > > typedef odb::query queryT; > queryT q; > if (!fullLoading) > q = queryT(queryT::hidden != true ); > > typename odb::core::result r (m_DB->query(q,true)); > > This way i have only Bs with hidden=0. > > Is it possible to have some condition for loaded A's objects inside manyA > vector inside pragma (means, at compilation) ? No, and I doubt we will support something like this. Seems very inflexible. > inside dynamic query ? Also not, but this is something on our TODO list. That is, support for containers in queries. What you can do as a workaround in the meantime is this (I am using raw pointers below but you will want to replace them with smart pointers): 1. Add the "back" pointer to A: class B; #pragma db... class A { bool hidden; #pragma db inverse(manyA) odb::lazy_ptr oneB; // Use the lazy (and weak) pointer corresponding // to the A's object pointer. }; This doesn't cost anything on the database side. If you want, you can also avoid loading it completely on the C++ side (see lazy-loaded sections). 2. Re-implement your query in terms of querying for A, not for B: typedef odb::query queryA; typedef odb::result resultA; queryA q (!queryA::hidden && !queryA::oneB->hidden) resultA r (db.query (q)); // Create an object cache so that Bs points to As that we have already // loaded. // odb::session s; std::setM bs; for (resultA::iterator i (r.begin ()); i != r.end (); ++i) { bs.insert (i->oneB.load ()); } // bs now contains all the Bs that are not hidden and only containing // non-hidden As. Boris From boris at codesynthesis.com Wed Aug 13 08:02:34 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 13 08:07:56 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> References: <60d0da4d602943c6b28317d64452335c@QEX.qosmotec.com> <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> Message-ID: Hi Marcel, Marcel Nehring writes: > One of my template classes has a member of type std::map std::pair>. ODB could not persist this automatically, > so I put the following inside the class' definition: > > typedef std::pair Item; > #pragma db value(Item) > > And changed the member declaration to std::map > > However, this too does not work and gives me a "unable to instantiate > composite value class template" error for the typedef line. Any ideas? I probably haven't explained this well enough in my previous emails. ODB only operates on class template instantiations. It doesn't process class templates themselves. So having something like this in a class template: typedef std::pair Item; #pragma db value(Item) doesn't tell ODB anything since this is itself a template (it is inside a template and depends on the template parameter T). What you need to do is have the value pragma for the instantiation of this. Here is what I mean: template class base { typedef std::pair Item; //#pragma db value(Item) // This won't work, Item is a "template". std::map map; }; typedef base int_base; #pragma db object(int_base) #pragma db value(int_base::Item); // This will work, int_base::Item is // an instantiation. Boris From lidia at lemur-soft.com Wed Aug 13 08:08:59 2014 From: lidia at lemur-soft.com (Lidia Kalinovsky) Date: Wed Aug 13 08:09:07 2014 Subject: [odb-users] one-to-many relationship question In-Reply-To: References: Message-ID: ok, thanks. waiting for support for containers in queries. On Wed, Aug 13, 2014 at 2:50 PM, Boris Kolpackov wrote: > Hi Lidia, > > Lidia Kalinovsky writes: > > > #pragma db... > > class A > > { > > bool hidden; > > }; > > > > #pragma db... > > class B > > { > > bool hidden; > > > > #pragma db unordered > > std::vector manyA; > > } > > > > to load objects of B, i use > > > > typedef odb::query queryT; > > queryT q; > > if (!fullLoading) > > q = queryT(queryT::hidden != true ); > > > > typename odb::core::result r (m_DB->query(q,true)); > > > > This way i have only Bs with hidden=0. > > > > Is it possible to have some condition for loaded A's objects inside manyA > > vector inside pragma (means, at compilation) ? > > No, and I doubt we will support something like this. Seems very > inflexible. > > > > inside dynamic query ? > > Also not, but this is something on our TODO list. That is, support for > containers in queries. > > What you can do as a workaround in the meantime is this (I am using > raw pointers below but you will want to replace them with smart > pointers): > > 1. Add the "back" pointer to A: > > class B; > > #pragma db... > class A > { > bool hidden; > > #pragma db inverse(manyA) > odb::lazy_ptr oneB; // Use the lazy (and weak) pointer corresponding > // to the A's object pointer. > }; > > This doesn't cost anything on the database side. If you want, you can > also avoid loading it completely on the C++ side (see lazy-loaded > sections). > > 2. Re-implement your query in terms of querying for A, not for B: > > typedef odb::query queryA; > typedef odb::result resultA; > > queryA q (!queryA::hidden && !queryA::oneB->hidden) > > resultA r (db.query (q)); > > // Create an object cache so that Bs points to As that we have already > // loaded. > // > odb::session s; > > std::setM bs; > > for (resultA::iterator i (r.begin ()); i != r.end (); ++i) > { > bs.insert (i->oneB.load ()); > } > > // bs now contains all the Bs that are not hidden and only containing > // non-hidden As. > > Boris > -- Software integration and outsourcing services, Lemur-Soft, Giv'at Nili Israel, 37825 Phone : (+972) 545748325 Fax : (+972) 775345383 Email : lidia@lemur-soft.com Web: www.lemur-soft.com From boris at codesynthesis.com Wed Aug 13 08:22:26 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 13 08:27:46 2014 Subject: [odb-users] Altering column from integer to double precision In-Reply-To: References: Message-ID: Hi Philip, Philip Ethier writes: > So I came up with the following approach, do you think it will work > correctly? > > 1 remove the int member var, odb compile with updated version > 2 add the double member var, odb compile with updated version > 3 write manual alter sql to change the column type from int to double > precision > 4 SQL to update the schema_version version column to the latest > 5 start the program, and make sure to not run the pre and post migration sql I "think" this will work. Generally, when it comes to database schema evolution, I believe your changes should be in the "obviously will work" category rather than "think will work". Otherwise this stuff will quickly get out of hand. Which brings us to your next questions: > Is this the recommended way to do the alter? No, this is definitely not the recommended way ;-). You are half way relying on ODB and half way doing your custom migration. The way I would implement this is like this: 1. Increment the model version. 2. Soft-delete the int member variable in this version (you can rename it also but keep its column name the same; db column pragma) 3. Soft-add the double member variable in this version (you can use the old var's name but make sure to give it a new column name). 4. Register data migration function that converts int's to double's. While this may not be as efficient (we have to load all the int's and store all the double's) or "seamless" (we will end up with a new column name), it is simple to the point that you can trust it will actually do what you think it should. You can read more about soft-add/delete in Section 13.4, "Soft Object Model Changes" in the ODB manual. Boris From mwpowellhtx at gmail.com Wed Aug 13 08:45:38 2014 From: mwpowellhtx at gmail.com (Michael Powell) Date: Wed Aug 13 08:45:45 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <60d0da4d602943c6b28317d64452335c@QEX.qosmotec.com> <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> Message-ID: On Wed, Aug 13, 2014 at 7:02 AM, Boris Kolpackov wrote: > Hi Marcel, > > Marcel Nehring writes: > >> One of my template classes has a member of type std::map> std::pair>. ODB could not persist this automatically, >> so I put the following inside the class' definition: >> >> typedef std::pair Item; >> #pragma db value(Item) If you stop and think about how preprocessor and compile time (template) issues are resolved, this makes perfect sense. ODB does not have enough information to preprocess the type at that time. >> And changed the member declaration to std::map >> >> However, this too does not work and gives me a "unable to instantiate >> composite value class template" error for the typedef line. Any ideas? > > I probably haven't explained this well enough in my previous emails. > ODB only operates on class template instantiations. It doesn't process > class templates themselves. So having something like this in a class > template: > > typedef std::pair Item; > #pragma db value(Item) > > doesn't tell ODB anything since this is itself a template (it is > inside a template and depends on the template parameter T). What you > need to do is have the value pragma for the instantiation of this. > Here is what I mean: > > template > class base > { > typedef std::pair Item; > //#pragma db value(Item) // This won't work, Item is a "template". > > std::map map; > }; > > typedef base int_base; > #pragma db object(int_base) > > #pragma db value(int_base::Item); // This will work, int_base::Item is > // an instantiation. > > Boris > From boris at codesynthesis.com Wed Aug 13 09:06:57 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 13 09:12:18 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> Message-ID: Hi Michael, Michael Powell writes: > >> typedef std::pair Item; > >> #pragma db value(Item) > > If you stop and think about how preprocessor and compile time > (template) issues are resolved, this makes perfect sense. ODB does not > have enough information to preprocess the type at that time. Well, what ODB could have done is "assign" the value pragma to the Item template (becomes a "pragma template", in a sense). Then, when it is instantiated (i.e., the outer class template is instantiated), apply this pragma to the instantiated Item. Of course, this is the level of complexity that I would prefer to avoid ;-). Boris From murray.wilson at gmail.com Fri Aug 15 19:48:49 2014 From: murray.wilson at gmail.com (Murray Wilson) Date: Fri Aug 15 19:48:57 2014 Subject: [odb-users] Attempting to create an index on an inverse pointer crashes compiler instead of producing an error Message-ID: Attempting to precompile this erroneous header with odb: PRAGMA_DB(object table("device") polymorphic) class Device : public LockableDatabaseMessage { PRAGMA_DB(value_not_null inverse(deviceList)) lazy_weak_ptr room; PRAGMA_DB(index("fk_room") members(room)) }; will crash the compiler with this error: cc1plus: ../odb/relational/model.hxx:432: virtual void relational::model::object_indexes::traverse(cutl::compiler::traverser_impl::type&): Assertion `c != 0' failed. *** WARNING *** there are active plugins, do not report this as a bug unless you can reproduce it without enabling any plugins. Event | Plugins PLUGIN_START_UNIT | odb PLUGIN_PRAGMAS | odb PLUGIN_OVERRIDE_GATE | odb In file included from :8:0: /usr/local/include/odb/tr1/pointer-traits.hxx: In destructor ?virtual boost::exception_detail::clone_base::~clone_base()?: /usr/local/include/odb/tr1/pointer-traits.hxx:116:1: internal compiler error: Aborted Please submit a full bug report, with preprocessed source if appropriate. See for instructions. instead of pointing out that you can not create an index where there is no column in the table to create it on. From philip.ethier at gmail.com Fri Aug 15 15:41:35 2014 From: philip.ethier at gmail.com (Philip Ethier) Date: Sat Aug 16 08:03:02 2014 Subject: [odb-users] Altering column from integer to double precision In-Reply-To: References: Message-ID: Thanks Boris. I got this working my way using the manual scripts that I wrote. But then I had an issue with an in code migration. I was trying to use the void schema_version_migration() function to set my version, but it doesn't seem to be persisting even though no exceptions are thrown. Do I have to wrap in a transaction? Any other ideas? Thanks again, On Aug 13, 2014 7:27 AM, "Boris Kolpackov" wrote: > Hi Philip, > > Philip Ethier writes: > > > So I came up with the following approach, do you think it will work > > correctly? > > > > 1 remove the int member var, odb compile with updated version > > 2 add the double member var, odb compile with updated version > > 3 write manual alter sql to change the column type from int to double > > precision > > 4 SQL to update the schema_version version column to the latest > > 5 start the program, and make sure to not run the pre and post migration > sql > > I "think" this will work. > > Generally, when it comes to database schema evolution, I believe your > changes should be in the "obviously will work" category rather than > "think will work". Otherwise this stuff will quickly get out of hand. > Which brings us to your next questions: > > > > Is this the recommended way to do the alter? > > No, this is definitely not the recommended way ;-). You are half way > relying on ODB and half way doing your custom migration. > > The way I would implement this is like this: > > 1. Increment the model version. > > 2. Soft-delete the int member variable in this version (you can rename > it also but keep its column name the same; db column pragma) > > 3. Soft-add the double member variable in this version (you can use > the old var's name but make sure to give it a new column name). > > 4. Register data migration function that converts int's to double's. > > While this may not be as efficient (we have to load all the int's > and store all the double's) or "seamless" (we will end up with a > new column name), it is simple to the point that you can trust > it will actually do what you think it should. > > You can read more about soft-add/delete in Section 13.4, "Soft Object > Model Changes" in the ODB manual. > > Boris > From ravil.nugmanov1 at ge.com Fri Aug 15 17:40:36 2014 From: ravil.nugmanov1 at ge.com (Nugmanov, Ravil (GE Energy Management)) Date: Sat Aug 16 08:03:03 2014 Subject: [odb-users] odb question Message-ID: <5F5CAC3EF988AA4383A0BD41B702AEBB6B1712@ALPURAPA27.e2k.ad.ge.com> Hello, I am evaluating your product ODB, and have couple of questions. Looking at the examples, I can see that the type of data base (MSQ SQL or MySQL for example) should be selected before compilation, using preprocessor definition. So there is no way to build the application once, and then select data base at runtime, correct? Looks like that separate binaries must be built for each target database, correct? Second question is about automatic creation of tables in the database. When I started the c++11-mssql-vc11 project, I was expecting that it would create tables in the database automatically. But that did not happen. So tables should be created before running this test, there is no support for automatic table creation, right? Thank you, Ravil Unsubscribe from our commercial electronic messages. http://supportcentral.ge.com/esurvey/takesurvey.asp?p=17778&d=3834102 D?sabonner de nos messages ?lectroniques commerciaux. http://supportcentral.ge.com/esurvey/takesurvey.asp?p=17778&d=3839563 From boris at codesynthesis.com Sat Aug 16 08:07:10 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sat Aug 16 08:12:30 2014 Subject: [odb-users] odb question In-Reply-To: <5F5CAC3EF988AA4383A0BD41B702AEBB6B1712@ALPURAPA27.e2k.ad.ge.com> References: <5F5CAC3EF988AA4383A0BD41B702AEBB6B1712@ALPURAPA27.e2k.ad.ge.com> Message-ID: Hi Ravil, Nugmanov, Ravil (GE Energy Management) writes: > Looking at the examples, I can see that the type of data base (MSQ SQL > or MySQL for example) should be selected before compilation, using > preprocessor definition. So there is no way to build the application > once, and then select data base at runtime, correct? Looks like that > separate binaries must be built for each target database, correct? There is multi-database support. You can even load support code for a particular database dynamically. The examples do it this way (i.e. compile-time, single-database support) for simplicity. For details, see Section 16, "Multi-Database Support" in the ODB manual. > Second question is about automatic creation of tables in the database. > When I started the c++11-mssql-vc11 project, I was expecting that it > would create tables in the database automatically. But that did not > happen. So tables should be created before running this test, there > is no support for automatic table creation, right? There is support for automatic table creation. ODB can generate the necessary DDL statements either into a separate .sql file (default for client-server databases such as SQL Server) or embedded into the generated C++ code (default for embedded databases such as SQLite). See Section 3.4, "Database" in the ODB manual for details. What's more, ODB also supports automatic database schema evolution, not only creation. That functionality is described in Chapter 13. Boris From boris at codesynthesis.com Sat Aug 16 08:13:27 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sat Aug 16 08:18:47 2014 Subject: [odb-users] Altering column from integer to double precision In-Reply-To: References: Message-ID: Hi Philip, Philip Ethier writes: > I was trying to use the void schema_version_migration() function to set > my version, but it doesn't seem to be persisting even though no exceptions > are thrown. The schema_version_migration() modifier does not persist anything. It simply stores the version in the odb::::database instance so that it can be used by the generated code during the execution of the application. Quoting Section 12.2: "You may already have a version table in your database or you (or your database administrator) may prefer to keep track of versions your own way. You can instruct ODB not to create the schema_version table with the --suppress-schema-version option. However, ODB still needs to know the current database version in order for certain schema evolution mechanisms to function properly. As a result, in this case, you will need to set the schema version on the database instance manually using the schema_version_migration() modifier." The version and the migration flags are only "persisted" by the pre- and post-schema migration scripts. Which means that if you run your own custom script instead, then you have to update the version as well. Boris From philip.ethier at gmail.com Sat Aug 16 15:39:29 2014 From: philip.ethier at gmail.com (Philip Ethier) Date: Mon Aug 18 06:26:15 2014 Subject: [odb-users] Altering column from integer to double precision In-Reply-To: References: Message-ID: Alright, thanks for the reply Boris. On Aug 16, 2014 7:18 AM, "Boris Kolpackov" wrote: > Hi Philip, > > Philip Ethier writes: > > > I was trying to use the void schema_version_migration() function to set > > my version, but it doesn't seem to be persisting even though no > exceptions > > are thrown. > > The schema_version_migration() modifier does not persist anything. It > simply stores the version in the odb::::database instance so that > it can be used by the generated code during the execution of the > application. Quoting Section 12.2: > > "You may already have a version table in your database or you (or your > database administrator) may prefer to keep track of versions your own > way. You can instruct ODB not to create the schema_version table with the > --suppress-schema-version option. However, ODB still needs to know the > current database version in order for certain schema evolution mechanisms > to > function properly. As a result, in this case, you will need to set the > schema > version on the database instance manually using the > schema_version_migration() modifier." > > The version and the migration flags are only "persisted" by the pre- and > post-schema migration scripts. Which means that if you run your own > custom script instead, then you have to update the version as well. > > Boris > From marcos.glez at gmail.com Sun Aug 17 05:25:28 2014 From: marcos.glez at gmail.com (Marcos Gonzalez Menendez) Date: Mon Aug 18 06:26:15 2014 Subject: [odb-users] Question about packaging the generated code for each database into a separate dynamic-link library Message-ID: Hi, I'm following the steps that are described in the manual for packaging the generated code into separate dll's. Following the example that is explained in the manual, odb.exe has already yielded: - person-odb.* - person-odb-pgsql.* - person-odb-sqlite.* The problem is that I would need a better explanation about the following manual paragraph: "The second step in packaging the generated code into DLLs is to decide where to place the gener- ated common interface code. One option is to place it into a DLL of its own so that we will end up with (replace *.dll with lib*.so for Unix): person.dll plus person-sqlite.dll and person-pgsql.dll, which both link to person.dll, as well as person.exe, which links to person.dll and dynamically loads person-sqlite.dll and/or person-pgsql.dll. If this is the organization that you prefer, then the next step is to build all the DLLs as you normally would any other DLL, placing person-odb.cxx and person.cxx into person.dll, person-odb-sqlite.cxx into person-sqlite.dll, etc. Note that in the pure dynamic multi-database support, person-sqlite.dll and person-pgsql.dll do not export any symbols." I have the followind doubts: - Does person.dll contain only person-odb.* code? - Does person.dll export any symbol? - Does person-sqlite.dll contain only person-odb-sqlite.* code? - Does person-sqlite.dll export any symbol? - Does person-sqlite.dll ling to person.dll? - Does person.exe need a LoadLibrary call for loading person-sqlite.dll? Coudl you give me an example of this? Thanks in advance for any help you can provide -- Marcos Gonz?lez Men?ndez From boris at codesynthesis.com Mon Aug 18 06:41:01 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Aug 18 06:46:21 2014 Subject: [odb-users] Attempting to create an index on an inverse pointer crashes compiler instead of producing an error In-Reply-To: References: Message-ID: Hi Murray, Murray Wilson writes: > instead of pointing out that you can not create an index where there is no > column in the table to create it on. Fixed, thanks for reporting this! http://scm.codesynthesis.com/?p=odb/odb.git;a=commit;h=8d066b8a07f45c517b6f8256eb4e4adbff3709a4 Boris From boris at codesynthesis.com Mon Aug 18 07:03:13 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Aug 18 07:08:34 2014 Subject: [odb-users] Question about packaging the generated code for each database into a separate dynamic-link library In-Reply-To: References: Message-ID: Hi Marcos, Marcos Gonzalez Menendez writes: > I have the followind doubts: I am kind of surprised since the above paragraph answers all (well, most of) these questions directly: > - Does person.dll contain only person-odb.* code? Yes: "placing person-odb.cxx and person.cxx into person.dll" > - Does person.dll export any symbol? Yes, your executable will use the API provided by person.hxx and person-odb.hxx, so you have to export their symbols. > - Does person-sqlite.dll contain only person-odb-sqlite.* code? Yes: "placing [...], person-odb-sqlite.cxx into person-sqlite.dll" > - Does person-sqlite.dll export any symbol? It depends: "Note that in the pure dynamic multi-database support, person-sqlite.dll and person-pgsql.dll do not export any symbols." So, if you don't need to "drop down" to static SQLite API, then you don't need to export any symbols from this DLL. > - Does person-sqlite.dll ling to person.dll? Yes: "... person-sqlite.dll and person-pgsql.dll, which both link to person.dll" > - Does person.exe need a LoadLibrary call for loading person-sqlite.dll? Yes. > Coudl you give me an example of this? There is an internal test that we use to test various multi-database setups. You can use it as a reference though note that it has some extra macros that select a particular configuration that you won't need (and that may make undestanding what's going on a bit trciky). The ODB command lines that were used to generate the *-odb files are in the README file. http://codesynthesis.com/~boris/tmp/odb/multi-db.zip Boris From ravil.nugmanov1 at ge.com Wed Aug 20 12:00:33 2014 From: ravil.nugmanov1 at ge.com (Nugmanov, Ravil (GE Energy Management)) Date: Wed Aug 20 12:52:45 2014 Subject: [odb-users] odb question In-Reply-To: References: <5F5CAC3EF988AA4383A0BD41B702AEBB6B1712@ALPURAPA27.e2k.ad.ge.com> Message-ID: <5F5CAC3EF988AA4383A0BD41B702AEBB6B17BA@ALPURAPA27.e2k.ad.ge.com> Hi Boris, Thank you for the response! With your help and after some more research now I have better understanding of ODB features, particularly how to create database tables automatically. I like how organized and how it works, looks very attractive for me. One more question - do you have any metrics for performance, how fast is it? Thank you, Ravil -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Saturday, August 16, 2014 6:07 AM To: Nugmanov, Ravil (GE Energy Management) Cc: odb-users@codesynthesis.com Subject: Re: [odb-users] odb question Hi Ravil, Nugmanov, Ravil (GE Energy Management) writes: > Looking at the examples, I can see that the type of data base (MSQ SQL > or MySQL for example) should be selected before compilation, using > preprocessor definition. So there is no way to build the application > once, and then select data base at runtime, correct? Looks like that > separate binaries must be built for each target database, correct? There is multi-database support. You can even load support code for a particular database dynamically. The examples do it this way (i.e. compile-time, single-database support) for simplicity. For details, see Section 16, "Multi-Database Support" in the ODB manual. > Second question is about automatic creation of tables in the database. > When I started the c++11-mssql-vc11 project, I was expecting that it > would create tables in the database automatically. But that did not > happen. So tables should be created before running this test, there is > no support for automatic table creation, right? There is support for automatic table creation. ODB can generate the necessary DDL statements either into a separate .sql file (default for client-server databases such as SQL Server) or embedded into the generated C++ code (default for embedded databases such as SQLite). See Section 3.4, "Database" in the ODB manual for details. What's more, ODB also supports automatic database schema evolution, not only creation. That functionality is described in Chapter 13. Boris Unsubscribe from our commercial electronic messages. http://supportcentral.ge.com/esurvey/takesurvey.asp?p=17778&d=3834102 D?sabonner de nos messages ?lectroniques commerciaux. http://supportcentral.ge.com/esurvey/takesurvey.asp?p=17778&d=3839563 From boris at codesynthesis.com Wed Aug 20 12:57:35 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 20 13:02:55 2014 Subject: [odb-users] odb question In-Reply-To: <5F5CAC3EF988AA4383A0BD41B702AEBB6B17BA@ALPURAPA27.e2k.ad.ge.com> References: <5F5CAC3EF988AA4383A0BD41B702AEBB6B1712@ALPURAPA27.e2k.ad.ge.com> <5F5CAC3EF988AA4383A0BD41B702AEBB6B17BA@ALPURAPA27.e2k.ad.ge.com> Message-ID: Hi Ravil, Nugmanov, Ravil (GE Energy Management) writes: > One more question - do you have any metrics for performance, how fast is it? ODB was designed from grounds up with performance in mind. It uses prepared statements throughout and caches connections, statements, and even memory buffers. It also includes a lot of performance- oriented features like lazy pointers, sections, change-tracking containers, session (object cache), etc. As an anecdotal evidence, I had a couple of people "complaining" that ODB is faster than their hand-written code that uses the database API directly. Boris From boris at codesynthesis.com Thu Aug 21 03:49:28 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Aug 21 03:54:48 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: <089d384f227440668d451f18d527777d@QEX.qosmotec.com> References: <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> <089d384f227440668d451f18d527777d@QEX.qosmotec.com> Message-ID: Hi Marcel, [I've CC'ed odb-users since others may find this information useful.] Marcel Nehring writes: > But I have indeed discovered a few other issues/questions this morning. > > 1) Trying to compile the generated ODB code gives me a C2380 error with > Visual Studio. To me it looks like that this might be because I have a value > type declared that has a member called value. If I then define a class that > has a member of type of this value type that is also named value, then the > resulting struct in the ODB code is called value_type_ and inside this > struct there is a typedef that is also called value_type_. Uh, you are really pushing ODB, I like that ;-). I've fixed this, let me know if you would like the updated ODB compiler binary. > 2) Is it somehow possible to store different classes in the same > database table? For example for a certain template class I would > like to store all of its instantiations in a single table. Yes, you can map multiple classes to the same table: #pragma db object table("foo") class foo { ... }; #pragma db object table("foo") class bar { ... }; ODB just assumes you know what you are doing ;-). > I would be able to figure out the correct template instantiation that > is needed when reading the row from the database by one of the columns > value. Just to clarify, "you" here is literally "you", not ODB. You will need to somehow figure out the correct class to use before, say, calling load(). You could, for example, use a view to first load the column value and then based on that, load the correct object. You might also want to take a look at object sections (Chapter 9). They allow you to partition a class into multiple separately loadable, updatable, etc., groups of data members. Maybe this is what you are looking for. Also polymorphism might be related (Section 8.2). > 3) I cannot specify different output directories for the different > types (*.hxx, *.sql, etc.) of generated files, can I? No, but you can always move the files where you need to afterwards with a few shell commands. > 4) I cannot specify different include prefixes for my own header files > and odb's header files, can I? For example that it results in #include > "inc/MyClass.h" and #include "gen/odb/MyClass-odb.h". At the moment I > do this by using the include-regex option. --include-regex is the way to do it. There is no special mechanism to separate headers into "your own" and "odb's". Boris From marcos.glez at gmail.com Fri Aug 22 12:38:57 2014 From: marcos.glez at gmail.com (Marcos Gonzalez Menendez) Date: Sat Aug 23 05:03:24 2014 Subject: [odb-users] Question about packaging the generated code for each database into a separate dynamic-link library In-Reply-To: References: Message-ID: Thanks a lot for your help. I'll try to adapt the example to my needs. Marcos 2014-08-18 13:03 GMT+02:00 Boris Kolpackov : > Hi Marcos, > > Marcos Gonzalez Menendez writes: > > > I have the followind doubts: > > I am kind of surprised since the above paragraph answers all (well, > most of) these questions directly: > > > > - Does person.dll contain only person-odb.* code? > > Yes: "placing person-odb.cxx and person.cxx into person.dll" > > > > - Does person.dll export any symbol? > > Yes, your executable will use the API provided by person.hxx and > person-odb.hxx, so you have to export their symbols. > > > > - Does person-sqlite.dll contain only person-odb-sqlite.* code? > > Yes: "placing [...], person-odb-sqlite.cxx into person-sqlite.dll" > > > > - Does person-sqlite.dll export any symbol? > > It depends: "Note that in the pure dynamic multi-database support, > person-sqlite.dll and person-pgsql.dll do not export any symbols." > So, if you don't need to "drop down" to static SQLite API, then > you don't need to export any symbols from this DLL. > > > > - Does person-sqlite.dll ling to person.dll? > > Yes: "... person-sqlite.dll and person-pgsql.dll, which both link to > person.dll" > > > > - Does person.exe need a LoadLibrary call for loading person-sqlite.dll? > > Yes. > > > > Coudl you give me an example of this? > > There is an internal test that we use to test various multi-database > setups. You can use it as a reference though note that it has some > extra macros that select a particular configuration that you won't > need (and that may make undestanding what's going on a bit trciky). > The ODB command lines that were used to generate the *-odb files > are in the README file. > > http://codesynthesis.com/~boris/tmp/odb/multi-db.zip > > Boris > -- Marcos Gonz?lez Men?ndez From marcos.glez at gmail.com Fri Aug 22 13:00:24 2014 From: marcos.glez at gmail.com (Marcos Gonzalez Menendez) Date: Sat Aug 23 05:03:24 2014 Subject: [odb-users] Specific index creation for a container table column Message-ID: Hi, I'm struggling with the way of creating an index for a particular column. The table is not a "db object" itself, because it's rather the table that is created by ODB when an container is used: Here is my example: #pragma db object class B { public: #pragma db id int id_; int prop_; }; #pragma db object class A { public: #pragma db auto id odbid id_; QList> ref_list_; #pragma db index member(ref_list_.id) }; As I'm using sqlite, the ddl produced is like this: CREATE TABLE "A" ( "id" INTEGER NULL PRIMARY KEY AUTOINCREMENT); CREATE TABLE "B" ( "id" INTEGER NULL PRIMARY KEY, "prop" INTEGER NULL); CREATE TABLE "A_ref_list" ( "object_id" INTEGER NULL, "index" INTEGER NULL, "value" INTEGER NULL, CONSTRAINT "object_id_fk" FOREIGN KEY ("object_id") REFERENCES "A" ("id") ON DELETE CASCADE, CONSTRAINT "value_fk" FOREIGN KEY ("value") REFERENCES "B" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE INDEX "A_ref_list_object_id_i" ON "A_ref_list" ("object_id"); CREATE INDEX "A_ref_list_index_i" ON "A_ref_list" ("index"); Now I would like to have an index for A_ref_list.value but the sentece: #pragma db index member(ref_list_.id) does not seem to be the right one. In fact is an index for the FOREIGN KEY Is it possible to do this with ODB? Thanks for any help you can provide -- Marcos Gonz?lez Men?ndez From boris at codesynthesis.com Sat Aug 23 05:22:07 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sat Aug 23 05:28:07 2014 Subject: [odb-users] Specific index creation for a container table column In-Reply-To: References: Message-ID: Hi Marcos, Marcos Gonzalez Menendez writes: > Now I would like to have an index for A_ref_list.value but the sentece: > > #pragma db index member(ref_list_.id) > > does not seem to be the right one. I am sure you meant that this doesn't work: #pragma db index member(ref_list_.value) This is indeed not yet supported by ODB so for the time being you will have to define the index manually via SQL. But this is on our TODO list so it will be supported at some point. Boris From iensoreus at gmail.com Mon Aug 25 18:30:29 2014 From: iensoreus at gmail.com (Philipp Maluta) Date: Tue Aug 26 04:26:18 2014 Subject: [odb-users] Full text search in SQLite Message-ID: Hello, CodeSynthesis! Is there a some way to turn on the subj. Suppose there is no particular pragma but maybe I can intrude to the table creation process and crewe a virtual table like CREATE VIRTUAL TABLE data USING fts3(); or so? Or maybe there is another way to achieve Full text search for Sqlite? Thank you anyway. All your job already done is really great! Philipp From boris at codesynthesis.com Tue Aug 26 04:39:00 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Aug 26 04:45:00 2014 Subject: [odb-users] Full text search in SQLite In-Reply-To: References: Message-ID: Hi Philipp, Philipp Maluta writes: > Suppose there is no particular pragma but maybe I can intrude to the > table creation process and crewe a virtual table like > > CREATE VIRTUAL TABLE data USING fts3(); ODB doesn't know anything about SQLite virtual tables or the FTS extension (yet; maybe we will support this directly in the future). So, yes, the way you can achieve what you want is by creating this table yourself manually. Assuming you are using the embedded database schema, here are the steps that you can take: 1. Place the class that you want to map to the FTS table into a separate header file (say data.hxx): #pragma db object table("data") no_id class data { std::string content; }; Note that here we have a persistent class without object id. You could probably also map the implicit rowid column to object id if you wanted to. 2. Compile this header without the --generate-schema option. This way the ODB generated code won't try to create the 'data' table. 3. In your application create the data FTS table manually: { odb::transaction t (db->begin ()); // Create the standard tables. // odb::schema_catalog::create_schema (*db); // Create the FTS table manually. // db->execute ("CREATE VIRTUAL TABLE data USING fts3()"); t.commit (); } Let me know if there are any issues. Boris From armz4pxq at gmail.com Tue Aug 26 19:37:45 2014 From: armz4pxq at gmail.com (Dan Man) Date: Wed Aug 27 02:57:51 2014 Subject: [odb-users] Is it possible to persist template classes? Message-ID: Hi Boris, I was wondering if I can persist template classes. If yes, where would I find an example? Thanks, Dan From boris at codesynthesis.com Wed Aug 27 04:53:01 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Aug 27 04:59:02 2014 Subject: [odb-users] Is it possible to persist template classes? In-Reply-To: References: Message-ID: Hi Dan, Dan Man writes: > I was wondering if I can persist template classes. Yes, they are mapped to template tables ;-). Just kidding. ODB does not support persisting class templates but it does support making persistent objects out of class templates instantiations. Or more precisely, it will support in the next version but this functionality is already available in the pre-release form. For more information on how it works (and the limitations) you can read this recent thread: http://codesynthesis.com/pipermail/odb-users/2014-July/001987.html And it continues: http://codesynthesis.com/pipermail/odb-users/2014-August/001994.html Let me know if you would like a pre-release for another platform. Boris From mne at qosmotec.com Thu Aug 28 07:23:32 2014 From: mne at qosmotec.com (Marcel Nehring) Date: Thu Aug 28 07:24:15 2014 Subject: AW: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> <089d384f227440668d451f18d527777d@QEX.qosmotec.com> Message-ID: Hi Boris, the reason for why I asked if it is possible to store different classes in the same table is that to me it looked like that it is not possible. Let's say I have two classes with two members each. One of these members is "the same" in both classes i.e. I want them to be mapped to the same column. The other member should be mapped to different columns. So that if I persist one of the classes it will use two of the table's columns and set the other one to null. In my specific case we are talking about the same template class with different template parameters/members. However, ODB does only generate the DDL for one of the classes. So in my example I would have a table with two instead of three columns. So when you said it works, did you mean it works if I generate the table by hand? Unfortunately there is another thing I could not solve myself. ODB supports C++11 enum classes, but when I try to compile code that uses them I get a compile error. That is because in traits.hxx in big_int_value_traits::set_value ODB tries to assign the value 0 to an instance of my enum class. But implicit conversions are illegal for enum classes. Searching the documentation for enum class I could not find any special treatment that is necessary to persist members of an enum class type. What am I missing here? Thanks, Marcel -----Urspr?ngliche Nachricht----- Von: Boris Kolpackov [mailto:boris@codesynthesis.com] Gesendet: Donnerstag, 21. August 2014 09:49 An: Marcel Nehring Cc: odb-users@codesynthesis.com Betreff: Re: [odb-users] reuse inheritance with templated base class Hi Marcel, [I've CC'ed odb-users since others may find this information useful.] Marcel Nehring writes: > But I have indeed discovered a few other issues/questions this morning. > > 1) Trying to compile the generated ODB code gives me a C2380 error > with Visual Studio. To me it looks like that this might be because I > have a value type declared that has a member called value. If I then > define a class that has a member of type of this value type that is > also named value, then the resulting struct in the ODB code is called > value_type_ and inside this struct there is a typedef that is also called value_type_. Uh, you are really pushing ODB, I like that ;-). I've fixed this, let me know if you would like the updated ODB compiler binary. > 2) Is it somehow possible to store different classes in the same > database table? For example for a certain template class I would like > to store all of its instantiations in a single table. Yes, you can map multiple classes to the same table: #pragma db object table("foo") class foo { ... }; #pragma db object table("foo") class bar { ... }; ODB just assumes you know what you are doing ;-). > I would be able to figure out the correct template instantiation that > is needed when reading the row from the database by one of the columns > value. Just to clarify, "you" here is literally "you", not ODB. You will need to somehow figure out the correct class to use before, say, calling load(). You could, for example, use a view to first load the column value and then based on that, load the correct object. You might also want to take a look at object sections (Chapter 9). They allow you to partition a class into multiple separately loadable, updatable, etc., groups of data members. Maybe this is what you are looking for. Also polymorphism might be related (Section 8.2). > 3) I cannot specify different output directories for the different > types (*.hxx, *.sql, etc.) of generated files, can I? No, but you can always move the files where you need to afterwards with a few shell commands. > 4) I cannot specify different include prefixes for my own header files > and odb's header files, can I? For example that it results in #include > "inc/MyClass.h" and #include "gen/odb/MyClass-odb.h". At the moment I > do this by using the include-regex option. --include-regex is the way to do it. There is no special mechanism to separate headers into "your own" and "odb's". Boris From quentindeldycke at gmail.com Wed Aug 27 05:34:30 2014 From: quentindeldycke at gmail.com (Quentin Deldycke) Date: Thu Aug 28 08:48:28 2014 Subject: [odb-users] Optimistic mode doesn't work for multiple select? (while another process update data) Message-ID: Hi, I would like some precision about the Optimistic mode... I have a process A who query every 10 seconds on the database. Let's say one entry having data 'ABCD' During the same time, a process (B) updates the value to 'EFGH'. (a mysql client show me that data is correctly commited) A need to reset the transaction between each query or it will continue to pull data 'ABCD'... Does Optimistic mode only work for update query? Do i have other choices than reseting the transaction at every query of A? Thanks -- Deldycke Quentin From boris at codesynthesis.com Thu Aug 28 08:53:53 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Aug 28 08:59:53 2014 Subject: [odb-users] Optimistic mode doesn't work for multiple select? (while another process update data) In-Reply-To: References: Message-ID: Hi Quentin, Quentin Deldycke writes: > I have a process A who query every 10 seconds on the database. Let's say > one entry having data 'ABCD' > > During the same time, a process (B) updates the value to 'EFGH'. (a mysql > client show me that data is correctly commited) > > A need to reset the transaction between each query or it will continue to > pull data 'ABCD'... I am not 100% sure what you mean by resetting the transaction but I suspect you have one long-running transaction that queries the database every 10 second. In that case, it is the expected behavior that you don't see changes made by other transactions running in parallel (the 'I' part in 'ACID'). In fact, I would expect your UPDATE transaction to block until this one is committed. The solution is not to have a long-lived transaction (i.e., start the transaction, query the database, and end the transaction). If this is not the setup that you have, then please show the code for both transactions. Boris From quentindeldycke at gmail.com Thu Aug 28 11:11:17 2014 From: quentindeldycke at gmail.com (Quentin Deldycke) Date: Thu Aug 28 11:11:23 2014 Subject: [odb-users] Optimistic mode doesn't work for multiple select? (while another process update data) In-Reply-To: References: Message-ID: Thanks for your help! I modified a bit my code to work as you suggested: "start the transaction, query the database, and end the transaction". Even if the architecture force me to be a bit more like: "end the transaction if one is open, start the transaction, query the database". The actual architecture is a bit complicated, and i took time to see if this wouldn't impact everything. But it seems everything is ok. Sadly it is not as optimised as i would like... Anyway, it is now working! -- Deldycke Quentin On 28 August 2014 14:53, Boris Kolpackov wrote: > Hi Quentin, > > Quentin Deldycke writes: > > > I have a process A who query every 10 seconds on the database. Let's say > > one entry having data 'ABCD' > > > > During the same time, a process (B) updates the value to 'EFGH'. (a mysql > > client show me that data is correctly commited) > > > > A need to reset the transaction between each query or it will continue to > > pull data 'ABCD'... > > I am not 100% sure what you mean by resetting the transaction but I > suspect you have one long-running transaction that queries the database > every 10 second. In that case, it is the expected behavior that you don't > see changes made by other transactions running in parallel (the 'I' part > in 'ACID'). In fact, I would expect your UPDATE transaction to block until > this one is committed. > > The solution is not to have a long-lived transaction (i.e., start the > transaction, query the database, and end the transaction). > > If this is not the setup that you have, then please show the code for > both transactions. > > Boris > From timo at rothenpieler.org Thu Aug 28 12:29:59 2014 From: timo at rothenpieler.org (Timo Rothenpieler) Date: Thu Aug 28 12:30:13 2014 Subject: [odb-users] CMake FindModule for ODB Message-ID: <53FF5907.3080401@rothenpieler.org> Hello, I was in need of a CMake module for ODB, but didn't find the existing ones sufficient, as they completely lack any functionality to locate the odb libraries and headers. So i wrote one, loosely based on the existing one from the wiki. As this might be usefull for other people, i uploaded it, together with an example, to my Github: https://github.com/BtbN/OdbCmake A short documentation on the variables the find module defines is in the header of the Find module: https://github.com/BtbN/OdbCmake/blob/master/cmake/Modules/FindODB.cmake To use it, all that needs to be done is: find_package(ODB REQUIRED COMPONENTS qt OPTIONAL_COMPONENTS mysql sqlite) include(${ODB_USE_FILE}) After that it sets OSB_QT_FOUND, ODB_MYSQL_FOUND and ODB_SQLITE_FOUND to true, if it found the said components. ODB_LIBRARIES contains all neccessary libs for the requested and found components, ODB_INCLUDE_DIRS the include directories. Those are also defined for each requested component and for the libodb core library in individual variables. The UseODB file defines the odb_compile function, which takes headers as input and calls the odb cli util on them to create the odb code. It appends the list of generated sources that need compiling to the variable it got as its fist argument. See the example CMakeLists.txt for an example on how to use it: https://github.com/BtbN/OdbCmake/blob/master/CMakeLists.txt Regards, Timo -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: OpenPGP digital signature Url : http://codesynthesis.com/pipermail/odb-users/attachments/20140828/8cc998cc/signature.pgp From boris at codesynthesis.com Fri Aug 29 04:47:22 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Aug 29 04:53:23 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> <089d384f227440668d451f18d527777d@QEX.qosmotec.com> Message-ID: Hi Marcel, Marcel Nehring writes: > Let's say I have two classes with two members each. One of these members is > "the same" in both classes i.e. I want them to be mapped to the same > column. The other member should be mapped to different columns. So that if I > persist one of the classes it will use two of the table's columns and set > the other one to null. In my specific case we are talking about the same > template class with different template parameters/members. However, ODB > does only generate the DDL for one of the classes. So in my example I would > have a table with two instead of three columns. So when you said it works, > did you mean it works if I generate the table by hand? If ODB sees two or more classes mapped to the same table and you asked it to generate the schema, it simply generates the schema based on the first class and ignores all the others. This suggests that one way to make this work would be to provide the first (perhaps dummy) class with all the data members that you want in the database. For example: // Dummy "schema-producing" class for a and b below. // #pragma db object table("ab") struct ab_schema { int common; #pragma db null int only_in_a; #pragma db null int only_in_b; }; #pragma db object table("ab") class a { int common; int only_in_a; }; #pragma db object table("ab") class b { int common; int only_in_b; }; You could even place it into a separate header and then discard its generated code. You just need to make sure that it is included before the other two during ODB compilation when you generate the schema. > Unfortunately there is another thing I could not solve myself. ODB > supports C++11 enum classes, but when I try to compile code that uses > them I get a compile error. That is because in traits.hxx in > big_int_value_traits::set_value ODB tries to assign the value 0 to > an instance of my enum class. But implicit conversions are illegal > for enum classes. Yes, this is a bug. These statements: v = 0; Should be replaced with: v = T (); I've applied the fix in the repository. Let me know if you want me to send you trait.hxx or libodb-oracle. It is probably easiest for you to just change the affected lines directly. Boris From boris at codesynthesis.com Fri Aug 29 05:03:15 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Aug 29 05:09:15 2014 Subject: [odb-users] CMake FindModule for ODB In-Reply-To: <53FF5907.3080401@rothenpieler.org> References: <53FF5907.3080401@rothenpieler.org> Message-ID: Hi Timo, Timo Rothenpieler writes: > As this might be usefull for other people, i uploaded it, together with > an example, to my Github: Great stuff, thanks for sharing! I've added a link to your post in the ODB CMake page: http://wiki.codesynthesis.com/Using_ODB_with_CMake Boris From mne at qosmotec.com Fri Aug 29 05:32:07 2014 From: mne at qosmotec.com (Marcel Nehring) Date: Fri Aug 29 05:33:07 2014 Subject: AW: [odb-users] reuse inheritance with templated base class In-Reply-To: References: <06f186deb62f49e5a19c2669702b6bbb@QEX.qosmotec.com> <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> <089d384f227440668d451f18d527777d@QEX.qosmotec.com> Message-ID: <81ce9bea3acf4494ab09faab9dbec18b@QEX.qosmotec.com> Hi Boris, thanks for elaborating on the matter. Thanks for the bug fix, too. I changed traits.hxx as you suggested and it works now. Unfortunately I ran into another problem. Do I have to take special care when using a member which is mapped to a column of type BLOB when using it with a polymorphic base class? The example code I added below is giving me a compile error stating that "struct 'odb::access::object_traits_impl::image_type'" has no applicable copy-constructor. Without the polymorphic base it compiles. Thanks, Marcel ###### #include #pragma db object polymorphic class Base { public: #pragma db id auto int id; virtual void foo() const = 0; }; #pragma db object class Derived : public Base { public: #pragma db type("BLOB") std::vector m_payload; }; From boris at codesynthesis.com Fri Aug 29 06:30:50 2014 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Aug 29 06:37:05 2014 Subject: [odb-users] reuse inheritance with templated base class In-Reply-To: <81ce9bea3acf4494ab09faab9dbec18b@QEX.qosmotec.com> References: <61a35a1db7ff450ab707cf56048d7462@QEX.qosmotec.com> <66093049aafb486eb267e206b2481baa@QEX.qosmotec.com> <089d384f227440668d451f18d527777d@QEX.qosmotec.com> <81ce9bea3acf4494ab09faab9dbec18b@QEX.qosmotec.com> Message-ID: Hi Marcel, Marcel Nehring writes: > The example code I added below is giving me a compile error stating that > "struct 'odb::access::object_traits_impl::image_type'" > has no applicable copy-constructor. Without the polymorphic base it compiles. Yes, another bug. I think by now you have reported more bugs than anyone else. Thanks, much appreciated! I've fixed it and uploaded the new ODB compiler binary: http://codesynthesis.com/~boris/tmp/odb/pre-release/odb-2.4.0.a3-i686-windows.zip Let me know if you find anything else. Boris From timo at rothenpieler.org Sat Aug 30 11:24:58 2014 From: timo at rothenpieler.org (Timo Rothenpieler) Date: Sat Aug 30 11:25:15 2014 Subject: [odb-users] Gentoo ebuilds and overlay Message-ID: <5401ECCA.7000206@rothenpieler.org> I updated the old odb 2.2.0 gentoo ebuilds to the current versions and put them into an overlay: https://git.btbn.de/gitweb/odb-overlay.git Also contains a layman xml file for easily adding the overlay via layman: https://git.btbn.de/gitweb/odb-overlay.git/blob/HEAD:/layman-odb.xml I'll try to keep it up to date with new versions getting released, if I miss an update, feel free to send me a mail about it. The ebuilds for libodb-mssql and the examples were removed, because it seems like the neccesary dependencies for mssql were removed from portage. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: OpenPGP digital signature Url : http://codesynthesis.com/pipermail/odb-users/attachments/20140830/112cddd7/signature.pgp From wvandoesburg at gmail.com Sun Aug 31 16:12:05 2014 From: wvandoesburg at gmail.com (WA van Doesburg) Date: Mon Sep 1 02:43:02 2014 Subject: [odb-users] =?windows-1252?q?error=3A_redefinition_of_=91bool_od?= =?windows-1252?q?b=3A=3Acreate=5Fschema?= Message-ID: <45E0E325-82AC-4E21-B1F4-1F652C5510D4@gmail.com> Hi, I?m trying to build a program using ODB 2.3.0 and SQLITE3 where each persistable class is defined in it?s own header file. I?m compiling all header files using the command: odb -d sqlite -DDATABASE_SQLITE -I../libs/libodb-boost-2.3.0 -o .. --generate-schema --generate-query --profile boost ${ODB_HEADERS} This results in the expected .hxx, .cxx and .ixx files. When linking my program I?m getting the error: error: redefinition of ?bool odb::create_schema the compiler is citing two different -odb.cxx files both defining this function. It seems to me that ODB generates code that creates a odb::create_schema() function for each header file. This of course results in a name clash. How can I get around this (besides using only one header file)? Wouldn?t it be better if ODB generated the create_schema() function in header specific namespaces? Best regards, ? Willem