query select changes
This commit is contained in:
parent
b15b8da31f
commit
4a04a678f9
|
|
@ -12,14 +12,13 @@ list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
|
|||
include(CTest)
|
||||
include(Catch)
|
||||
|
||||
set(POSTGRES_CONNECTION_STRING "postgres://test:test123@127.0.0.1:5432/matador_test")
|
||||
set(POSTGRES_CONNECTION_STRING "postgres://test:test123@127.0.0.1:15432/test")
|
||||
|
||||
configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/connection.hpp @ONLY IMMEDIATE)
|
||||
|
||||
message(STATUS "postgresql connection string: ${POSTGRES_CONNECTION_STRING}")
|
||||
|
||||
set(TEST_SOURCES
|
||||
../../tests/QueryTest.cpp
|
||||
../../tests/QueryTest.cpp
|
||||
../../tests/ConnectionTest.cpp
|
||||
../../tests/QueryRecordTest.cpp
|
||||
|
|
|
|||
|
|
@ -252,7 +252,8 @@ TEST_CASE_METHOD(QueryRecordFixture, "Execute select statement", "[session][reco
|
|||
auto rec = db.query(schema).select({"id", "name", "age"})
|
||||
.from("person")
|
||||
.fetch_one();
|
||||
REQUIRE(rec.at(1).str() == "george");
|
||||
REQUIRE(rec.has_value());
|
||||
REQUIRE(rec->at(1).str() == "george");
|
||||
|
||||
auto name = db.query(schema).select({"name"})
|
||||
.from("person")
|
||||
|
|
@ -386,15 +387,16 @@ TEST_CASE_METHOD(QueryRecordFixture, "Test quoted identifier", "[session][record
|
|||
|
||||
auto res = db.query(schema).select({"from", "to"}).from("quotes").fetch_one();
|
||||
|
||||
REQUIRE("Berlin" == res.at("from").str());
|
||||
REQUIRE("London" == res.at("to").str());
|
||||
REQUIRE(res.has_value());
|
||||
REQUIRE("Berlin" == res->at("from").str());
|
||||
REQUIRE("London" == res->at("to").str());
|
||||
|
||||
db.query(schema).update("quotes").set({{"from", "Hamburg"}, {"to", "New York"}}).where("from"_col == "Berlin").execute();
|
||||
|
||||
res = db.query(schema).select({"from", "to"}).from("quotes").fetch_one();
|
||||
|
||||
REQUIRE("Hamburg" == res.at("from").str());
|
||||
REQUIRE("New York" == res.at("to").str());
|
||||
REQUIRE("Hamburg" == res->at("from").str());
|
||||
REQUIRE("New York" == res->at("to").str());
|
||||
|
||||
db.query(schema).drop().table("quotes").execute();
|
||||
}
|
||||
|
|
@ -188,11 +188,13 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[session]")
|
|||
auto res = db.query(schema).insert().into<flight>("flight").values(f4711).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto f = *db.query(schema).select<flight>().from("flight").fetch_all<flight>().begin();
|
||||
REQUIRE(f.id == 4);
|
||||
REQUIRE(f.pilot_name == "hans");
|
||||
REQUIRE(f.airplane.get() != nullptr);
|
||||
REQUIRE(f.airplane->id == 2);
|
||||
auto f = *db.query(schema)
|
||||
.select<flight>()
|
||||
.from("flight")
|
||||
.fetch_all().begin();
|
||||
REQUIRE(f.at(0).as<unsigned long>() == 4);
|
||||
REQUIRE(f.at(1).as<unsigned long>() == 2);
|
||||
REQUIRE(f.at(2).as<std::string>() == "hans");
|
||||
|
||||
db.query(schema).drop().table("flight").execute();
|
||||
db.query(schema).drop().table("airplane").execute();
|
||||
|
|
@ -236,11 +238,13 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
REQUIRE(res == 1);
|
||||
}
|
||||
|
||||
auto f = *db.query(schema).select<flight>().from("flight").fetch_all<flight>().begin();
|
||||
REQUIRE(f.id == 4);
|
||||
REQUIRE(f.pilot_name == "hans");
|
||||
REQUIRE(f.airplane.get() != nullptr);
|
||||
REQUIRE(f.airplane->id == 1);
|
||||
auto f = *db.query(schema)
|
||||
.select<flight>()
|
||||
.from("flight")
|
||||
.fetch_all().begin();
|
||||
REQUIRE(f.at(0).as<unsigned long>() == 4);
|
||||
REQUIRE(f.at(1).as<unsigned long>() == 1);
|
||||
REQUIRE(f.at(2).as<std::string>() == "hans");
|
||||
|
||||
auto result = db.query(schema).select({"f.id", "ap.brand", "ap.model", "f.pilot_name"})
|
||||
.from({"flight", "f"})
|
||||
|
|
@ -264,5 +268,81 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
|
||||
db.query(schema).drop().table("flight").execute();
|
||||
db.query(schema).drop().table("airplane").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single entity", "[session][join_left][find]") {
|
||||
schema.attach<airplane>("airplane");
|
||||
schema.attach<flight>("flight");
|
||||
db.query(schema).create()
|
||||
.table<airplane>("airplane")
|
||||
.execute();
|
||||
|
||||
db.query(schema).create()
|
||||
.table<flight>("flight")
|
||||
.execute();
|
||||
|
||||
std::vector<entity<airplane>> planes{
|
||||
make_entity<airplane>(1, "Airbus", "A380"),
|
||||
make_entity<airplane>(2, "Boeing", "707"),
|
||||
make_entity<airplane>(3, "Boeing", "747")
|
||||
};
|
||||
|
||||
for (const auto &plane: planes) {
|
||||
auto res = db
|
||||
.query(schema)
|
||||
.insert()
|
||||
.into<airplane>("airplane")
|
||||
.values(*plane)
|
||||
.execute();
|
||||
REQUIRE(res == 1);
|
||||
}
|
||||
|
||||
auto count = db
|
||||
.query(schema)
|
||||
.select({count_all()})
|
||||
.from("airplane")
|
||||
.fetch_value<int>();
|
||||
REQUIRE(count == 3);
|
||||
|
||||
std::vector<entity<flight>> flights{
|
||||
make_entity<flight>(4, planes.at(0), "hans"),
|
||||
make_entity<flight>(5, planes.at(0), "otto"),
|
||||
make_entity<flight>(6, planes.at(1), "george"),
|
||||
make_entity<flight>(7, planes.at(2), "paul")
|
||||
};
|
||||
|
||||
for (const auto &f: flights) {
|
||||
auto res = db.query(schema).insert().into<flight>("flight").values(*f).execute();
|
||||
REQUIRE(res == 1);
|
||||
}
|
||||
|
||||
auto f = *db.query(schema)
|
||||
.select<flight>()
|
||||
.from("flight")
|
||||
.fetch_all().begin();
|
||||
REQUIRE(f.at(0).as<unsigned long>() == 4);
|
||||
REQUIRE(f.at(1).as<unsigned long>() == 1);
|
||||
REQUIRE(f.at(2).as<std::string>() == "hans");
|
||||
|
||||
auto result = db
|
||||
.query(schema)
|
||||
.select({"f.id", "f.airplane_id", "ap.brand", "ap.model", "f.pilot_name"})
|
||||
.from({"flight", "f"})
|
||||
.join_left({"airplane", "ap"})
|
||||
.on("f.airplane_id"_col == "ap.id"_col)
|
||||
.where("f.id"_col == 4)
|
||||
.fetch_one<flight>();
|
||||
|
||||
auto expected_flight = flights[0];
|
||||
|
||||
REQUIRE(result.has_value());
|
||||
REQUIRE(result->id == expected_flight->id);
|
||||
REQUIRE(result->pilot_name == expected_flight->pilot_name);
|
||||
REQUIRE(result->airplane.get());
|
||||
REQUIRE(result->airplane->id == 1);
|
||||
REQUIRE(result->airplane->model == "A380");
|
||||
REQUIRE(result->airplane->brand == "Airbus");
|
||||
|
||||
db.query(schema).drop().table("flight").execute();
|
||||
db.query(schema).drop().table("airplane").execute();
|
||||
}
|
||||
|
|
@ -46,10 +46,11 @@ TEST_CASE_METHOD(SessionFixture, "Session relation test", "[session][relation]")
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Find object with id", "[session][find]") {
|
||||
ses.attach<matador::test::airplane>("airplane");
|
||||
using namespace matador::test;
|
||||
ses.attach<airplane>("airplane");
|
||||
ses.create_schema();
|
||||
auto a380 = ses.insert<test::airplane>(1, "Boeing", "A380");
|
||||
auto a380 = ses.insert<airplane>(1, "Boeing", "A380");
|
||||
|
||||
ses.find<test::airplane>(1);
|
||||
ses.find<airplane>(1);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "book",
|
||||
"fields": {
|
||||
"id": {
|
||||
"type": "unsigned long",
|
||||
"constraint": "primary_key"
|
||||
},
|
||||
"first_name": {
|
||||
"type": "string",
|
||||
"size": 63
|
||||
},
|
||||
"last_name": {
|
||||
"type": "string",
|
||||
"size": 63
|
||||
},
|
||||
"date_of_birth": {
|
||||
"type": "string",
|
||||
"size": 31
|
||||
},
|
||||
"year_of_birth": {
|
||||
"type": "unsigned short"
|
||||
},
|
||||
"distinguished": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "book",
|
||||
"fields": {
|
||||
"id": {
|
||||
"type": "unsigned long",
|
||||
"constraint": "primary_key"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"size": 511
|
||||
},
|
||||
"book_author": {
|
||||
"type": "author",
|
||||
"constraint": {
|
||||
"type": "foreign_key",
|
||||
"references": "id"
|
||||
}
|
||||
},
|
||||
"published_in": {
|
||||
"type": "unsigned_short"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,13 +61,29 @@ public:
|
|||
{
|
||||
return query_result<Type>(fetch());
|
||||
}
|
||||
|
||||
query_result<record> fetch_all();
|
||||
record fetch_one();
|
||||
template<typename Type>
|
||||
Type fetch_value()
|
||||
|
||||
template < class Type >
|
||||
std::optional<Type> fetch_one()
|
||||
{
|
||||
return fetch_one().at(0).as<Type>().value();
|
||||
auto result = query_result<Type>(fetch());
|
||||
auto first = result.begin();
|
||||
if (first == result.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return *first.get();
|
||||
}
|
||||
std::optional<record> fetch_one();
|
||||
|
||||
template<typename Type>
|
||||
std::optional<Type> fetch_value()
|
||||
{
|
||||
const auto result = fetch_one();
|
||||
if (result.has_value()) {
|
||||
return result.value().at(0).as<Type>().value();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
statement prepare();
|
||||
|
|
|
|||
|
|
@ -73,23 +73,30 @@ public:
|
|||
void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes);
|
||||
// void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes);
|
||||
|
||||
template < class Pointer >
|
||||
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &/*attr*/)
|
||||
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr)
|
||||
{
|
||||
if (!x.get()) {
|
||||
x.reset(new typename Pointer::value_type);
|
||||
}
|
||||
pk_reader_.read(*x, column_index_++);
|
||||
if (attr.fetch() == utils::fetch_type::LAZY) {
|
||||
pk_reader_.read(*x, column_index_++);
|
||||
} else {
|
||||
utils::access::process(*this, *x);
|
||||
}
|
||||
}
|
||||
template < class Pointer >
|
||||
void on_has_one(const char * /*id*/, Pointer &x, const utils::foreign_attributes &/*attr*/)
|
||||
void on_has_one(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr)
|
||||
{
|
||||
if (!x.get()) {
|
||||
x.reset(new typename Pointer::value_type);
|
||||
}
|
||||
pk_reader_.read(*x, column_index_++);
|
||||
if (attr.fetch() == utils::fetch_type::LAZY) {
|
||||
pk_reader_.read(*x, column_index_++);
|
||||
} else {
|
||||
utils::access::process(*this, *x);
|
||||
}
|
||||
}
|
||||
|
||||
template<class ContainerType>
|
||||
|
|
|
|||
|
|
@ -14,10 +14,16 @@ query_result<record> query_select_finish::fetch_all()
|
|||
return connection_.fetch(compiler.compile(&data_));
|
||||
}
|
||||
|
||||
record query_select_finish::fetch_one()
|
||||
std::optional<record> query_select_finish::fetch_one()
|
||||
{
|
||||
query_compiler compiler(connection_.dialect());
|
||||
return *connection_.fetch(compiler.compile(&data_)).begin().get();
|
||||
auto result = connection_.fetch(compiler.compile(&data_));
|
||||
auto first = result.begin();
|
||||
if (first == result.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return *first.get();
|
||||
}
|
||||
|
||||
query_context query_select_finish::build() const
|
||||
|
|
|
|||
Loading…
Reference in New Issue