From songshuran4 at gmail.com Sun Jul 12 12:19:02 2026 From: songshuran4 at gmail.com (ShuRan Song) Date: Mon Jul 13 08:16:09 2026 Subject: [odb-users] Segmentation fault (core dumped) Message-ID: #pragma once #include #include #include #include #include namespace ssr_im { #pragma db object table("user") class User { public: User() {}; User(std::string uid, std::string nickname, std::string password) : _user_id(uid), _nickname(nickname), _password(password) {} User(const std::string uid, const std::string phone) : _user_id(uid ), _nickname(uid), _phone(phone) {} void user_id(const std::string &val) { _user_id = val; } std::string user_id() { return _user_id; } std::string nickname() { if (_nickname) return *_nickname; return std::string(); } void nickname(const std::string &val) { _nickname = val; } std::string description() { if (!_description) return std::string(); return *_description; } void description(const std::string &val) { _description = val; } std::string password() { if (!_password) return std::string(); return *_password; } void password(const std::string &val) { _password = val; } std::string phone() { if (!_phone) return std::string(); return *_phone; } void phone(const std::string &val) { _phone = val; } std::string avatar_id() { if (!_avatar_id) return std::string(); return *_avatar_id; } void avatar_id(const std::string &val) { _avatar_id = val; } private: friend class odb::access; #pragma db id auto unsigned long _id; // ??id #pragma db type("varchar(64)") index unique std::string _user_id; // ??id #pragma db type("varchar(64)") index unique odb::nullable _nickname; // ????-??????????????????? #pragma db type("varchar(64)") odb::nullable _description; // ????-????? #pragma db type("varchar(64)") odb::nullable _password; // ????-??????????????????? #pragma db type("varchar(64)") index unique odb::nullable _phone; // ?????-????? #pragma db type("varchar(64)") odb::nullable _avatar_id; // ??????id-????? }; } // odb -d mysql --generate-query --generate-schema ../../odb/user.hxx // odb -d mysql --generate-query --generate-schema --profile boost/date-time ../../odb/user.hxx #include #include #include #include #include "../../odb/user.hxx" #include "../test/user-odb.hxx" #include #include "../../common/logger.hpp" #include #include namespace ssr_im { class OBDFactory { public: static std::shared_ptr create(std::string user, std::string pswd, std::string host, int port, std::string db, int max_pool, std::string cset) { std::shared_ptr str; // 1. ??????????? std::unique_ptr cpf(new odb ::mysql::connection_pool_factory(max_pool, 0)); // 2. ?????????:MySQL??? MySQL?? ????? MySQL????? MySQL?? socket???? ??? MySQL?????? ??????? // str = std::make_shared(user, pswd, db, host, port, "", cset, 0, std::move(cpf)); str = std::make_shared(user, pswd, db, host, port, nullptr, cset, 0, std::move(cpf)); return str; } }; class UserTable { public: UserTable(std::shared_ptr &db) : _db(db) {} // ?????? bool insert(const std::shared_ptr &user) { try { odb::transaction trans(_db->begin()); _db->persist(*user); trans.commit(); } catch (std::exception &e) { LOG_ERR("????{}?? ?{}", user->nickname(), e.what()); return false; } return true; } // ???? // bool del(const std::shared_ptr &user) // { // try // { // odb::transaction trans(_db->begin()); // // shared_ptr ????? operator*()??????????user.operator*();?? User&? // _db->erase(*user); // // ??get??? shared_ptr ????????(User*)??????????????????? // // _db->erase(*(user.get())); // trans.commit(); // } // catch (std::exception &e) // { // LOG_ERR("????{}?? ?{}", user->nickname(), e.what()); // return false; // } // return true; // } bool update(const std::shared_ptr &user) { try { odb::transaction trans(_db->begin()); _db->update(*user); trans.commit(); } catch (std::exception &e) { LOG_ERR("????{}?? ?{}", user->nickname(), e.what()); return false; } return true; } std::shared_ptr select_by_nickname(const std::string & nickname) { std::shared_ptr str; try { /* code */ odb::transaction trans(_db->begin()); typedef odb::query query; typedef odb::result result; // query() ?? odb::result ?query?????????????????????????? // query_one() ??? odb::result query_one() ?????User*??????????????? str.reset(_db->query_one(query::nickname == nickname)); trans.commit(); } catch (const std::exception &e) { LOG_ERR("???????{}?? ?{}", nickname, e.what()); } return str; } std::shared_ptr select_by_phone(const std::string & phone) { std::shared_ptr str; try { /* code */ odb::transaction trans(_db->begin()); typedef odb::query query; typedef odb::result result; str.reset(_db->query_one(query::phone == phone )); trans.commit(); } catch (const std::exception &e) { LOG_ERR("???????{}?? ?{}", phone, e.what()); } return str; } std::shared_ptr select_by_user_if(const std::string & user_id) { std::shared_ptr str; try { /* code */ odb::transaction trans(_db->begin()); typedef odb::query query; typedef odb::result result; str.reset(_db->query_one(query::user_id == user_id)); trans.commit(); } catch (const std::exception &e) { LOG_ERR("????id???{}?? ?{}", user_id, e.what()); } return str; } // ?user_id??,?????? std::vector select_multi_users(const std::vector &id_list) { // select * from user where id in ('id1', 'id2', ...) if (id_list.empty()) { return std::vector(); } std::vector res; try { odb::transaction trans(_db->begin()); typedef odb::query query; typedef odb::result result; std::stringstream ss; ss << "user_id in ("; for (const auto &id : id_list) { ss << "'" << id << "',"; } std::string condition = ss.str(); condition.pop_back(); condition += ")"; result r(_db->query(condition)); for (result::iterator i(r.begin()); i != r.end(); ++i) { res.push_back(*i); } trans.commit(); } catch (std::exception &e) { LOG_ERR("????ID????????:{}?", e.what()); } return res; } private: std::shared_ptr _db; }; } #include "user-odb.hxx" // #include "../../odb/user.hxx" #include "../../common/logger.hpp" #include "../source/mysql_user.hpp" DEFINE_bool(run_mode, false, "????????false-??? true-???"); DEFINE_string(log_file, "", "?????????????????"); DEFINE_int32(log_level, 0, "????????????????"); void insert(ssr_im::UserTable &user) { auto u1 = std::make_shared("user1", "lxr", "123456"); auto u2 = std::make_shared("user2", "ayq", "888888"); bool ret = user.insert(u1); if (!ret) { std::cout << "????" << std::endl; } ret = user.insert(u2); if (!ret) { std::cout << "????" << std::endl; } } int main(int argc, char *argv[]) { google::ParseCommandLineFlags(&argc, &argv, true); ssr_im::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level); auto db = ssr_im::OBDFactory::create("root", "123456", "127.0.0.1", 3306 , "ssr_im", 1, "utf8"); ssr_im::UserTable users(db); insert(users); // odb::mysql::database db("root", "123456", "ssr_im", "127.0.0.1", 3306); // odb::transaction t(db.begin()); // std::cout << "begin ok" << std::endl; // t.commit(); // std::cout << "commit ok" << std::endl; } ????????????????Segmentation fault (core dumped)??? _db->persist(*user); ????????? From boris at codesynthesis.com Tue Jul 28 09:05:37 2026 From: boris at codesynthesis.com (Boris Kolpackov) Date: Tue Jul 28 09:05:48 2026 Subject: [odb-users] ODB 2.6.0 released Message-ID: We have released ODB version 2.6.0. The complete list of the NEWS file entries for this release is included below. Source code and binary distribution packages for this release are available from: http://www.codesynthesis.com/products/odb/download.xhtml There is also a release entry on GitHub: https://github.com/codesynthesis-com/odb/releases/tag/v2.6.0 For the list of supported platforms and compilers see: https://codesynthesis.com/products/xsd/platforms.xhtml NEWS file entries for ODB version 2.6.0: * Drop support for C++98 with C++11 being the minimum supported version. Specifically: - The ODB compiler now defaults to C++11 (overridable with --std option). - The use of odb::details::unique_ptr was replaced with std::unique_ptr. - The use of odb::details::shared_ptr was replaced with std::shared_ptr. - The use of odb::details::function_wrapper was replaced with std::function. In particular, odb::connection_ptr is now std::shared_ptr. * Support for std::optional mapping when ODB is invoked with --std c++17 or later. In the database the absent value is represented as NULL, similar to odb::nullable. * Support for direct loading of containers of object pointers. By default, object pointers are loaded indirectly, that is, we first fetch their object ids and then we load each object with a separate SELECT statement (unless said object is already in the session's object cache). In certain situations this can lead to unacceptable performance due to the so-called "N+1 Problem". With the direct load we fetch the entire pointed-to objects as part of the initial SELECT statement, which may result in improved performance. For background and details, see Section 15.3, "Dealing with N+1 Problem". The development of this functionality was sponsored by Qube Research & Technologies Limited. * Query columns of mapped C++ types are now comparable to mapped types rather than interface types. For example: enum class state {disabled, enabled}; #pragma db map(state) as(std::string) to(...) from(...) #pragma db object class o { state s; }; query q (query::s == std::string (...)); // Ok in 2.5.0, error now. query q (query::s == state::enabled); // Error in 2.5.0, ok now. Further, if a wrapper type is mapped to another wrapper type, then the query comparison is now to the unwrapped mapped type. Continuing with the above examples: using optional_string = std::optional; using optional_state = std::optional; #pragma db map(optional_state) as(optional_string) to(...) from(...) #pragma db object class o { optional_state s; }; query q (query::s == state::enabled); query q (query::s.is_null ()); * The connection_pool_factory implementation for all databases now provides the recycle() hook which is called when the connection is returned to the pool. * Support for SQLite WAL mode concurrency. For details, refer to Section 18.4, "SQLite Connection Configuration" in the ODB manual. * Ability to provide a connection configurator for SQLite database. The configurator is a callable object (function, lambda, etc) that is called to configure newly created connections, for instance, by executing one or more SQLite PRAGMAs. For details and examples of common configurations, see Section 18.4, "SQLite Connection Configuration" in the ODB manual. * The SQLite runtime is now able to distinguish the primary key constraint violations from other constraint violations and only map the former to the object_already_persistent exception. * Ability to specify minimum SQLite version with the --sqlite-version ODB compiler options. This information is used to enable SQLite version-specific features and workarounds in the generated C++ code and schema. For example: --sqlite-version 3.53.3 Specifically, SQLite 3.35.0 added support for DROP COLUMN which can be used instead of the "logical" drop (set to NULL) during database schema migration. Note also that we still cannot drop columns belonging to foreign keys (typically object pointers) since there is currently (as of 3.53.0) still no way to drop foreign keys. So we unfortunately have to continue using the logical drop for such columns. And SQLite 3.53.0 added support for ALTER COLUMN SET|DROP NOT NULL, which makes the use of the --sqlite-override-null option unnecessary. The default for --sqlite-version in this version of ODB is 3.7.4. * Assumed minimum PostgreSQL server version has been increased to 9.1. This can be overridden with the --pgsql-server-version ODB compiler option. * The lowest supported SQLite version has been raised to 3.7.4. * The Qt profile (libodb-qt) no longer supports Qt5, only Qt6.