From tony.rietwyk at rightsoft.com.au Mon Jun 6 20:02:22 2011 From: tony.rietwyk at rightsoft.com.au (Tony Rietwyk) Date: Tue Jun 7 01:19:52 2011 Subject: [odb-users] Adding support for Firebird Message-ID: Hi. I saw your announcement of the Qt profile on the Qt mailing list. I particularly like the way that ODB does the queries. How hard would it be to add support for Firebird? I don't know either MYSQL or SQLLITE. I notice that Boris has committed something about Postgres. I would be happy to help with a Firdbird port. Regards, Tony. From boris at codesynthesis.com Tue Jun 7 06:02:23 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Jun 7 03:45:52 2011 Subject: [odb-users] Adding support for Firebird In-Reply-To: References: Message-ID: Hi Tony, Tony Rietwyk writes: > I saw your announcement of the Qt profile on the Qt mailing list. I > particularly like the way that ODB does the queries. Thanks, I am glad you like it. > How hard would it be to add support for Firebird? ODB uses native C APIs to access the database in order to minimize dependencies and overhead as well as to gain access to all the available functionality. Because of this, supporting a new database requires some effort. The code is not very complex (unless the database does something very unusual) but there is quite a bit that needs to be handled. We have a high-level roadmap for adding support for a new database. I can send it to you if your are interested. > I don't know either MYSQL or SQLLITE. I notice that Boris has > committed something about Postgres. Yes, PostgreSQL support is currently in development and will be available in the next release of ODB which should be out in 3-4 weeks. > I would be happy to help with a Firdbird port. Firebird support is not in our short-term plans though we would like to have it supported at some point. This means that if you want to add Firebird support now, you will have to do most of the work yourself. Of course, we will be there to answer the questions, etc., but you will have to take the lead on this. Let me know if you would like to discuss this further. Boris From uwe.kindler at cetoni.de Thu Jun 9 07:26:54 2011 From: uwe.kindler at cetoni.de (cetoni GmbH - Uwe Kindler) Date: Fri Jun 10 02:57:10 2011 Subject: [odb-users] ODB exception problem Message-ID: <4DF0ADFE.7060205@cetoni.de> Hi, while evaluating ODB we stumbled on a serious problem catching exceptions from libodb. The following example shows the problem int main() { boost::shared_ptr db; cout << "Hello World!!!" << endl; db = boost::shared_ptr(new odb::sqlite::database( "test.db", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)); transaction t(db->begin()); try { odb::schema_catalog::create_schema (*db); } catch (odb::unknown_schema& ex) { std::cout << ex.what() << std::endl; } catch (...) { std::cout << "Exception" << std::endl; } t.commit(); return 0; } This application produces the following output: This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. Hello World!!! terminate called after throwing an instance of 'odb::unknown_schema' what(): unknown database schema '' The "Hello World!!!" message appears on stdout and the rest appares on stderr if I start the application in eclipse. If I insert the following line throw odb::unknown_schema("Test"); before odb::schema_catalog::create_schema (*db); then I get the following output: Hello World!!! unknown database schema 'Test' So it seems like it is not possible to catch exceptions thrown from libodb because normally the application should run into the first catch block because odb::schema_catalog::create_schema (*db) throws an unknown_schema exception like it happens if I insert the throw odb::unknown_schema("Test") command . This is quite strange because we use DLLs extensively and never discovered such a problem. We discovered the problem in our Qt application and I created this tiny exampleto check if it is a problem of our Qt application or if this problem occures always. Our environment: Windows 7 MinGW with GCC4.5.1 libodb configuration: ./configure --disable-static LDFLAGS="-Wl,--enable-auto-import" We have no idea what could cause this problem but ist must be something in libodb compilation or linkage because we never had any problems to throw exceptions across DLL boundaries. Any idea what goes wrong here? Thank you for any help. From boris at codesynthesis.com Fri Jun 10 05:31:01 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Jun 10 03:14:30 2011 Subject: [odb-users] ODB exception problem In-Reply-To: <4DF0ADFE.7060205@cetoni.de> References: <4DF0ADFE.7060205@cetoni.de> Message-ID: Hi Uwe, cetoni GmbH - Uwe Kindler writes: > So it seems like it is not possible to catch exceptions thrown from > libodb because normally the application should run into the first catch > block because odb::schema_catalog::create_schema (*db) throws an > unknown_schema exception like it happens if I insert the throw > odb::unknown_schema("Test") command . This is quite strange because we > use DLLs extensively and never discovered such a problem. I was quite surprised to hear that this doesn't work for you because some of our tests cause libodb to throw exceptions and these tests catch them on MinGW without any problems. I also modified one of the examples to cause libodb to throw unknown_schema and I was able to catch this exception as well. I think the problem is with your MinGW GCC toolchain (or its configuration). To run our tests, we use the GCC build that comes with ODB (in fact, the ODB Windows distribution includes a fairly complete MinGW+MSYS system in the mingw/ subdirectory; you can start the shell by running msys.bat found in this subdirectory). So one thing that you may want to try is to rebuild your code with our GCC and see if it makes a difference. If it does, then you will need to see what is different between our build of GCC and the one you are using. One potentially relevant bit of information that I found on the MinGW wiki GCCStatus page[1] is that in order for exceptions to work cross- DLL boundaries, each DLL and the executable should link to the DLL version of libgcc. Perhaps you GCC comes only with a static version or links to the static version by default. You may want to try the -shared-libgcc option to force the use of the shared libgcc, as suggested on the above page. [1] http://www.mingw.org/wiki/GCCStatus Boris From uwe.kindler at cetoni.de Fri Jun 10 07:20:10 2011 From: uwe.kindler at cetoni.de (cetoni GmbH - Uwe Kindler) Date: Sun Jun 12 05:00:39 2011 Subject: [odb-users] ODB exception problem In-Reply-To: References: <4DF0ADFE.7060205@cetoni.de> Message-ID: <4DF1FDEA.7080507@cetoni.de> Hi Boris, thank you for the response. We use the MinGW build with GCC 4.5.1 from here (now there is already the version 4.5.2 available but we still use 4.5.1): http://tdm-gcc.tdragon.net/ Like I mentioned it in my last mail we use this MinGW version since over a year now without any trouble. Our projects are plugin based and use DLLs extensively and we never had any problems throwing and catching exceptions across DLL boundaries so this is quite strange. This is what the compilers readme file says about exceptions and DLLs: *** Exceptions and DLLs *** With the advent of the GCC 4.5 release series, the mingw32 port finally supports fully the same method every other platform uses to allow exceptions to propagate out of shared libraries (DLLs): gcc library DLLs. For any GCC language that supports exceptions (and DLLs), this method requires the runtime presence of two additional DLLs: (1) libgcc_s*.dll, which contains common core data, and (2) a language-specific DLL. However, TDM-GCC also continues to integrate a versioned shared memory region for the *static* (non-DLL) runtime libraries, which will still allow you to throw exceptions between any DLLs or executables that are built with TDM-GCC. This method incurs a very small execution overhead as compared to the shared library method, but has the very important benefit of not requiring you to redistribute extra DLLs with your program. By default, TDM-GCC will continue to create executables and DLLs that use the static libraries and do not require you to redistribute further DLLs. If you would like to use the shared libraries, you should add "-shared-libgcc" to the command line to use a shared version of libgcc, and additionally ensure that the shared version of your language-specific runtime library is being used. For C++, add "-shared-libstdc++". You cannot use a shared version of libgcc with a static version of a language- specific runtime. The reverse -- static libgcc with shared language-specific runtime -- should work fine. From reading this documentation it should be possible to throw exceptions even if we do not use shared versions of libgcc and libstdc++. I modified the ODB example under odb-examples-1.4.0/schema/custom to throw an exception and it shows the same behaviour - the exception is not caught. Now I'm going to try to use the shared versions and will tell you about the results. Uwe From uwe.kindler at cetoni.de Fri Jun 10 08:05:05 2011 From: uwe.kindler at cetoni.de (cetoni GmbH - Uwe Kindler) Date: Sun Jun 12 05:00:40 2011 Subject: [odb-users] ODB exception problem In-Reply-To: <4DF1FDEA.7080507@cetoni.de> References: <4DF0ADFE.7060205@cetoni.de> <4DF1FDEA.7080507@cetoni.de> Message-ID: <4DF20871.6070904@cetoni.de> Hi Boris, I compiled all ODB libraries and examples with -shared-libgcc -shared-libstdc++ and that did the trick. I ran the modiefied example and the exception was properly catched. Uwe From boris at codesynthesis.com Sun Jun 12 07:56:52 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sun Jun 12 05:40:17 2011 Subject: [odb-users] ODB exception problem In-Reply-To: <4DF20871.6070904@cetoni.de> References: <4DF0ADFE.7060205@cetoni.de> <4DF1FDEA.7080507@cetoni.de> <4DF20871.6070904@cetoni.de> Message-ID: Hi Uwe, cetoni GmbH - Uwe Kindler writes: > I compiled all ODB libraries and examples with -shared-libgcc > -shared-libstdc++ and that did the trick. I ran the modiefied example > and the exception was properly catched. Thanks for sharing your findings. The strange part in all this is that, as you've said in one of your previous emails, you have built numerous DLLs for your project and never had any problem catching cross-DLL exceptions. I assume you didn't use the -shared-libgcc and -shared-libstdc++ options to build your DLLs. This makes me think that there is some difference in how libtool links libodb and how you link your DLLs. Would you be able to compare the command lines for any differences that could trigger this difference in behavior? Alternatively, maybe you could post the command line as was executed by libtool when building libodb and the command line that you use. Then I could look for any differences. Thanks Boris From uwe_kindler at web.de Tue Jun 14 10:40:36 2011 From: uwe_kindler at web.de (Uwe Kindler) Date: Tue Jun 14 11:11:03 2011 Subject: [odb-users] ODB exception problem In-Reply-To: References: <4DF0ADFE.7060205@cetoni.de> <4DF1FDEA.7080507@cetoni.de> <4DF20871.6070904@cetoni.de> Message-ID: <4DF772E4.2040401@web.de> Hi Boris, indeed our software mainly consists of DLLs and exception handling are the main error handling strategy and we never had any problems throwing exceptions across DLL boundaries. Here is the libtool command line for building libodb under MSYS: C:/msys/bin/sh.exe ../libtool --tag=CXX --mode=link g++ -g -O2 -mthreads -release 1.4 -no-undefined -L/local/lib -L/c/CodingXP/Qt/qt/lib -shared-libgcc -shared-libstdc++ -Wl,--enable-auto-import -Wl,--export-all-symbols -o libodb.la -rpa th /usr/local/lib exceptions.lo database.lo lazy-ptr-impl.lo schema-catalog.lo session.lo transaction.lo details/buffer.lo details/condition.lo details/lock.lo details/mutex.lo details/shared-ptr/base.lo details/win32/init.lo details/win32 /once.lo details/win32/tls.lo details/win32/condition.lo details/win32/thread.lo details/win32/exceptions.lo details/win32/dll.lo libtool: link: g++ -shared -nostdlib c:/codingxp/mingw/bin/../lib/gcc/mingw32/4.5.1/../../../dllcrt2.o c:/codingxp/mingw/bin/../lib/gcc/mingw32/4.5.1/crtbegin.o .libs/exceptions.o .libs/database.o .libs/lazy-ptr-impl.o .libs/schema-catalog .o .libs/session.o .libs/transaction.o details/.libs/buffer.o details/.libs/condition.o details/.libs/lock.o details/.libs/mutex.o details/shared-ptr/.libs/base.o details/win32/.libs/init.o details/win32/.libs/once.o details/win32/.libs/tls .o details/win32/.libs/condition.o details/win32/.libs/thread.o details/win32/.libs/exceptions.o details/win32/.libs/dll.o -L/local/lib -L/c/CodingXP/Qt/qt/lib -Lc:/codingxp/mingw/bin/../lib/gcc/mingw32/4.5.1 -Lc:/codingxp/mingw/bin/../li b/gcc -Lc:/codingxp/mingw/bin/../lib/gcc/mingw32/4.5.1/../../../../mingw32/lib -Lc:/codingxp/mingw/bin/../lib/gcc/mingw32/4.5.1/../../.. -lstdc++ -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw 32 -lgcc -lmoldname -lmingwex -lmsvcrt c:/codingxp/mingw/bin/../lib/gcc/mingw32/4.5.1/crtend.o -mthreads -Wl,--enable-auto-import -Wl,--export-all-symbols -mthreads -o .libs/libodb-1-4.dll -Wl,--enable-auto-image-base -Xlinker --out-impl ib -Xlinker .libs/libodb.dll.a Creating library file: .libs/libodb.dll.a libtool: link: ( cd ".libs" && rm -f "libodb.la" && ln -s "../libodb.la" "libodb.la" ) For building our own DLLs we use either eclipse managed DLL projects or CMake for building the DLLs with Hudson CI server. This is the link output from eclipse (I stripped most of the object files from the output and replaced them with ...): g++ -LC:\CodingXP\cetoni_repository\libs\mingw -Xlinker --enable-auto-import -shared -ocanoo-d.dll canoo\utils\RemoteObjDicScanList.o canoo\utils\NodeIdListBitfield.o .. \version.o -lliblog4cplusD -lusl-d This is the link output from CMake for the same project: C:\CodingXP\mingw\bin\g++.exe -Wl,--enable-auto-import -Wl,--export-all-symbols -shared -o canoo.dll -Wl,--out-implib,canoo.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -Wl,--whole-archive CMake Files\canoo.dir/objects.a -Wl,--no-whole-archive -LC:\CodingXP\cetoni_repository\libs\mingw -lusl -lliblog4cplus -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 Creating library file: canoo.dll.a Kind regards, Uwe From boris at codesynthesis.com Wed Jun 15 06:30:38 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Jun 15 04:13:58 2011 Subject: [odb-users] ODB exception problem In-Reply-To: <4DF772E4.2040401@web.de> References: <4DF0ADFE.7060205@cetoni.de> <4DF1FDEA.7080507@cetoni.de> <4DF20871.6070904@cetoni.de> <4DF772E4.2040401@web.de> Message-ID: Hi Uwe, Thanks for sending the command lines. I think the difference in behavior comes from the fact that libtool passes the -nostdlib option and then passes -lgcc and -lstdc++ itself. I am not sure why but this seems to make a difference with your build of GCC but not with ours (I checked and we supply both static and dynamic versions of libgcc/libstdc++). At least we know how to work-around this problem. Boris From uwe.kindler at cetoni.de Wed Jun 15 04:59:24 2011 From: uwe.kindler at cetoni.de (cetoni GmbH - Uwe Kindler) Date: Wed Jun 15 10:15:01 2011 Subject: [odb-users] ODB exception problem In-Reply-To: References: <4DF0ADFE.7060205@cetoni.de> <4DF1FDEA.7080507@cetoni.de> <4DF20871.6070904@cetoni.de> <4DF772E4.2040401@web.de> Message-ID: <4DF8746C.6000007@cetoni.de> Hi Boris, the strange thing is, that it is not sufficient to change libodb build to use -shared-libgcc -shared-libstdc++ options but that I need to add these linker options to all our DLL projects explicitely to make it work properly. From reading the README file that comes with MinGW GCC4.5.1 it seems, that the linker links to the static libaries (libgcc and libstdc++) by default and that a shared memory region ensures that throwing exceptions across DLL boundaries is possible even when using the static versions. Here the snippet from the README file: ---------------> ... However, TDM-GCC also continues to integrate a versioned shared memory region for the *static* (non-DLL) runtime libraries, which will still allow you to throw exceptions between any DLLs or executables that are built with TDM-GCC. This method incurs a very small execution overhead as compared to the shared library method, but has the very important benefit of not requiring you to redistribute extra DLLs with your program. By default, TDM-GCC will continue to create executables and DLLs that use the static libraries and do not require you to redistribute further DLLs. ... <----------------- And this specific mechanism seems to fail for libodb library. So the only solution to use exceptions and libodb is to add the linker options -shared-libgcc -shared-libstdc++ to all libodb and any other DLLs - thats what I did. Kind regards, Uwe -- Mit freundlichen Gr??en Uwe Kindler Dipl. Inf. (FH) Software Engineering cetoni GmbH Automatisierung und Mikrosysteme Am Wiesenring 6 D-07554 Korbussen Phone: +49 (0) 36602 338 28 Fax: +49 (0) 36602 338 11 Email: uwe.kindler@cetoni.de Web: http://www.cetoni.de Handelsregister Jena HRB 202566 Ust.-Ident-Nr. DE 1505 26212 Gesch?ftsf?hrer: Tilo Kunze From boris at codesynthesis.com Thu Jun 16 05:26:15 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Jun 16 03:09:35 2011 Subject: [odb-users] ODB exception problem In-Reply-To: <4DF8746C.6000007@cetoni.de> References: <4DF0ADFE.7060205@cetoni.de> <4DF1FDEA.7080507@cetoni.de> <4DF20871.6070904@cetoni.de> <4DF772E4.2040401@web.de> <4DF8746C.6000007@cetoni.de> Message-ID: Hi Uwe, cetoni GmbH - Uwe Kindler writes: > the strange thing is, that it is not sufficient to change libodb build > to use -shared-libgcc -shared-libstdc++ options but that I need to add > these linker options to all our DLL projects explicitely to make it work > properly. Right, I am pretty sure mixing different exception handling mechanisms won't work. I also currently suspect that the -shared-libgcc and -shared-libstdc++ options are not really needed when building libodb, etc., -- only when building your own (non-libtool) DLLs and executables. This might also explain why ODB tests work fine. They are also built using libtool and are probably linked to the shared support libraries. I will need to investigate this further. You mentioned in one of your previous emails that you modified the 'embedded' examples in ODB to cause it to throw/catch the exception. Did you build it using the supplied makefiles or did you use something else? Boris From uwe.kindler at cetoni.de Thu Jun 16 03:33:24 2011 From: uwe.kindler at cetoni.de (cetoni GmbH - Uwe Kindler) Date: Thu Jun 16 07:04:29 2011 Subject: [odb-users] ODB exception problem In-Reply-To: References: <4DF0ADFE.7060205@cetoni.de> <4DF1FDEA.7080507@cetoni.de> <4DF20871.6070904@cetoni.de> <4DF772E4.2040401@web.de> <4DF8746C.6000007@cetoni.de> Message-ID: <4DF9B1C4.9030304@cetoni.de> Hi Boris, first I built libodb and the examples with the default settings. I simply modified some lines in the embedded driver.cxx but did not modify a makefiles or linker options: { //transaction t (db->begin ()); schema_catalog::create_schema (*db); //t.commit (); } Because create_schema needs a transaction this code now throws an exception. When I ran the example, it crashed and never reached the lines. catch (const odb::exception& e) { cerr << e.what () << endl; return 1; } Both the examples and libodb was buit with the default makefiles (with libtool). So there was no mixing of different exception handling mechanisms. Then I added the -shared-libgcc and -shared-libstdc++ options to the libodb and to the examples build and rebuilt everything. After this change the exception was properly catched in the embedded example. Kind regards, Uwe Kindler Dipl. Inf. (FH) Software Engineering cetoni GmbH Automatisierung und Mikrosysteme Am Wiesenring 6 D-07554 Korbussen Phone: +49 (0) 36602 338 28 Fax: +49 (0) 36602 338 11 Email: uwe.kindler@cetoni.de Web: http://www.cetoni.de Handelsregister Jena HRB 202566 Ust.-Ident-Nr. DE 1505 26212 Gesch?ftsf?hrer: Tilo Kunze From nelson777 at gmail.com Sun Jun 19 11:48:18 2011 From: nelson777 at gmail.com (Nelson Teixeira) Date: Sun Jun 19 11:48:45 2011 Subject: [odb-users] PostgreSQL Message-ID: Hello, Does, ODB has PostgreSQL support ? If not what are the databases supported in the moment ? are other databases support being considered ? Thnx, Nelson From boris at codesynthesis.com Sun Jun 19 16:56:54 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sun Jun 19 14:40:11 2011 Subject: [odb-users] PostgreSQL In-Reply-To: References: Message-ID: Hi Nelson, Nelson Teixeira writes: > Does, ODB has PostgreSQL support? Not in the current version but we are working on PostgreSQL support right now and planning to release it in the next couple of weeks. > If not what are the databases supported in the moment? The current 1.4.0 release supports MySQL and SQLite. > are other databases support being considered? Yes, PostgreSQL support is imminent, MSSQL and Oracle are in the pipeline. Boris From n.albeza at gmail.com Wed Jun 22 11:28:10 2011 From: n.albeza at gmail.com (Nicolas ALBEZA) Date: Wed Jun 22 11:28:18 2011 Subject: [odb-users] ODB in a multi-threaded environment Message-ID: Hello, I was wondering how to use odb::database in a multi-threaded environment : - Does i need to instantiate a database for each thread ? - If this is the case, how caching is handled ? - Is odb::database a light object that i can instantiate and destroy without much overhead ? Thanks ! Regards, -- ALBEZA "Pause" Nicolas From boris at codesynthesis.com Thu Jun 23 07:42:17 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Jun 23 07:44:59 2011 Subject: [odb-users] ODB in a multi-threaded environment In-Reply-To: References: Message-ID: Hi Nicolas, Nicolas ALBEZA writes: > I was wondering how to use odb::database in a multi-threaded environment : > - Does i need to instantiate a database for each thread ? > - If this is the case, how caching is handled ? In a multi-threaded application you would normally have a group of threads use the same odb::database instance (it is thread-safe and you can call its functions without any extra locking). In this setup it also makes sense to use the connection_pool factory (it is the default for MySQL and SQLite). You can also configure the pool with the maximum number of connections it should maintain, etc. For more information on the available connection factories as well as their semantics and parameters, see the "Connection Factory" sections in PART II, "Database Systems" of the manual. > - Is odb::database a light object that i can instantiate and destroy > without much overhead ? This depends on the underlying connection factory used. If, for example, you use the new_connection_factory, then yes, the database instance is quite light and can be created/destroyed often. On the other hand, if you are using the pool factory, then the database instance can be quite "heavy", especially if it is configured to start up with a large number of connections (the min_connections parameter). Boris From n.albeza at gmail.com Thu Jun 23 09:08:14 2011 From: n.albeza at gmail.com (Nicolas ALBEZA) Date: Thu Jun 23 09:08:23 2011 Subject: [odb-users] ODB in a multi-threaded environment In-Reply-To: References: Message-ID: Thanks a lot for your reply ! Regards, 2011/6/23 Boris Kolpackov > Hi Nicolas, > > Nicolas ALBEZA writes: > > > I was wondering how to use odb::database in a multi-threaded environment > : > > - Does i need to instantiate a database for each thread ? > > - If this is the case, how caching is handled ? > > In a multi-threaded application you would normally have a group of threads > use the same odb::database instance (it is thread-safe and you can call its > functions without any extra locking). In this setup it also makes sense > to use the connection_pool factory (it is the default for MySQL and > SQLite). > You can also configure the pool with the maximum number of connections it > should maintain, etc. For more information on the available connection > factories as well as their semantics and parameters, see the "Connection > Factory" sections in PART II, "Database Systems" of the manual. > > > > - Is odb::database a light object that i can instantiate and destroy > > without much overhead ? > > This depends on the underlying connection factory used. If, for example, > you use the new_connection_factory, then yes, the database instance is > quite light and can be created/destroyed often. On the other hand, if > you are using the pool factory, then the database instance can be quite > "heavy", especially if it is configured to start up with a large number > of connections (the min_connections parameter). > > Boris > -- ALBEZA "Pause" Nicolas From thomas.szumowski at lmco.com Thu Jun 23 19:30:17 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Thu Jun 23 19:30:32 2011 Subject: [odb-users] Optimal way of checking if DB entry exists before persisting? Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EDA8386@HVXMSP9.us.lmco.com> Suppose I have have an "employee" object that as a member has a pointer to an "employer" object as in the one-way relationship example from the user guide. I am periodically receiving "employee" objects from an external system and would like to persist the employees in one table and corresponding employers in another (as in the example). If I blindly try to persist the employer (before attempting to persist employee), and an object with that employer ID already exists in the database, ODB throws an error stating the object is already persisted. As an alternative, upon receipt of an employee object, I can do the following: - open transaction - Get employer ID from received employee object - Query the database to see if this employer ID exists - If it does, then call db->update(..) - If it doesn't, then call db->persist(..) - commit This procedure is similar to that outlined at the end of section 2.6 from the manual. My question are: (1) Is this the most efficient way of updating/persisting objects that may already exist in the DB? (2) Since the objects come in periodically, is there a more efficient way of persisting each employee to the database? I assume if the data rate is high, doing commits so often may be inefficient and it may be better to commit based off some timer periodically and cache. (Is there a similar feature in ODB?) Thank you for your help, -Tom Tom Szumowski Lockheed Martin - Advanced Technology Laboratories Phone: (856) 792-9077 E-mail: thomas.szumowski@lmco.com From thomas.szumowski at lmco.com Thu Jun 23 19:39:11 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Thu Jun 23 19:39:29 2011 Subject: [odb-users] Question on Using ODB within a DLL Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EDA838A@HVXMSP9.us.lmco.com> I am interested in creating an DLL. Within that DLL I'd like to create a database and make ODB transactions. I have code that operates perfectly when it is an executable, but when I turn it into a DLL and call from an external program, I get ODB related errors. Specifically, The dialog error indicates a null pointer: Unhandled exception at 0x0039fa4a (odb-d-1.4-vc10.dll) in dbtest.exe 0xC0000005: Access violation reading location 0x00000000. When I trace through the code, the error occurs during the create_database call (where argc and argv are valid and passed through to the DLL as function prototypes): auto_ptr db (create_database(argc, argv)); And the null pointer exception occurs in the return line of transaction::current() in transaction.cxx: bool transaction:: has_current () { return tls_get (current_transaction) != 0; } First, is it possible to access the ODB library from a developed DLL? Second, if so, are there specifics in the setup, or any suggestions as to why this null pointer exception may be occurring in a DLL but not as an EXE? Thank you again. From thomas.szumowski at lmco.com Thu Jun 23 16:46:51 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Fri Jun 24 04:53:29 2011 Subject: [odb-users] Error when migrating or adding headers with ODB markings Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EDA826F@HVXMSP9.us.lmco.com> I noticed that occasionally if I add header files to a project, change the name of a header (and regenerate the ODB files), or change the class names, I tend to get the error below. I can provide the exact source code that causes the error, but before that, any ideas why this may be occurring or what the error is indicating? In particular, it occurs on the db->persist(..) command. If I comment it out, the error disappears. ERROR START: 1>------ Build started: Project: relationship-sqlite-vc10, Configuration: Debug Win32 ------ 1> employee-odb.cxx 1> driver.cxx 1>c:\util\libodb\odb\database.ixx(85): error C2440: 'initializing' : cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer &' 1> with 1> [ 1> _Ty=employee 1> ] 1> Reason: cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer' 1> with 1> [ 1> _Ty=employee 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 1> c:\util\libodb\odb\database.ixx(95) : see reference to function template instantiation 'void odb::database::update(const std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1> c:\tszumows\projects\o2\code\odb_feature_test\driver.cxx(47) : see reference to function template instantiation 'void odb::database::update(std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1>c:\util\libodb\odb\database.ixx(40): error C2440: 'initializing' : cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer &' 1> with 1> [ 1> _Ty=employee 1> ] 1> Reason: cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer' 1> with 1> [ 1> _Ty=employee 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 1> c:\util\libodb\odb\database.ixx(50) : see reference to function template instantiation 'odb::access::object_traits::id_type odb::database::persist(const std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1> c:\tszumows\projects\o2\code\odb_feature_test\driver.cxx(50) : see reference to function template instantiation 'odb::access::object_traits::id_type odb::database::persist(std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1> Generating Code... ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== From thomas.szumowski at lmco.com Thu Jun 23 16:55:24 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Fri Jun 24 04:53:29 2011 Subject: [odb-users] RE: Error when migrating or adding headers with ODB markings Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EDA828E@HVXMSP9.us.lmco.com> I believe I found the issue. I wasn't enforcing TR1 pointers when using the ODB compiler. Per the recommendation from the user manual, I added the following to the compiler call: "--default-pointer std::tr1::shared_ptr" The full command was: "odb -d sqlite --generate-query --generate-schema --default-pointer std::tr1::shared_ptr employee.hxx" This modified a few lines in employee-odb.hxx to use the TR1 pointers and it compiles now. From: Szumowski, Thomas Sent: Thursday, June 23, 2011 4:47 PM To: 'odb-users@codesynthesis.com' Subject: Error when migrating or adding headers with ODB markings I noticed that occasionally if I add header files to a project, change the name of a header (and regenerate the ODB files), or change the class names, I tend to get the error below. I can provide the exact source code that causes the error, but before that, any ideas why this may be occurring or what the error is indicating? In particular, it occurs on the db->persist(..) command. If I comment it out, the error disappears. ERROR START: 1>------ Build started: Project: relationship-sqlite-vc10, Configuration: Debug Win32 ------ 1> employee-odb.cxx 1> driver.cxx 1>c:\util\libodb\odb\database.ixx(85): error C2440: 'initializing' : cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer &' 1> with 1> [ 1> _Ty=employee 1> ] 1> Reason: cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer' 1> with 1> [ 1> _Ty=employee 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 1> c:\util\libodb\odb\database.ixx(95) : see reference to function template instantiation 'void odb::database::update(const std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1> c:\tszumows\projects\o2\code\odb_feature_test\driver.cxx(47) : see reference to function template instantiation 'void odb::database::update(std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1>c:\util\libodb\odb\database.ixx(40): error C2440: 'initializing' : cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer &' 1> with 1> [ 1> _Ty=employee 1> ] 1> Reason: cannot convert from 'const std::tr1::shared_ptr<_Ty>' to 'const object_pointer' 1> with 1> [ 1> _Ty=employee 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 1> c:\util\libodb\odb\database.ixx(50) : see reference to function template instantiation 'odb::access::object_traits::id_type odb::database::persist(const std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1> c:\tszumows\projects\o2\code\odb_feature_test\driver.cxx(50) : see reference to function template instantiation 'odb::access::object_traits::id_type odb::database::persist(std::tr1::shared_ptr<_Ty> &)' being compiled 1> with 1> [ 1> _Ty=employee 1> ] 1> Generating Code... ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== From boris at codesynthesis.com Fri Jun 24 08:38:14 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Jun 24 08:40:53 2011 Subject: [odb-users] Question on Using ODB within a DLL In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EDA838A@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EDA838A@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > And the null pointer exception occurs in the return line of > transaction::current() in transaction.cxx: > > bool transaction:: > has_current () > { > return tls_get (current_transaction) != 0; > } Hm, this is strange. I don't see why ODB cannot be used from the DLL and one shouldn't need to do anything special for that. It looks like the TLS support was not initialized properly in the ODB DLL. Would you be able to create a small test case that reproduces this problem? I will then try to figure out what's going on. Thanks Boris From thomas.szumowski at lmco.com Fri Jun 24 10:45:41 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Fri Jun 24 10:45:56 2011 Subject: EXTERNAL: Re: [odb-users] Question on Using ODB within a DLL In-Reply-To: References: <50FEB91CC4FBAB4881226E0EC04AC3408EDA838A@HVXMSP9.us.lmco.com> Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EDA87DC@HVXMSP9.us.lmco.com> Boris, I attached a MSVC++ 2010 project that results in the described error. Remove the .allow extension so that it is a .zip and unzip the archive. The VC++ solution has two projects. TestDatabase is a project that generates a dll, and dbtest is the driver that uses the DLL file. The testbasic() dll call succeeded because it just is a print statement from the DLL. The test() call fails upon create_database. Thank you for your assistance, Tom -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Friday, June 24, 2011 8:38 AM To: Szumowski, Thomas Cc: odb-users@codesynthesis.com Subject: EXTERNAL: Re: [odb-users] Question on Using ODB within a DLL Hi Thomas, Szumowski, Thomas writes: > And the null pointer exception occurs in the return line of > transaction::current() in transaction.cxx: > > bool transaction:: > has_current () > { > return tls_get (current_transaction) != 0; > } Hm, this is strange. I don't see why ODB cannot be used from the DLL and one shouldn't need to do anything special for that. It looks like the TLS support was not initialized properly in the ODB DLL. Would you be able to create a small test case that reproduces this problem? I will then try to figure out what's going on. Thanks Boris -------------- next part -------------- A non-text attachment was scrubbed... Name: testdb.zip.allow Type: application/octet-stream Size: 12013 bytes Desc: testdb.zip.allow Url : http://codesynthesis.com/pipermail/odb-users/attachments/20110624/f138ea8e/testdb.zip-0001.obj From thomas.szumowski at lmco.com Fri Jun 24 10:53:43 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Fri Jun 24 10:53:56 2011 Subject: EXTERNAL: Re: [odb-users] Optimal way of checking if DB entry exists before persisting? In-Reply-To: References: <50FEB91CC4FBAB4881226E0EC04AC3408EDA8386@HVXMSP9.us.lmco.com> Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EDA880F@HVXMSP9.us.lmco.com> Boris, Thank you for the suggestions. I believe I will be in the situation where the object will be in the database more often than it is not. So I will use your suggestion either to use "find" or to maintain a local map since the module I am developing will be the only one persisting that object type. As for the comment on the commits. I recall some tests I did in the past assessing sqlite speed when directly calling the sqlite api from C. Suppose I was to say commit 50,000 entries. I thought I remember that if I were to commit after binding every entry, it was an order of magnitude slower than if I were to commit after binding all 50,000 entries at first. My memory may not be serving me accurately though ... In either case, I agree with your counter concept and will consider it if performance becomes an issue (which it hasn't yet). Thanks again, Tom -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Friday, June 24, 2011 7:19 AM To: Szumowski, Thomas Cc: odb-users@codesynthesis.com Subject: EXTERNAL: Re: [odb-users] Optimal way of checking if DB entry exists before persisting? Hi Thomas, Szumowski, Thomas writes: > Suppose I have have an "employee" object that as a member has a pointer > to an "employer" object as in the one-way relationship example from the > user guide. I am periodically receiving "employee" objects from an > external system and would like to persist the employees in one table > and corresponding employers in another (as in the example). > > If I blindly try to persist the employer (before attempting to persist > employee), and an object with that employer ID already exists in the > database, ODB throws an error stating the object is already persisted. > As an alternative, upon receipt of an employee object, I can do the > following: > > - open transaction > - Get employer ID from received employee object > - Query the database to see if this employer ID exists > - If it does, then call db->update(..) > - If it doesn't, then call db->persist(..) > - commit > > This procedure is similar to that outlined at the end of section 2.6 > from the manual. > > My question are: > > (1) Is this the most efficient way of updating/persisting objects that > may already exist in the DB? There are several ways to optimize this: 1. Instead of using the query() function you can use find(). find() is quite a bit faster. 2. If you know that in most cases the object will not be in the database, then you can do a speculative persist() call. If it fails with the object_already_persistent exception, then you fall back to the load()/update() call sequence. This method doesn't work as well for the situation where in most cases the object will be in the database since you need to call load() (which is equivalent to find()) before calling update(). 3. If your application is the only entity that persists/updates employer objects, then you can maintain a map of such objects that outlive individual transactions. This way you can avoid doing find(). > (2) Since the objects come in periodically, is there a more efficient > way of persisting each employee to the database? I assume if the > data rate is high, doing commits so often may be inefficient and > it may be better to commit based off some timer periodically and > cache. (Is there a similar feature in ODB?) This depends on your application. If you have multiple applications accessing the database or a multi-threaded application, then having long transactions will hurt concurrency. While it depends on the database, I am also not certain that having a one long transaction instead of a series of smaller ones will necessarily lead to better performance. In the above scenario, you could combine the transactions that persist the employee and employer object into one transactions. Also, while ODB doesn't support some sort of a timer-based auto-commit, you can easily implement something like this yourself. For example, by counting the number of objects that were updated/persisted and committing the current transaction after a certain threshold has been reached. Boris From boris at codesynthesis.com Fri Jun 24 11:36:00 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Jun 24 11:38:40 2011 Subject: EXTERNAL: Re: [odb-users] Question on Using ODB within a DLL In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EDA87DC@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EDA838A@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EDA87DC@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > I attached a MSVC++ 2010 project that results in the described error. > The test() call fails upon create_database. I just tried your test under the VC++ 2010 debugger and it works fine for me. I even examined the output file (a.sql) and it contains the expected data. My only guess would be that some of the DLLs are not loaded. Here are the entries in the Output windows in the debugger that I see after executing the LoadLibrary() function: 'dbtest.exe': Loaded 'C:\projects\testdb\bin\dbtest.exe', Symbols loaded. 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\msvcr100d.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\testdb\bin\DatabaseDLL.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\odb\libodb-sqlite\bin\odb-sqlite-d-1.4-vc10.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\odb\libodb\bin\odb-d-1.4-vc10.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\msvcp100d.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\sqlite\bin\sqlite3.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\msvcr100.dll', Symbols loaded. 'dbtest.exe': Unloaded 'C:\projects\testdb\bin\DatabaseDLL.dll' 'dbtest.exe': Unloaded 'C:\projects\odb\libodb-sqlite\bin\odb-sqlite-d-1.4-vc10.dll' 'dbtest.exe': Unloaded 'C:\projects\sqlite\bin\sqlite3.dll' 'dbtest.exe': Unloaded 'C:\Windows\SysWOW64\msvcr100.dll' 'dbtest.exe': Unloaded 'C:\projects\odb\libodb\bin\odb-d-1.4-vc10.dll' 'dbtest.exe': Unloaded 'C:\Windows\SysWOW64\msvcp100d.dll' Can you check if you get something similar. The DLLs of interest are odb-sqlite-d-1.4-vc10.dll, sqlite3.dll, and odb-d-1.4-vc10.dll. If all this looks similar, can you set a breakpoint (before the call to LoadLibrary()) in libodb/odb/details/win32/dll.cxx at the beginning of DllMain() and see if it is called? Boris From thomas.szumowski at lmco.com Fri Jun 24 12:03:06 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Fri Jun 24 12:03:25 2011 Subject: EXTERNAL: Re: [odb-users] Question on Using ODB within a DLL In-Reply-To: References: <50FEB91CC4FBAB4881226E0EC04AC3408EDA838A@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EDA87DC@HVXMSP9.us.lmco.com> Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EDA896F@HVXMSP9.us.lmco.com> Boris, My debugger output looks similar on loading, but it is missing sqlite3.dll. (See the snippet below). Also, I put a breakpoint in dll.cxx. The code under "case DLL_PROCESS_ATTACH" executes successfully and the function returns a 1. Also I noticed it works on my end fine when I implicitly link to the DLL rather than explicitly. So I suppose it is in fact what you suspected, a DLL (sqlite3) is not being loaded. I'll look into why sqlite3 is not being pulled in while everything else is. Debugger Output: 'dbtest.exe': Loaded 'C:\tszumows\projects\O2\code\testdb\bin\dbtest.exe', Symbols loaded. 'dbtest.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\WINDOWS\system32\msvcr100d.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\tszumows\projects\O2\code\testdb\bin\DatabaseDLL.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\util\libodb-sqlite\bin\odb-sqlite-d-1.4-vc10.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\util\libodb\bin\odb-d-1.4-vc10.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\WINDOWS\system32\msvcp100d.dll', Symbols loaded. -Tom -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Friday, June 24, 2011 11:36 AM To: Szumowski, Thomas Cc: odb-users@codesynthesis.com Subject: Re: EXTERNAL: Re: [odb-users] Question on Using ODB within a DLL Hi Thomas, Szumowski, Thomas writes: > I attached a MSVC++ 2010 project that results in the described error. > The test() call fails upon create_database. I just tried your test under the VC++ 2010 debugger and it works fine for me. I even examined the output file (a.sql) and it contains the expected data. My only guess would be that some of the DLLs are not loaded. Here are the entries in the Output windows in the debugger that I see after executing the LoadLibrary() function: 'dbtest.exe': Loaded 'C:\projects\testdb\bin\dbtest.exe', Symbols loaded. 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll', Cannot find or open the PDB file 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\msvcr100d.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\testdb\bin\DatabaseDLL.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\odb\libodb-sqlite\bin\odb-sqlite-d-1.4-vc10.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\odb\libodb\bin\odb-d-1.4-vc10.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\msvcp100d.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\projects\sqlite\bin\sqlite3.dll', Symbols loaded. 'dbtest.exe': Loaded 'C:\Windows\SysWOW64\msvcr100.dll', Symbols loaded. 'dbtest.exe': Unloaded 'C:\projects\testdb\bin\DatabaseDLL.dll' 'dbtest.exe': Unloaded 'C:\projects\odb\libodb-sqlite\bin\odb-sqlite-d-1.4-vc10.dll' 'dbtest.exe': Unloaded 'C:\projects\sqlite\bin\sqlite3.dll' 'dbtest.exe': Unloaded 'C:\Windows\SysWOW64\msvcr100.dll' 'dbtest.exe': Unloaded 'C:\projects\odb\libodb\bin\odb-d-1.4-vc10.dll' 'dbtest.exe': Unloaded 'C:\Windows\SysWOW64\msvcp100d.dll' Can you check if you get something similar. The DLLs of interest are odb-sqlite-d-1.4-vc10.dll, sqlite3.dll, and odb-d-1.4-vc10.dll. If all this looks similar, can you set a breakpoint (before the call to LoadLibrary()) in libodb/odb/details/win32/dll.cxx at the beginning of DllMain() and see if it is called? Boris From boris at codesynthesis.com Fri Jun 24 07:19:06 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Sun Jun 26 07:54:43 2011 Subject: [odb-users] Optimal way of checking if DB entry exists before persisting? In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EDA8386@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EDA8386@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > Suppose I have have an "employee" object that as a member has a pointer > to an "employer" object as in the one-way relationship example from the > user guide. I am periodically receiving "employee" objects from an > external system and would like to persist the employees in one table > and corresponding employers in another (as in the example). > > If I blindly try to persist the employer (before attempting to persist > employee), and an object with that employer ID already exists in the > database, ODB throws an error stating the object is already persisted. > As an alternative, upon receipt of an employee object, I can do the > following: > > - open transaction > - Get employer ID from received employee object > - Query the database to see if this employer ID exists > - If it does, then call db->update(..) > - If it doesn't, then call db->persist(..) > - commit > > This procedure is similar to that outlined at the end of section 2.6 > from the manual. > > My question are: > > (1) Is this the most efficient way of updating/persisting objects that > may already exist in the DB? There are several ways to optimize this: 1. Instead of using the query() function you can use find(). find() is quite a bit faster. 2. If you know that in most cases the object will not be in the database, then you can do a speculative persist() call. If it fails with the object_already_persistent exception, then you fall back to the load()/update() call sequence. This method doesn't work as well for the situation where in most cases the object will be in the database since you need to call load() (which is equivalent to find()) before calling update(). 3. If your application is the only entity that persists/updates employer objects, then you can maintain a map of such objects that outlive individual transactions. This way you can avoid doing find(). > (2) Since the objects come in periodically, is there a more efficient > way of persisting each employee to the database? I assume if the > data rate is high, doing commits so often may be inefficient and > it may be better to commit based off some timer periodically and > cache. (Is there a similar feature in ODB?) This depends on your application. If you have multiple applications accessing the database or a multi-threaded application, then having long transactions will hurt concurrency. While it depends on the database, I am also not certain that having a one long transaction instead of a series of smaller ones will necessarily lead to better performance. In the above scenario, you could combine the transactions that persist the employee and employer object into one transactions. Also, while ODB doesn't support some sort of a timer-based auto-commit, you can easily implement something like this yourself. For example, by counting the number of objects that were updated/persisted and committing the current transaction after a certain threshold has been reached. Boris From n.albeza at gmail.com Mon Jun 27 03:51:09 2011 From: n.albeza at gmail.com (Nicolas ALBEZA) Date: Mon Jun 27 03:51:17 2011 Subject: [odb-users] Object ID and unidirectional to-one relationships Message-ID: Hello odb-users, I was wondering if it was possible for an object ID to be a foreign key (id used to map the primary table). It could save some bytes in my tables, and allow me to use find() more often. Regards, -- ALBEZA "Pause" Nicolas From boris at codesynthesis.com Mon Jun 27 03:58:24 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Jun 27 04:01:04 2011 Subject: [odb-users] Object ID and unidirectional to-one relationships In-Reply-To: References: Message-ID: Hi Nicolas, Nicolas ALBEZA writes: > I was wondering if it was possible for an object ID to be a foreign key (id > used to map the primary table). It could save some bytes in my tables, and > allow me to use find() more often. I don't see any problem doing this. You will have to provide a custom database schema but I assume you are already doing this. Boris From n.albeza at gmail.com Mon Jun 27 04:18:20 2011 From: n.albeza at gmail.com (Nicolas ALBEZA) Date: Mon Jun 27 04:18:30 2011 Subject: [odb-users] Object ID and unidirectional to-one relationships In-Reply-To: References: Message-ID: The problem is i can't see how to "merge" my two fields (integer id and shared_ptr) into one. 2011/6/27 Boris Kolpackov > Hi Nicolas, > > Nicolas ALBEZA writes: > > > I was wondering if it was possible for an object ID to be a foreign key > (id > > used to map the primary table). It could save some bytes in my tables, > and > > allow me to use find() more often. > > I don't see any problem doing this. You will have to provide a custom > database schema but I assume you are already doing this. > > Boris > -- ALBEZA "Pause" Nicolas From boris at codesynthesis.com Mon Jun 27 06:44:43 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Mon Jun 27 06:47:22 2011 Subject: [odb-users] Object ID and unidirectional to-one relationships In-Reply-To: References: Message-ID: Hi Nicolas, Nicolas ALBEZA writes: > The problem is i can't see how to "merge" my two fields (integer id and > shared_ptr) into one. Yes, I see the issue now. Ideally you should be able to use a pointer as an object id. However, that would require some extra code to be generated by the ODB compiler which it currently does not do. I have added this to the requested feature list so hopefully we will get to that at some point. The work-around would be to have the id as an integer and object pointer as a transient member. You would also need to initialize one from the other in different situations, e.g., id from pointer in your constructors and pointer from id after the call to load()). Having the ability to have a user callback after operations such as load() would help with the latter case and we plan to add something like this in the near future. Boris From n.albeza at gmail.com Mon Jun 27 08:13:43 2011 From: n.albeza at gmail.com (Nicolas ALBEZA) Date: Mon Jun 27 08:13:52 2011 Subject: [odb-users] Object ID and unidirectional to-one relationships In-Reply-To: References: Message-ID: Thanks a lot for your answer ! Keep up the good work with ODB =) Regards, 2011/6/27 Boris Kolpackov > Hi Nicolas, > > Nicolas ALBEZA writes: > > > The problem is i can't see how to "merge" my two fields (integer id and > > shared_ptr) into one. > > Yes, I see the issue now. Ideally you should be able to use a pointer > as an object id. However, that would require some extra code to be > generated by the ODB compiler which it currently does not do. I have > added this to the requested feature list so hopefully we will get to > that at some point. > > The work-around would be to have the id as an integer and object > pointer as a transient member. You would also need to initialize > one from the other in different situations, e.g., id from pointer > in your constructors and pointer from id after the call to load()). > Having the ability to have a user callback after operations such > as load() would help with the latter case and we plan to add > something like this in the near future. > > Boris > -- ALBEZA "Pause" Nicolas From thomas.szumowski at lmco.com Mon Jun 27 15:56:11 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Mon Jun 27 15:56:28 2011 Subject: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> I have some objects that I would like to persist using ODB. These objects are dependent on objects generated by an external third party middleware application, Apache Thrift. The objects I'd like to persist themselves are not Thrift objects, but rather they inherit Thrift Objects (via reuse inheritance). For example, I may have an object "ODBObject" that inherits a Thrift object "ThriftObject". Note the example I attached (rename from .allow to .zip), specifically "ODBTest.h" and odb_compile_output.txt. When I attempt to compile, I get the following seg fault in std-vector-traits listed below. (The code is provided for reference only as the Windows Thrift environment takes some time to set up). I figured it was a longshot to get ODB and Thrift interoperable on the first shot. This is especially true because Apache relies on external software like pthread-win32 and boost. And I suspect the integration may be more difficult than creating a workaround. I have a workaround in mind, but I'm curious what the error below even means. Any idea why the seg-fault may be occurring for a more general perspective? ------- ODB COMPILER ERROR: ------- In file included from c:\util\odb-1.4.0-i686-windows\mingw\bin\../../mingw/include/odb/container-traits.hxx:196:0, from :7: c:\util\odb-1.4.0-i686-windows\mingw\bin\../../mingw/include/odb/std-vector-traits.hxx: In function '(static initializers for c:\util\odb-1.4.0-i686-w indows\mingw\bin\../../mingw/include/odb/std-vector-traits.hxx)': c:\util\odb-1.4.0-i686-windows\mingw\bin\../../mingw/include/odb/std-vector-traits.hxx:66:1: internal compiler error: Segmentation fault ------- Tom Szumowski Lockheed Martin - Advanced Technology Laboratories Phone: (856) 792-9077 E-mail: thomas.szumowski@lmco.com -------------- next part -------------- A non-text attachment was scrubbed... Name: odb_thrift_test.zip.allow Type: application/octet-stream Size: 5144 bytes Desc: odb_thrift_test.zip.allow Url : http://codesynthesis.com/pipermail/odb-users/attachments/20110627/bd03eb73/odb_thrift_test.zip.obj From boris at codesynthesis.com Tue Jun 28 10:37:25 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Jun 28 10:40:09 2011 Subject: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > Note the example I attached (rename from .allow to .zip), specifically > "ODBTest.h" and odb_compile_output.txt. When I attempt to compile, I > get the following seg fault in std-vector-traits listed below. (The > code is provided for reference only as the Windows Thrift environment > takes some time to set up). It is much easier to install Thrift on a Linux box so I tried that. In this setup the ODB compiler compiles your test without any problems. Would you be able to get the preprocessed source for your ODBTest.h file and send it to me? This way I would be able to try it with the Windows version of ODB without having to setup Thrift. You can get the preprocessed source by adding these options to the ODB command line: -x -E -x -o -x ODBTest.i > I figured it was a longshot to get ODB and Thrift interoperable on > the first shot. This is especially true because Apache relies on > external software like pthread-win32 and boost. I don't see why merely including some headers should lead to the ODB compiler breaking. This is definitely something we would want to fix. > Any idea why the seg-fault may be occurring for a more general > perspective? Most likely an ODB compiler bug. Will hopefully find out more with the preprocessed source. Boris From thomas.szumowski at lmco.com Tue Jun 28 11:15:27 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Tue Jun 28 11:27:55 2011 Subject: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) In-Reply-To: References: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EEB6A2A@HVXMSP9.us.lmco.com> Hi Boris, No problem. Thank you for looking into the issue. I attached the ODBTest.i in the same usual form (.zip.allow remove the "allow" suffix). And yes you are correct, Thrift is a bit tricky to get working with Windows. I followed the patches from the Apache THRIFT-1123 tracker report at: https://issues.apache.org/jira/browse/THRIFT-1123 Good to know ODB is working fine given all of Thrift's specificities and dependencies. Let me know if you need any more files or information. -Tom -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Tuesday, June 28, 2011 10:37 AM To: Szumowski, Thomas Cc: odb-users@codesynthesis.com Subject: EXTERNAL: Re: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) Hi Thomas, Szumowski, Thomas writes: > Note the example I attached (rename from .allow to .zip), specifically > "ODBTest.h" and odb_compile_output.txt. When I attempt to compile, I > get the following seg fault in std-vector-traits listed below. (The > code is provided for reference only as the Windows Thrift environment > takes some time to set up). It is much easier to install Thrift on a Linux box so I tried that. In this setup the ODB compiler compiles your test without any problems. Would you be able to get the preprocessed source for your ODBTest.h file and send it to me? This way I would be able to try it with the Windows version of ODB without having to setup Thrift. You can get the preprocessed source by adding these options to the ODB command line: -x -E -x -o -x ODBTest.i > I figured it was a longshot to get ODB and Thrift interoperable on > the first shot. This is especially true because Apache relies on > external software like pthread-win32 and boost. I don't see why merely including some headers should lead to the ODB compiler breaking. This is definitely something we would want to fix. > Any idea why the seg-fault may be occurring for a more general > perspective? Most likely an ODB compiler bug. Will hopefully find out more with the preprocessed source. Boris -------------- next part -------------- A non-text attachment was scrubbed... Name: ODBTest.zip.allow Type: application/octet-stream Size: 208079 bytes Desc: ODBTest.zip.allow Url : http://codesynthesis.com/pipermail/odb-users/attachments/20110628/1a4a5043/ODBTest.zip-0001.obj From boris at codesynthesis.com Tue Jun 28 12:36:53 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Jun 28 12:39:41 2011 Subject: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EEB6A2A@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EEB6A2A@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > I attached the ODBTest.i... Thanks, I managed to reproduce and fix the problem (it was the anonymous struct inside a union construct in the winnt.h header that ODB couldn't handle). I've built you a 1.4.0 compiler binary with the fix: http://www.codesynthesis.com/~boris/tmp/odb/odb-1.4.0-1-i686-windows.zip Boris From thomas.szumowski at lmco.com Tue Jun 28 13:11:32 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Tue Jun 28 13:11:52 2011 Subject: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) In-Reply-To: References: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EEB6A2A@HVXMSP9.us.lmco.com> Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EEB6CD1@HVXMSP9.us.lmco.com> Success! I was able to compile on my end with the new build. I appreciate your assistance in finding the resolution. This will make the interface to our architecture much more seamless. -Tom -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Tuesday, June 28, 2011 12:37 PM To: Szumowski, Thomas Cc: odb-users@codesynthesis.com Subject: EXTERNAL: Re: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) Hi Thomas, Szumowski, Thomas writes: > I attached the ODBTest.i... Thanks, I managed to reproduce and fix the problem (it was the anonymous struct inside a union construct in the winnt.h header that ODB couldn't handle). I've built you a 1.4.0 compiler binary with the fix: http://www.codesynthesis.com/~boris/tmp/odb/odb-1.4.0-1-i686-windows.zip Boris From thomas.szumowski at lmco.com Tue Jun 28 13:16:14 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Tue Jun 28 13:16:28 2011 Subject: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) References: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EEB6A2A@HVXMSP9.us.lmco.com> Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EEB6CF2@HVXMSP9.us.lmco.com> Just to confirm. The update was only needed for the compiler (that you provided a link for), and not the ODB or ODB extension libraries correct? -Tom -----Original Message----- From: Szumowski, Thomas Sent: Tuesday, June 28, 2011 1:12 PM To: 'Boris Kolpackov' Cc: odb-users@codesynthesis.com Subject: RE: Re: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) Success! I was able to compile on my end with the new build. I appreciate your assistance in finding the resolution. This will make the interface to our architecture much more seamless. -Tom -----Original Message----- From: Boris Kolpackov [mailto:boris@codesynthesis.com] Sent: Tuesday, June 28, 2011 12:37 PM To: Szumowski, Thomas Cc: odb-users@codesynthesis.com Subject: EXTERNAL: Re: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) Hi Thomas, Szumowski, Thomas writes: > I attached the ODBTest.i... Thanks, I managed to reproduce and fix the problem (it was the anonymous struct inside a union construct in the winnt.h header that ODB couldn't handle). I've built you a 1.4.0 compiler binary with the fix: http://www.codesynthesis.com/~boris/tmp/odb/odb-1.4.0-1-i686-windows.zip Boris From boris at codesynthesis.com Tue Jun 28 13:45:29 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Jun 28 13:48:09 2011 Subject: [odb-users] Compatibility with Third Party Middleware (Apache Thrift) In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EEB6CF2@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EEB60FD@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EEB6A2A@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EEB6CF2@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > The update was only needed for the compiler (that you provided a link for), > and not the ODB or ODB extension libraries correct? Right, the bug only affected the ODB compiler. Boris From thomas.szumowski at lmco.com Wed Jun 29 08:21:48 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Wed Jun 29 08:22:20 2011 Subject: [odb-users] Opening an already existing database (SQLite) and appending Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EF13C3C@HVXMSP9.us.lmco.com> Quick question. When using sqlite, what is the correct command to open an already existing database and append to it, rather than overwrite it? I tried create_database as in the hello example. But if I recompile to persist a different person, it seems to overwrite. I also tried the database constructor that takes in a name and flags - something to the effect "database(string name, int flags)", setting the flags to SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, with no luck. I'm sure I'm making a very fundamental mistake. Any recommendations? From boris at codesynthesis.com Wed Jun 29 08:32:12 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Jun 29 08:34:55 2011 Subject: [odb-users] Opening an already existing database (SQLite) and appending In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EF13C3C@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EF13C3C@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > I also tried the database constructor that takes in a name and flags - > something to the effect "database(string name, int flags)", setting > the flags to SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, with no luck. According to the SQLite documentation[1], opening with just SQLITE_OPEN_READWRITE will open the existing database but fail if it does not already exist. Opening with SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE will create the database if it does not exist. ODB underneath always uses the sqlite3_open_v2() function. So it sounds to me that this should work as expected. Can you elaborate on the overwrite behavior that you are observing? Is the database always empty after you open it even though you stored something into it before? Can you also check that you are actually committing the transaction? If none of this helps, can you send a small test case that reproduces this? [1] http://www.sqlite.org/c3ref/open.html Boris From thomas.szumowski at lmco.com Wed Jun 29 12:12:18 2011 From: thomas.szumowski at lmco.com (Szumowski, Thomas) Date: Wed Jun 29 12:14:01 2011 Subject: [odb-users] Opening an already existing database (SQLite) and appending In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EE87A63@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EE87A63@HVXMSP9.us.lmco.com> Message-ID: <50FEB91CC4FBAB4881226E0EC04AC3408EE87A64@HVXMSP9.us.lmco.com> I attached a small test case that is derived from the "hello" example. See the top of driver.cxx for usage. Essentially I first persist John Doe. It shows up in the database xyz.sql. I then run the program again persisting Jane Doe. But when I look at xyz.sql again, it only shows Jane, and not both John and Jane. -Tom ________________________________________ From: Boris Kolpackov [boris@codesynthesis.com] Sent: Wednesday, June 29, 2011 8:32 AM To: Szumowski, Thomas Cc: odb-users@codesynthesis.com Subject: EXTERNAL: Re: [odb-users] Opening an already existing database (SQLite) and appending Hi Thomas, Szumowski, Thomas writes: > I also tried the database constructor that takes in a name and flags - > something to the effect "database(string name, int flags)", setting > the flags to SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, with no luck. According to the SQLite documentation[1], opening with just SQLITE_OPEN_READWRITE will open the existing database but fail if it does not already exist. Opening with SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE will create the database if it does not exist. ODB underneath always uses the sqlite3_open_v2() function. So it sounds to me that this should work as expected. Can you elaborate on the overwrite behavior that you are observing? Is the database always empty after you open it even though you stored something into it before? Can you also check that you are actually committing the transaction? If none of this helps, can you send a small test case that reproduces this? [1] http://www.sqlite.org/c3ref/open.html Boris -------------- next part -------------- A non-text attachment was scrubbed... Name: db_append_test.zip.allow Type: application/octet-stream Size: 10570 bytes Desc: db_append_test.zip.allow Url : http://codesynthesis.com/pipermail/odb-users/attachments/20110629/eb6eae22/db_append_test.zip.obj From boris at codesynthesis.com Wed Jun 29 13:07:56 2011 From: boris at codesynthesis.com (Boris Kolpackov) Date: Wed Jun 29 13:10:39 2011 Subject: [odb-users] Opening an already existing database (SQLite) and appending In-Reply-To: <50FEB91CC4FBAB4881226E0EC04AC3408EE87A64@HVXMSP9.us.lmco.com> References: <50FEB91CC4FBAB4881226E0EC04AC3408EE87A63@HVXMSP9.us.lmco.com> <50FEB91CC4FBAB4881226E0EC04AC3408EE87A64@HVXMSP9.us.lmco.com> Message-ID: Hi Thomas, Szumowski, Thomas writes: > But when I look at xyz.sql again, it only shows Jane, and not both > John and Jane. Ok, I've figured it out: the create_database() function re-creates the database schema every time it is called, regardless of whether the database already exists or not. Part of this process is dropping all the existing tables which also deleted all the entries. The 'schema/embedded' example has a piece of code that shows how to detect whether the schema already exists. Boris