From boris at codesynthesis.com Thu Jul 23 02:27:12 2020 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Jul 23 02:41:59 2020 Subject: [odb-users] ODB 2.5.0-b.19 available Message-ID: ODB 2.5.0-b.19 pre-release is available from cppget.org. One notable change compared to the previous pre-release is compatibility with GCC 10: https://cppget.org/odb/2.5.0-b.19+1 The build instructions are here: https://codesynthesis.com/products/odb/doc/install-build2.xhtml Note that you will need to upgrade to build2 0.13.0 to be able to build this version of ODB. From haupt.wolfgang at gmail.com Thu Jul 23 03:21:07 2020 From: haupt.wolfgang at gmail.com (Wolfgang Haupt) Date: Thu Jul 23 03:36:03 2020 Subject: [odb-users] ODB 2.5.0-b.19 available In-Reply-To: References: Message-ID: On 23.07.20 08:27, Boris Kolpackov wrote: > ODB 2.5.0-b.19 pre-release is available from cppget.org. One notable > change compared to the previous pre-release is compatibility with GCC 10: > > https://cppget.org/odb/2.5.0-b.19+1 > > The build instructions are here: > > https://codesynthesis.com/products/odb/doc/install-build2.xhtml > > Note that you will need to upgrade to build2 0.13.0 to be able to build > this version of ODB. > Is there a build2 way to create a classic source tarball? I'm bound to a large rather complicated autotools buildsystem where the easiest way is to use a tarball and `./configure`. I managed to create that by pulling the source and `make dist dist_prefix=/tmp/libodb-2.5.0-b.19`. Now I wonder if that should be done using the build2 toolchain by now? From boris at codesynthesis.com Thu Jul 23 10:32:38 2020 From: boris at codesynthesis.com (Boris Kolpackov) Date: Thu Jul 23 10:47:23 2020 Subject: [odb-users] ODB 2.5.0-b.19 available In-Reply-To: References: Message-ID: Wolfgang Haupt writes: > Is there a build2 way to create a classic source tarball? It can create the source distribution which will use build2 as the build system but it cannot convert the build2 build system to the autotools build system. > I'm bound to a large rather complicated autotools buildsystem where the > easiest way is to use a tarball and `./configure`. > I managed to create that by pulling the source and `make dist > dist_prefix=/tmp/libodb-2.5.0-b.19`. That works only accidentally since the autotools templates (which is how the old make-based build system does this) are no longer maintained. > Now I wonder if that should be done using the build2 toolchain by now? If you cannot use build2 directly, then the next best option is probably to create binary packages (so instead of ./configure && make you do dpkg or rpm). I am not sure which distribution you are using but here are the instructions on how to create the .deb package for the ODB compiler (for the runtime libraries the steps would be similar), in case you or someone else finds this useful (we plan to eventually make build2 generate such distribution packages automatically). The below instructions are based on the approach described on this page: https://askubuntu.com/questions/474387/installing-a-directory-with-a-debian-package First build and install the ODB compiler using this configuration (instead of the one in the install-build2 instructions): $ bpkg create -d odb-gcc cc \ config.cxx=g++ \ config.cc.coptions=-O3 \ config.install.root=/usr \ config.install.chroot=/tmp/odb With the result in /tmp/odb/, add the following DEBIAN/control file: # mkdir -p /tmp/odb/DEBIAN $ cat </tmp/odb/DEBIAN/control Package: odb Version: 2.5.0-b.19 Architecture: amd64 Maintainer: you@example.org Description: ORM for C++ ODB is an object-relational mapping (ORM) system for C++. It provides tools, APIs, and library support that allow you to persist C++ objects to a relational database (RDBMS) without having to deal with tables, columns, or SQL and without manually writing any of the mapping code. EOF Then, from /tmp/ run: $ dpkg -b odb . dpkg-deb: building package 'odb' in './odb_2.5.0-b.19_amd64.deb'. You can then install/uninstall odb_2.5.0-b.19_amd64.deb using dpkg: sudo dpkg -i odb_2.5.0-b.17_amd64.deb sudo dpkg --purge odb The binary package should work on any machine that has the same version of GCC. From ratkaisut at gmail.com Fri Jul 24 01:36:00 2020 From: ratkaisut at gmail.com (Sten Kultakangas) Date: Fri Jul 24 01:51:05 2020 Subject: [odb-users] composite ID containing an auto-incrementable field Message-ID: Hello I know that composite IDs have some restrictions but I made a conclusion that this issue can be fixed with relatively low effort. The problem is that in the following case odb does not generate a valid code needed to persist the object: #pragma db value struct ObjectId { #pragma db auto long long id = 0; long long tenant_id = 0; }; #pragma db object schema("GenericSwitch.dbo") struct Extension { #pragma db id column("") ObjectId key; #pragma db type("varchar(16)") std::string extension; }; Here's the generated INSERT statement: const char access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::persist_statement[] = "INSERT INTO [GenericSwitch].[dbo].[Extension] " "([id], " "[tenant_id], " "[extension]) " "VALUES " "(?, ?, ?)"; Instead it must not contain the id field and must contain the OUTPUT INSERTED keyword: const char access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::persist_statement[] = "INSERT INTO [GenericSwitch].[dbo].[Extension] " "([tenant_id], " "[extension]) " "OUTPUT INSERTED.[id] " "VALUES " "(?, ?)"; This also requires some modifications to the code which generates access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::persist() Boris, I am going to make the necessary modifications to odb/relational/source.cxx and odb/relational/mssql/source.cxx but i wonder if you have some work-in-progress branch having the relevant modifications that I can easily backport to the stable 2.5.0 branch ? If you haven't yet worked on this issue, then do you have instructions for contributors on how to make a patch that can be incorporated into the official version control branch ? P.S. Actually tenant_id does not belong to the primary key, but i see no other way to force odb to generate UPDATE statement having condition WHERE tenant_id=X and id=X which is necessary for data integrity as our API does not currently perform sanity-checks on the user-supplied ID but instead it determines the tenant the API user belongs to. Best regards, Sten Kultakangas From haupt.wolfgang at gmail.com Fri Jul 24 01:50:26 2020 From: haupt.wolfgang at gmail.com (Wolfgang Haupt) Date: Fri Jul 24 02:05:23 2020 Subject: [odb-users] ODB 2.5.0-b.19 available In-Reply-To: References: Message-ID: <742710f4-df05-2455-b36e-85e97ee6fbe7@gmail.com> On 23.07.20 16:32, Boris Kolpackov wrote: > Wolfgang Haupt writes: > >> Is there a build2 way to create a classic source tarball? > It can create the source distribution which will use build2 as the > build system but it cannot convert the build2 build system to the > autotools build system. > > >> I'm bound to a large rather complicated autotools buildsystem where the >> easiest way is to use a tarball and `./configure`. >> I managed to create that by pulling the source and `make dist >> dist_prefix=/tmp/libodb-2.5.0-b.19`. > That works only accidentally since the autotools templates (which is > how the old make-based build system does this) are no longer maintained. Alright, that was my guess already, thx for clarifying. For now I'm glad it still worked :) > > >> Now I wonder if that should be done using the build2 toolchain by now? > If you cannot use build2 directly, then the next best option is probably > to create binary packages (so instead of ./configure && make you do dpkg > or rpm). I am not sure which distribution you are using but here are the > instructions on how to create the .deb package for the ODB compiler (for > the runtime libraries the steps would be similar), in case you or someone > else finds this useful (we plan to eventually make build2 generate such > distribution packages automatically). > > The below instructions are based on the approach described on this page: > > https://askubuntu.com/questions/474387/installing-a-directory-with-a-debian-package > > First build and install the ODB compiler using this configuration (instead > of the one in the install-build2 instructions): > > $ bpkg create -d odb-gcc cc \ > config.cxx=g++ \ > config.cc.coptions=-O3 \ > config.install.root=/usr \ > config.install.chroot=/tmp/odb > > With the result in /tmp/odb/, add the following DEBIAN/control file: > > # mkdir -p /tmp/odb/DEBIAN > $ cat </tmp/odb/DEBIAN/control > Package: odb > Version: 2.5.0-b.19 > Architecture: amd64 > Maintainer: you@example.org > Description: ORM for C++ > ODB is an object-relational mapping (ORM) system for C++. It provides > tools, APIs, and library support that allow you to persist C++ objects > to a relational database (RDBMS) without having to deal with tables, > columns, or SQL and without manually writing any of the mapping code. > EOF > > Then, from /tmp/ run: > > $ dpkg -b odb . > dpkg-deb: building package 'odb' in './odb_2.5.0-b.19_amd64.deb'. > > You can then install/uninstall odb_2.5.0-b.19_amd64.deb using dpkg: > > sudo dpkg -i odb_2.5.0-b.17_amd64.deb > sudo dpkg --purge odb > > The binary package should work on any machine that has the same version > of GCC. I bet this is useful to a bunch of guys in here, so thx again for the sample. My project however, uses a self made unified depends system that will build a large number of dependencies (probably more than 70 libs) for multiple platforms (linux, windows, android, osx, etc. etc.). If I find enough time, I'll look into what's needed to pass all the necessary cross compile options to build2 and might work on initial build2 support. From boris at codesynthesis.com Fri Jul 24 06:24:59 2020 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Jul 24 06:39:51 2020 Subject: [odb-users] ODB 2.5.0-b.19 available In-Reply-To: <742710f4-df05-2455-b36e-85e97ee6fbe7@gmail.com> References: <742710f4-df05-2455-b36e-85e97ee6fbe7@gmail.com> Message-ID: Wolfgang Haupt writes: > If I find enough time, I'll look into what's needed to pass all the > necessary cross compile options to build2 and might work on initial > build2 support. This should normally be just a matter of passing the compiler since build2 gets everything else from there (target, search paths, binutils, etc). For example: $ b config.cxx=x86_64-w64-mingw32-g++ But let me know if you run into any issues. From boris at codesynthesis.com Fri Jul 24 07:17:21 2020 From: boris at codesynthesis.com (Boris Kolpackov) Date: Fri Jul 24 07:32:10 2020 Subject: [odb-users] composite ID containing an auto-incrementable field In-Reply-To: References: Message-ID: Sten Kultakangas writes: > Boris, I am going to make the necessary modifications to > odb/relational/source.cxx and odb/relational/mssql/source.cxx but i wonder > if you have some work-in-progress branch having the relevant modifications > that I can easily backport to the stable 2.5.0 branch ? No, I haven't looked into this. > If you haven't yet worked on this issue, then do you have instructions for > contributors on how to make a patch that can be incorporated into the > official version control branch ? You can either email the patch directly or create a pull request on your favorite Git hosting platform (GitHub, etc). Note that for this to be merged to master we would need the fix for all the databases as well as a test. > P.S. Actually tenant_id does not belong to the primary key, but i see no > other way to force odb to generate UPDATE statement having condition WHERE > tenant_id=X and id=X which is necessary for data integrity as our API does > not currently perform sanity-checks on the user-supplied ID but instead it > determines the tenant the API user belongs to. One somewhat admittedly hackish way to achieve this could be to "overlay" two classes over the same database table. One class would have the simple auto id to be used for persist and the other would have the composite id without auto to be used for update. You might also need to tweak the generated database schema depending on the database system used. From ratkaisut at gmail.com Tue Jul 28 02:47:21 2020 From: ratkaisut at gmail.com (Sten Kultakangas) Date: Tue Jul 28 03:02:40 2020 Subject: [odb-users] composite ID containing an auto-incrementable field In-Reply-To: References: Message-ID: Hi Boris I was able to produce code which inserts the record to the database, however, i could not retrieve the inserted ID. I suspect mssql::object_statements::id_image() cannot be used with more than one bound value. Can you confirm this? If that's the case, then the following assignment cannot work: obj.key = id (sts.id_image ()); So we would need to generate a totally different alternative to access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::id() Obviously we only need the inserted auto id, not the tenant_id, but i assumed we can reuse the existing code which can be used to generate access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::id() Here's the code const char access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::persist_statement[] = "INSERT INTO [GenericSwitch].[dbo].[Extension] " "([tenant_id], " "[extension], " "[name], " "[type_id], " "[timezone], " "[coverage_map_id], " "[office_hours_map_id], " "[office_holidays_map_id], " "[rec_days]) " "OUTPUT INSERTED.[id],INSERTED.[tenant_id] " "VALUES " "(?, ?, ?, ?, ?, ?, ?, ?, ?)"; void access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: persist (database& db, object_type& obj) { ODB_POTENTIALLY_UNUSED (db); using namespace mssql; mssql::connection& conn ( mssql::transaction::current ().connection ()); statements_type& sts ( conn.statement_cache ().find_object ()); callback (db, obj, callback_event::pre_persist); image_type& im (sts.image ()); binding& imb (sts.insert_image_binding ()); init (im, obj, statement_insert); if (im.version != sts.insert_image_version () || imb.version == 0) { bind (imb.bind, im, statement_insert); sts.insert_image_version (im.version); imb.version++; } { id_image_type& i (sts.id_image ()); binding& b (sts.id_image_binding ()); if (i.version != sts.id_image_version () || b.version == 0) { bind (b.bind, i); sts.id_image_version (i.version); b.version++; } } insert_statement& st (sts.persist_statement ()); if (!st.execute ()) throw object_already_persistent (); obj.key = id (sts.id_image ()); // <--- problem here callback (db, obj, callback_event::post_persist); } access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::id_type access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: id (const id_image_type& i) { mssql::database* db (0); ODB_POTENTIALLY_UNUSED (db); id_type id; { composite_value_traits< ::GenericSwitch::ObjectId, id_mssql >::init ( id, i.id_value, db); } return id; } access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >::id_type access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: id (const image_type& i) { mssql::database* db (0); ODB_POTENTIALLY_UNUSED (db); id_type id; { composite_value_traits< ::GenericSwitch::ObjectId, id_mssql >::init ( id, i.key_value, db); } return id; } void access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: bind (mssql::bind* b, image_type& i, mssql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (sk); using namespace mssql; std::size_t n (0); // key // if (sk == statement_insert) { b[n].type = mssql::bind::bigint; b[n].buffer = &i.key_value.tenant_id_value; b[n].size_ind = &i.key_value.tenant_id_size_ind; n++; } else if (sk != statement_update) { composite_value_traits< ::GenericSwitch::ObjectId, id_mssql >::bind ( b + n, i.key_value, sk); n += 2UL; } // extension // b[n].type = mssql::bind::string; b[n].buffer = &i.extension_value; b[n].size_ind = &i.extension_size_ind; b[n].capacity = static_cast (sizeof (i.extension_value)); n++; // name // b[n].type = mssql::bind::nstring; b[n].buffer = &i.name_value; b[n].size_ind = &i.name_size_ind; b[n].capacity = static_cast (sizeof (i.name_value)); n++; // type_id // b[n].type = mssql::bind::bigint; b[n].buffer = &i.type_id_value; b[n].size_ind = &i.type_id_size_ind; n++; // timezone // b[n].type = mssql::bind::nstring; b[n].buffer = &i.timezone_value; b[n].size_ind = &i.timezone_size_ind; b[n].capacity = static_cast (sizeof (i.timezone_value)); n++; // coverage_map_id // b[n].type = mssql::bind::bigint; b[n].buffer = &i.coverage_map_id_value; b[n].size_ind = &i.coverage_map_id_size_ind; n++; // office_hours_map_id // b[n].type = mssql::bind::bigint; b[n].buffer = &i.office_hours_map_id_value; b[n].size_ind = &i.office_hours_map_id_size_ind; n++; // office_holidays_map_id // b[n].type = mssql::bind::bigint; b[n].buffer = &i.office_holidays_map_id_value; b[n].size_ind = &i.office_holidays_map_id_size_ind; n++; // rec_days // b[n].type = mssql::bind::int_; b[n].buffer = &i.rec_days_value; b[n].size_ind = &i.rec_days_size_ind; n++; } void access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: bind (mssql::bind* b, id_image_type& i) { std::size_t n (0); mssql::statement_kind sk (mssql::statement_select); composite_value_traits< ::GenericSwitch::ObjectId, id_mssql >::bind ( b + n, i.id_value, sk); } void access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: init (image_type& i, const object_type& o, mssql::statement_kind sk) { ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (sk); using namespace mssql; if (i.change_callback_.callback != 0) (i.change_callback_.callback) (i.change_callback_.context); // key // if (sk == statement_insert) { // tenant_id // { long long int const& v = o.key.tenant_id; bool is_null (false); mssql::value_traits< long long int, mssql::id_bigint >::set_image ( i.key_value.tenant_id_value, is_null, v); i.key_value.tenant_id_size_ind = is_null ? SQL_NULL_DATA : 0; } } // extension // { ::std::string const& v = o.extension; bool is_null (false); std::size_t size (0); mssql::value_traits< ::std::string, mssql::id_string >::set_image ( i.extension_value, sizeof (i.extension_value) - 1, size, is_null, v); i.extension_size_ind = is_null ? SQL_NULL_DATA : static_cast (size); } // name // { ::std::string const& v = o.name; bool is_null (false); std::size_t size (0); mssql::value_traits< ::std::string, mssql::id_nstring >::set_image ( i.name_value, sizeof (i.name_value) / 2 - 1, size, is_null, v); i.name_size_ind = is_null ? SQL_NULL_DATA : static_cast (size * 2); } // type_id // { ::GenericSwitch::ExtensionType const& v = o.type_id; bool is_null (false); mssql::value_traits< ::GenericSwitch::ExtensionType, mssql::id_bigint >::set_image ( i.type_id_value, is_null, v); i.type_id_size_ind = is_null ? SQL_NULL_DATA : 0; } // timezone // { ::std::string const& v = o.timezone; bool is_null (false); std::size_t size (0); mssql::value_traits< ::std::string, mssql::id_nstring >::set_image ( i.timezone_value, sizeof (i.timezone_value) / 2 - 1, size, is_null, v); i.timezone_size_ind = is_null ? SQL_NULL_DATA : static_cast (size * 2); } // coverage_map_id // { ::odb::nullable< long long int > const& v = o.coverage_map_id; bool is_null (true); mssql::value_traits< ::odb::nullable< long long int >, mssql::id_bigint >::set_image ( i.coverage_map_id_value, is_null, v); i.coverage_map_id_size_ind = is_null ? SQL_NULL_DATA : 0; } // office_hours_map_id // { ::odb::nullable< long long int > const& v = o.office_hours_map_id; bool is_null (true); mssql::value_traits< ::odb::nullable< long long int >, mssql::id_bigint >::set_image ( i.office_hours_map_id_value, is_null, v); i.office_hours_map_id_size_ind = is_null ? SQL_NULL_DATA : 0; } // office_holidays_map_id // { ::odb::nullable< long long int > const& v = o.office_holidays_map_id; bool is_null (true); mssql::value_traits< ::odb::nullable< long long int >, mssql::id_bigint >::set_image ( i.office_holidays_map_id_value, is_null, v); i.office_holidays_map_id_size_ind = is_null ? SQL_NULL_DATA : 0; } // rec_days // { ::odb::nullable< int > const& v = o.rec_days; bool is_null (true); mssql::value_traits< ::odb::nullable< int >, mssql::id_int >::set_image ( i.rec_days_value, is_null, v); i.rec_days_size_ind = is_null ? SQL_NULL_DATA : 0; } } void access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: init (object_type& o, const image_type& i, database* db) { ODB_POTENTIALLY_UNUSED (o); ODB_POTENTIALLY_UNUSED (i); ODB_POTENTIALLY_UNUSED (db); // key // { ::GenericSwitch::ObjectId& v = o.key; composite_value_traits< ::GenericSwitch::ObjectId, id_mssql >::init ( v, i.key_value, db); } // extension // { ::std::string& v = o.extension; mssql::value_traits< ::std::string, mssql::id_string >::set_value ( v, i.extension_value, static_cast (i.extension_size_ind), i.extension_size_ind == SQL_NULL_DATA); } // name // { ::std::string& v = o.name; mssql::value_traits< ::std::string, mssql::id_nstring >::set_value ( v, i.name_value, static_cast (i.name_size_ind / 2), i.name_size_ind == SQL_NULL_DATA); } // type_id // { ::GenericSwitch::ExtensionType& v = o.type_id; mssql::value_traits< ::GenericSwitch::ExtensionType, mssql::id_bigint >::set_value ( v, i.type_id_value, i.type_id_size_ind == SQL_NULL_DATA); } // timezone // { ::std::string& v = o.timezone; mssql::value_traits< ::std::string, mssql::id_nstring >::set_value ( v, i.timezone_value, static_cast (i.timezone_size_ind / 2), i.timezone_size_ind == SQL_NULL_DATA); } // coverage_map_id // { ::odb::nullable< long long int >& v = o.coverage_map_id; mssql::value_traits< ::odb::nullable< long long int >, mssql::id_bigint >::set_value ( v, i.coverage_map_id_value, i.coverage_map_id_size_ind == SQL_NULL_DATA); } // office_hours_map_id // { ::odb::nullable< long long int >& v = o.office_hours_map_id; mssql::value_traits< ::odb::nullable< long long int >, mssql::id_bigint >::set_value ( v, i.office_hours_map_id_value, i.office_hours_map_id_size_ind == SQL_NULL_DATA); } // office_holidays_map_id // { ::odb::nullable< long long int >& v = o.office_holidays_map_id; mssql::value_traits< ::odb::nullable< long long int >, mssql::id_bigint >::set_value ( v, i.office_holidays_map_id_value, i.office_holidays_map_id_size_ind == SQL_NULL_DATA); } // rec_days // { ::odb::nullable< int >& v = o.rec_days; mssql::value_traits< ::odb::nullable< int >, mssql::id_int >::set_value ( v, i.rec_days_value, i.rec_days_size_ind == SQL_NULL_DATA); } } void access::object_traits_impl< ::GenericSwitch::Extension, id_mssql >:: init (id_image_type& i, const id_type& id) { mssql::statement_kind sk (mssql::statement_select); { composite_value_traits< ::GenericSwitch::ObjectId, id_mssql >::init ( i.id_value, id, sk); } } On Fri, Jul 24, 2020 at 2:17 PM Boris Kolpackov wrote: > Sten Kultakangas writes: > > > Boris, I am going to make the necessary modifications to > > odb/relational/source.cxx and odb/relational/mssql/source.cxx but i > wonder > > if you have some work-in-progress branch having the relevant > modifications > > that I can easily backport to the stable 2.5.0 branch ? > > No, I haven't looked into this. > > > > If you haven't yet worked on this issue, then do you have instructions > for > > contributors on how to make a patch that can be incorporated into the > > official version control branch ? > > You can either email the patch directly or create a pull request on your > favorite Git hosting platform (GitHub, etc). > > Note that for this to be merged to master we would need the fix for all > the databases as well as a test. > > > > P.S. Actually tenant_id does not belong to the primary key, but i see no > > other way to force odb to generate UPDATE statement having condition > WHERE > > tenant_id=X and id=X which is necessary for data integrity as our API > does > > not currently perform sanity-checks on the user-supplied ID but instead > it > > determines the tenant the API user belongs to. > > One somewhat admittedly hackish way to achieve this could be to "overlay" > two classes over the same database table. One class would have the simple > auto id to be used for persist and the other would have the composite id > without auto to be used for update. You might also need to tweak the > generated database schema depending on the database system used. > From shprotello at mail.ru Tue Jul 28 05:13:21 2020 From: shprotello at mail.ru (=?UTF-8?B?0KHQtdGA0LPQtdC5INCd0LjQutC+0L3QvtCy?=) Date: Tue Jul 28 05:28:31 2020 Subject: [odb-users] crach on vs2019 Message-ID: <1595927601.155188338@f127.i.mail.ru> Hello, ? I have a trouble concerned with migration from VS2015 to VS2019. Under VS2019 ODB crashes at transaction beginning. The call stack is here: ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::connection_factory::database() Line 212?? ?C++ ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::connection::database() Line 39?? ?C++ >?? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::connection::connection(odb::sqlite::connection_factory & cf, int extra_flags) Line 37?? ?C++ ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::connection_pool_factory::pooled_connection::pooled_connection(odb::sqlite::connection_pool_factory & f, int extra_flags) Line 246?? ?C++ ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::connection_pool_factory::create() Line 131?? ?C++ ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::connection_pool_factory::connect() Line 172?? ?C++ ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::database::connection_() Line 182?? ?C++ ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::database::connection() Line 33?? ?C++ ??? ?odb-sqlite-2.5.0-b.17.dll!odb::sqlite::transaction_impl::start() Line 43?? ?C++ ? The sqlite::connection_factory instance db_ member is null. The same issue takes place if a database is being constructed with explicitly specified connection factory instance.?Is there any ideas on that? ? Under VS2015 the same code works well. ? Regards, Sergey ? From boris at codesynthesis.com Tue Jul 28 08:45:24 2020 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Jul 28 09:00:27 2020 Subject: [odb-users] crach on vs2019 In-Reply-To: <1595927601.155188338@f127.i.mail.ru> References: <1595927601.155188338@f127.i.mail.ru> Message-ID: ?????? ??????? writes: > I have a trouble concerned with migration from VS2015 to VS2019. Under > VS2019 ODB crashes at transaction beginning. What update of VS 2019 is this, specifically? Anything interesting about the build (e.g., is it optimized)? Did you try to rebuild everything from scratch (maybe this is a "skew" build)? > The sqlite::connection_factory instance db_ member is null. This member should have been initialized in connection-factory.cxx:188. Can you set a breakpoint on that line and see if you get there and if so what happens then?