#include #include "matador/sql/connection.hpp" #include "matador/query/criteria.hpp" #include "matador/query/query.hpp" #include "matador/query/column.hpp" #include "models/person.hpp" #include "QueryFixture.hpp" #include #include using namespace matador::sql; using namespace matador::object; using namespace matador::query; using namespace matador::test; TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][create]") { REQUIRE(repo.attach("person")); auto stmt = query::create() .table("person", repo) .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 0); tables_to_drop.emplace("person"); check_table_exists("person"); const std::vector cols = {"id", "name", "age", "image"}; const auto fields = db.describe("person"); REQUIRE(fields.is_ok()); for (const auto &fld : *fields) { REQUIRE(std::find(cols.begin(), cols.end(), fld.name()) != cols.end()); } } TEST_CASE_METHOD(QueryFixture, "Test insert statement", "[query][statement][insert]") { using namespace matador::test; REQUIRE(repo.attach("person")); auto stmt = query::create() .table("person", repo) .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 0); tables_to_drop.emplace("person"); check_table_exists("person"); person george{1, "george", 45, {1,2,3,4}}; stmt = query::insert() .into("person", repo) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); res = stmt->bind(george) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); auto row = query::select(repo) .from("person") .fetch_one(db); REQUIRE(row.is_ok()); REQUIRE(*row != nullptr); REQUIRE((*row)->id == 1); REQUIRE((*row)->name == "george"); REQUIRE((*row)->age == 45); REQUIRE((*row)->image == matador::utils::blob{1,2,3,4}); } TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][update]") { using namespace matador::test; using namespace matador::utils; REQUIRE(repo.attach("person")); auto stmt = query::create() .table("person", repo) .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 0); tables_to_drop.emplace("person"); check_table_exists("person"); person george{1, "george", 45, {1,2,3,4}}; stmt = query::insert() .into("person", repo) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); res = stmt->bind(george) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); auto row = query::select(repo) .from("person") .fetch_one(db); REQUIRE(row.is_ok()); REQUIRE(*row != nullptr); REQUIRE((*row)->id == 1); REQUIRE((*row)->name == "george"); REQUIRE((*row)->age == 45); REQUIRE((*row)->image == blob{1,2,3,4}); george.age = 36; george.image = {5,6,7,8}; stmt = query::update("person") .set(generator::column_value_pairs()) .where("id"_col == _) .prepare(db); REQUIRE(stmt); res = stmt->bind(george) .bind(4, george.id) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); row = query::select(repo) .from("person") .fetch_one(db); REQUIRE(row.is_ok()); REQUIRE(*row != nullptr); REQUIRE((*row)->id == 1); REQUIRE((*row)->name == "george"); REQUIRE((*row)->age == 36); REQUIRE((*row)->image == blob{5,6,7,8}); } TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][delete]") { using namespace matador::test; REQUIRE(repo.attach("person")); auto stmt = query::create() .table("person", repo) .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 0); tables_to_drop.emplace("person"); check_table_exists("person"); stmt = query::insert() .into("person", repo) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); std::vector peoples { {1,"george", 45, {1,2,3,4}}, {2,"jane", 36, {1,2,3,4}}, {3,"lukas", 68, {1,2,3,4}}, {4,"merlin", 99, {1,2,3,4}} }; for (const auto &p : peoples) { res = stmt->bind(p) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); stmt->reset(); } auto select_stmt = query::select(repo) .from("person") .where("name"_col == matador::utils::_) .prepare(db); REQUIRE(select_stmt); auto rows = select_stmt->bind(0, "jane") .fetch(); REQUIRE(rows.is_ok()); for (const auto &r : *rows) { constexpr size_t index = 1; REQUIRE(r.id == peoples[index].id); REQUIRE(r.name == peoples[index].name); REQUIRE(r.age == peoples[index].age); REQUIRE(r.image == peoples[index].image); } stmt = query::remove() .from("person") .where("name"_col == matador::utils::_) .prepare(db); REQUIRE(stmt); res = stmt->bind(0, "jane") .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); select_stmt->reset(); auto row = select_stmt->bind(0, "jane") .fetch_one(); REQUIRE(row.is_ok()); REQUIRE(*row == nullptr); stmt->reset(); res = stmt->bind(0, "merlin") .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); select_stmt->reset(); row = select_stmt->bind(0, "merlin") .fetch_one(); REQUIRE(row.is_ok()); REQUIRE(*row == nullptr); } TEST_CASE_METHOD(QueryFixture, "Test reuse prepared statement", "[query][statement][reuse]") { using namespace matador::test; REQUIRE(repo.attach("person")); auto stmt = query::create() .table("person", repo) .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 0); tables_to_drop.emplace("person"); check_table_exists("person"); stmt = query::insert() .into("person", repo) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); std::vector peoples { {1,"george", 45, {1,2,3,4}}, {2,"jane", 36, {1,2,3,4}}, {3,"lukas", 68, {1,2,3,4}}, {4,"merlin", 99, {1,2,3,4}} }; for (const auto &p : peoples) { res = stmt->bind(p) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); stmt->reset(); } stmt = query::select(repo) .from("person") .prepare(db); REQUIRE(stmt); auto rows = stmt->fetch(); REQUIRE(rows.is_ok()); size_t index = 0; for (const auto &r : *rows) { REQUIRE(r.id == peoples[index].id); REQUIRE(r.name == peoples[index].name); REQUIRE(r.age == peoples[index].age); REQUIRE(r.image == peoples[index].image); ++index; } stmt->reset(); rows = stmt->fetch(); REQUIRE(rows.is_ok()); index = 0; for (const auto &r : *rows) { REQUIRE(r.id == peoples[index].id); REQUIRE(r.name == peoples[index].name); REQUIRE(r.age == peoples[index].age); REQUIRE(r.image == peoples[index].image); ++index; } }