diff --git a/include/sqlgen/read.hpp b/include/sqlgen/read.hpp index b773ede..4bb6746 100644 --- a/include/sqlgen/read.hpp +++ b/include/sqlgen/read.hpp @@ -1,6 +1,7 @@ #ifndef SQLGEN_READ_HPP_ #define SQLGEN_READ_HPP_ +#include #include #include "Connection.hpp" @@ -56,13 +57,31 @@ Result read_impl(const Result>& _res, }); } -template +template struct Read { - Result operator()(const auto& _conn) const noexcept { + Result operator()(const auto& _conn) const noexcept { try { - return read_impl( - _conn, where_, limit_); + if constexpr (std::ranges::input_range>) { + return read_impl(_conn, where_, + limit_); + + } else { + const auto extract_result = [](auto&& _vec) -> Result { + if (_vec.size() != 1) { + return error( + "Because the provided type was not a container, the query " + "needs to return exactly one result, but it did return " + + std::to_string(_vec.size()) + " results."); + } + return std::move(_vec[0]); + }; + + return read_impl, WhereType, OrderByType, LimitType>( + _conn, where_, limit_) + .and_then(extract_result); + } + } catch (std::exception& e) { return error(e.what()); } diff --git a/include/sqlgen/write.hpp b/include/sqlgen/write.hpp index 10a8202..52c5136 100644 --- a/include/sqlgen/write.hpp +++ b/include/sqlgen/write.hpp @@ -14,7 +14,6 @@ #include "Result.hpp" #include "internal/batch_size.hpp" #include "internal/to_str_vec.hpp" -#include "transpilation/has_value_type.hpp" #include "transpilation/to_create_table.hpp" #include "transpilation/to_insert.hpp" diff --git a/tests/sqlite/test_single_read.cpp b/tests/sqlite/test_single_read.cpp new file mode 100644 index 0000000..742a964 --- /dev/null +++ b/tests/sqlite/test_single_read.cpp @@ -0,0 +1,42 @@ +#include + +#include +#include +#include +#include +#include + +namespace test_single_read { + +struct Person { + sqlgen::PrimaryKey id; + std::string first_name; + std::string last_name; + int age; +}; + +TEST(sqlite, test_single_read) { + const auto people1 = std::vector( + {Person{ + .id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45}, + Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10}, + Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8}, + Person{ + .id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0}}); + + const auto conn = sqlgen::sqlite::connect(); + + sqlgen::write(conn, people1); + + using namespace sqlgen; + + const auto people2 = + (sqlgen::read | where("id"_c == 0))(conn).value(); + + const auto json1 = rfl::json::write(people1.at(0)); + const auto json2 = rfl::json::write(people2); + + EXPECT_EQ(json1, json2); +} + +} // namespace test_single_read