From acdb5575bc1b0c95653d8cd5540aef884d16dfee Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Oct 2026 14:15:44 +0300 Subject: [PATCH 1/2] feat: added string ids support --- brazierORM/include/Model.hpp | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/brazierORM/include/Model.hpp b/brazierORM/include/Model.hpp index a595046..4946fff 100644 --- a/brazierORM/include/Model.hpp +++ b/brazierORM/include/Model.hpp @@ -194,9 +194,9 @@ namespace brazier { return model; } - static std::shared_ptr find(int id, const std::shared_ptr& db) { + static std::shared_ptr find(std::string id, const std::shared_ptr& db) { try { - auto results = query().Where(Derived::primary_key + " = " + std::to_string(id)).Limit(1).get(db); + auto results = query().Where(Derived::primary_key + " = " + id).Limit(1).get(db); if (results.empty()) { Logger::log("No data found by id", "WARNING"); return nullptr; @@ -211,7 +211,12 @@ namespace brazier { } } - static void update(int id, const std::map& data, const std::shared_ptr& db) { + static std::shared_ptr find(int id, const std::shared_ptr& db) { + return Derived::find(std::to_string(id), db); + } + + + static void update(std::string id, const std::map& data, const std::shared_ptr& db) { try { PGconn* conn = db->getConnection(); if (!conn) { @@ -229,7 +234,7 @@ namespace brazier { Logger::log("No valid fields provided for update", "WARNING"); return; } - builder.Update(updateValues).Where(Derived::primary_key + " = " + SQLString::EscapeString(conn, std::to_string(id))); + builder.Update(updateValues).Where(Derived::primary_key + " = " + SQLString::EscapeString(conn, id)); db->execute(builder.get()); } catch (const std::exception& e) { @@ -237,6 +242,10 @@ namespace brazier { } } + static void update(int id, const std::map& data, const std::shared_ptr& db) { + return Derived::update(std::to_string(id), data, db); + } + void delete_() { try { if (!database) throw std::runtime_error("Database connection is not initialized"); @@ -260,7 +269,7 @@ namespace brazier { } } - static void deleteById(int id, const std::shared_ptr& db) { + static void deleteById(std::string id, const std::shared_ptr& db) { try { PGconn* conn = db->getConnection(); if (!conn) { @@ -268,7 +277,7 @@ namespace brazier { return; } SQLQueryBuilder builder(Derived::table_name); - builder.Delete().Where("id = " + SQLString::EscapeString(conn, std::to_string(id))); + builder.Delete().Where("id = " + SQLString::EscapeString(conn, id)); std::string query = builder.get(); db->execute(query); } @@ -277,6 +286,10 @@ namespace brazier { } } + static void deleteById(int id, const std::shared_ptr& db) { + Derived::deleteByID(std::to_string(id), db); + } + static bool deleteWhere(const std::string& condition, const std::shared_ptr& db) { try { PGconn* conn = db->getConnection(); @@ -458,14 +471,18 @@ namespace brazier { return results.front(); } - static std::shared_ptr findOrFail(int id, const std::shared_ptr& db) { + static std::shared_ptr findOrFail(std::string id, const std::shared_ptr& db) { auto model = find(id, db); if (!model) { - throw std::runtime_error("Model with id " + std::to_string(id) + " not found"); + throw std::runtime_error("Model with id " + id + " not found"); } return model; } + static std::shared_ptr findOrFail(int id, const std::shared_ptr& db) { + return Derived::findOrFail(std::to_string(id), db); + } + /* @brief Finds the first model matching the given attributes or creates a new one if none exists. @param attributes A map of attribute names and values to search for. From d8737cfe92091d5321bc1345d90329c9a1487336 Mon Sep 17 00:00:00 2001 From: ksergeev Date: Mon, 12 Oct 2026 23:21:15 +0300 Subject: [PATCH 2/2] fix: fixed problems with non-string id in query, added tests --- brazierORM/include/Model.hpp | 4 ++-- brazierORM/tests/include/migrations.hpp | 31 ++++++++++++++++++++++++- brazierORM/tests/include/models.hpp | 13 +++++++++++ brazierORM/tests/unit/test_model.cpp | 16 +++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/brazierORM/include/Model.hpp b/brazierORM/include/Model.hpp index 962e196..ce75d21 100644 --- a/brazierORM/include/Model.hpp +++ b/brazierORM/include/Model.hpp @@ -196,7 +196,7 @@ namespace brazier { static std::shared_ptr find(std::string id, const std::shared_ptr& db) { try { - auto results = query().Where(Derived::primary_key + " = " + id).Limit(1).get(db); + auto results = query().Where(Derived::primary_key + " = '" + id + "'").Limit(1).get(db); if (results.empty()) { Logger::log("No data found by id", "WARNING"); return nullptr; @@ -277,7 +277,7 @@ namespace brazier { return; } SQLQueryBuilder builder(Derived::table_name); - builder.Delete().Where("id = " + SQLString::EscapeString(conn, id)); + builder.Delete().Where(Derived::primary_key + " = " + SQLString::EscapeString(conn, id)); std::string query = builder.get(); db->execute(query); } diff --git a/brazierORM/tests/include/migrations.hpp b/brazierORM/tests/include/migrations.hpp index 7652eed..644732a 100644 --- a/brazierORM/tests/include/migrations.hpp +++ b/brazierORM/tests/include/migrations.hpp @@ -111,4 +111,33 @@ class CreateTestTableDB : public BaseMigration { return q; } -}; \ No newline at end of file +}; + +class CreateTestUserTable : public BaseMigration { +public: + static std::vector up() { + SQLSchemaBuilder builder("test_user_table"); + std::vector queries; + + queries.push_back(builder + .AddColumn("id_user UUID primary key default gen_random_uuid()") + .AddColumn("test varchar(255)") + .AddColumn("description varchar(255)") + .CreateTable() + ); + + return queries; + } + + static std::vector down() { + SQLSchemaBuilder builder("test_user_table"); + std::vector q; + + q.push_back( + builder.DropTable() + ); + + return q; + } +}; + diff --git a/brazierORM/tests/include/models.hpp b/brazierORM/tests/include/models.hpp index 9f996d4..f8fda0a 100644 --- a/brazierORM/tests/include/models.hpp +++ b/brazierORM/tests/include/models.hpp @@ -59,4 +59,17 @@ class TestModelDB : public Model { TestModelDB() = default; TestModelDB(const std::shared_ptr& db) : Model(db) {} +}; + +class TestUserModel : public Model { +public: + static inline std::string table_name = "test_user_table"; + static inline std::string primary_key = "id_user"; + + static inline std::vector fillable = { "test", "description" }; + static inline std::vector fields = { "id_user", "test", "description" }; + + + TestUserModel() = default; + TestUserModel(const std::shared_ptr& db) : Model(db) {} }; \ No newline at end of file diff --git a/brazierORM/tests/unit/test_model.cpp b/brazierORM/tests/unit/test_model.cpp index e1e2b80..5f95f45 100644 --- a/brazierORM/tests/unit/test_model.cpp +++ b/brazierORM/tests/unit/test_model.cpp @@ -212,4 +212,20 @@ TEST_F(TestModelCase, SaveWithSpecialCharacters) { catch (std::exception& e) { FAIL() << e.what(); } +} + +TEST_F(TestModelCase, SaveUUIdUser) { + try { + manager->migrate(); + std::shared_ptr model = TestUserModel::create({ {"test", "test"}, {"description", "description"} }, 0, db_ptr); + bool res = model->save(); + EXPECT_EQ(res, true); + + auto id = model->getAttribute("id_user"); + std::shared_ptr model2 = TestUserModel::find(id, db_ptr); + EXPECT_NE(model2, nullptr); + } + catch (std::exception& e) { + FAIL() << e.what(); + } } \ No newline at end of file