use table metas where possible
This commit is contained in:
parent
ac53526a27
commit
b9f5819be5
|
|
@ -33,6 +33,7 @@ set(TEST_SOURCES
|
||||||
../../../test/backends/TypeTraitsTest.cpp
|
../../../test/backends/TypeTraitsTest.cpp
|
||||||
../../../test/utils/record_printer.hpp
|
../../../test/utils/record_printer.hpp
|
||||||
../../../test/utils/record_printer.cpp
|
../../../test/utils/record_printer.cpp
|
||||||
|
../../../test/models/model_metas.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARY_TEST_TARGET PostgresTests)
|
set(LIBRARY_TEST_TARGET PostgresTests)
|
||||||
|
|
|
||||||
|
|
@ -22,18 +22,12 @@ using namespace matador::test;
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::object;
|
using namespace matador::object;
|
||||||
using namespace matador::query;
|
using namespace matador::query;
|
||||||
|
using namespace matador::utils;
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Insert and select basic datatypes", "[query][datatypes]") {
|
TEST_CASE_METHOD(QueryFixture, "Insert and select basic datatypes", "[query][datatypes]") {
|
||||||
REQUIRE(repo.attach<types>("types"));
|
REQUIRE(repo.attach<types>("types")
|
||||||
auto obj = object_generator::generate<types>(repo.repo(), "types");
|
.and_then([this] {return repo.create(db); }));
|
||||||
auto res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
tables_to_drop.emplace("types");
|
|
||||||
float float_value = 2.44557f;
|
float float_value = 2.44557f;
|
||||||
double double_value = 11111.23433345;
|
double double_value = 11111.23433345;
|
||||||
int8_t cval = 'c';
|
int8_t cval = 'c';
|
||||||
|
|
@ -74,16 +68,16 @@ TEST_CASE_METHOD(QueryFixture, "Insert and select basic datatypes", "[query][dat
|
||||||
blob_val
|
blob_val
|
||||||
};
|
};
|
||||||
|
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("types", generator::columns<types>(repo))
|
.into("types", generator::columns<types>(repo))
|
||||||
.values(t)
|
.values(t)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
auto result = query::select<types>(repo)
|
auto result = query::select<types>(repo)
|
||||||
.from("types")
|
.from("types")
|
||||||
.fetch_one<types>(db);
|
.fetch_one<types>(db);
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
REQUIRE(*result != nullptr);
|
REQUIRE(*result != nullptr);
|
||||||
|
|
||||||
|
|
@ -108,9 +102,6 @@ TEST_CASE_METHOD(QueryFixture, "Insert and select basic datatypes", "[query][dat
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][identifier]" ) {
|
TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][identifier]" ) {
|
||||||
using namespace matador::sql;
|
|
||||||
using namespace matador::utils;
|
|
||||||
|
|
||||||
auto res = query::create()
|
auto res = query::create()
|
||||||
.table("quotes")
|
.table("quotes")
|
||||||
.columns({
|
.columns({
|
||||||
|
|
@ -169,9 +160,6 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][ident
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD( QueryFixture, "Test quoted column names", "[query][quotes][column]" ) {
|
TEST_CASE_METHOD( QueryFixture, "Test quoted column names", "[query][quotes][column]" ) {
|
||||||
using namespace matador::sql;
|
|
||||||
using namespace matador::utils;
|
|
||||||
|
|
||||||
const auto start_quote = db.dialect().token_at(dialect_token::StartQuote);
|
const auto start_quote = db.dialect().token_at(dialect_token::StartQuote);
|
||||||
const auto end_quote = db.dialect().token_at(dialect_token::EndQuote);
|
const auto end_quote = db.dialect().token_at(dialect_token::EndQuote);
|
||||||
|
|
||||||
|
|
@ -213,9 +201,6 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted column names", "[query][quotes][col
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test quoted literals", "[query][quotes][literals]") {
|
TEST_CASE_METHOD(QueryFixture, "Test quoted literals", "[query][quotes][literals]") {
|
||||||
using namespace matador::sql;
|
|
||||||
using namespace matador::utils;
|
|
||||||
|
|
||||||
auto res = query::create()
|
auto res = query::create()
|
||||||
.table("escapes")
|
.table("escapes")
|
||||||
.columns({
|
.columns({
|
||||||
|
|
@ -285,18 +270,8 @@ TEST_CASE_METHOD(QueryFixture, "Test quoted literals", "[query][quotes][literals
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test describe table", "[query][describe][table]") {
|
TEST_CASE_METHOD(QueryFixture, "Test describe table", "[query][describe][table]") {
|
||||||
using namespace matador::sql;
|
REQUIRE(repo.attach<types>("types")
|
||||||
|
.and_then([this] { return repo.create(db); }));
|
||||||
REQUIRE(repo.attach<types>("types"));
|
|
||||||
auto obj = object_generator::generate<types>(repo.repo(), "types");
|
|
||||||
auto res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
tables_to_drop.emplace("types");
|
|
||||||
|
|
||||||
const auto columns = db.describe("types");
|
const auto columns = db.describe("types");
|
||||||
REQUIRE(columns.is_ok());
|
REQUIRE(columns.is_ok());
|
||||||
|
|
@ -365,20 +340,12 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key", "[query][primary key]") {
|
||||||
using namespace matador::test::temporary;
|
using namespace matador::test::temporary;
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
|
|
||||||
REQUIRE(repo.attach<pk>("pk"));
|
REQUIRE(repo.attach<pk>("pk")
|
||||||
auto obj = object_generator::generate<pk>(repo.repo(), "pk");
|
.and_then([this] { return repo.create(db); }));
|
||||||
auto res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
tables_to_drop.emplace("pk");
|
|
||||||
|
|
||||||
pk pk1{ 7, "george" };
|
pk pk1{ 7, "george" };
|
||||||
|
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("pk", generator::columns<pk>(repo))
|
.into("pk", generator::columns<pk>(repo))
|
||||||
.values(pk1)
|
.values(pk1)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
|
|
@ -395,18 +362,9 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key", "[query][primary key]") {
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test primary key prepared", "[query][primary key][prepared]") {
|
TEST_CASE_METHOD(QueryFixture, "Test primary key prepared", "[query][primary key][prepared]") {
|
||||||
using namespace matador::test::temporary;
|
using namespace matador::test::temporary;
|
||||||
using namespace matador::sql;
|
|
||||||
|
|
||||||
REQUIRE(repo.attach<pk>("pk"));
|
REQUIRE(repo.attach<pk>("pk")
|
||||||
auto obj = object_generator::generate<pk>(repo.repo(), "pk");
|
.and_then([this] { return repo.create(db); }));
|
||||||
auto res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
tables_to_drop.emplace("pk");
|
|
||||||
|
|
||||||
pk pk1{ 7, "george" };
|
pk pk1{ 7, "george" };
|
||||||
|
|
||||||
|
|
@ -414,9 +372,9 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key prepared", "[query][primary key
|
||||||
.into("pk", generator::columns<pk>(repo))
|
.into("pk", generator::columns<pk>(repo))
|
||||||
.values(generator::placeholders<pk>())
|
.values(generator::placeholders<pk>())
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
||||||
res = stmt->bind(pk1)
|
auto res = stmt->bind(pk1)
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
|
||||||
|
|
@ -9,30 +9,28 @@
|
||||||
#include "catch2/catch_test_macros.hpp"
|
#include "catch2/catch_test_macros.hpp"
|
||||||
|
|
||||||
namespace matador::test {
|
namespace matador::test {
|
||||||
|
|
||||||
QueryFixture::QueryFixture()
|
QueryFixture::QueryFixture()
|
||||||
: db(connection::dns)
|
: db(connection::dns)
|
||||||
, repo(db.dialect().default_schema_name())
|
, repo(db.dialect().default_schema_name()) {
|
||||||
{
|
|
||||||
REQUIRE(db.open());
|
REQUIRE(db.open());
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryFixture::~QueryFixture() {
|
QueryFixture::~QueryFixture() {
|
||||||
while (!tables_to_drop.empty()) {
|
while (!tables_to_drop.empty()) {
|
||||||
drop_table_if_exists(tables_to_drop.top());
|
drop_table_if_exists(tables_to_drop.top());
|
||||||
tables_to_drop.pop();
|
tables_to_drop.pop();
|
||||||
}
|
}
|
||||||
|
REQUIRE(repo.drop(db));
|
||||||
|
REQUIRE(db.close());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueryFixture::check_table_exists(const std::string &table_name) const
|
void QueryFixture::check_table_exists(const std::string &table_name) const {
|
||||||
{
|
|
||||||
auto result = db.exists(table_name);
|
auto result = db.exists(table_name);
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
REQUIRE(*result);
|
REQUIRE(*result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueryFixture::check_table_not_exists(const std::string &table_name) const
|
void QueryFixture::check_table_not_exists(const std::string &table_name) const {
|
||||||
{
|
|
||||||
auto result = db.exists(table_name);
|
auto result = db.exists(table_name);
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
REQUIRE(!*result);
|
REQUIRE(!*result);
|
||||||
|
|
@ -41,7 +39,7 @@ void QueryFixture::check_table_not_exists(const std::string &table_name) const
|
||||||
void QueryFixture::drop_table_if_exists(const std::string &table_name) const {
|
void QueryFixture::drop_table_if_exists(const std::string &table_name) const {
|
||||||
const auto result = db.exists(table_name).and_then([&table_name, this](const bool exists) {
|
const auto result = db.exists(table_name).and_then([&table_name, this](const bool exists) {
|
||||||
if (exists) {
|
if (exists) {
|
||||||
auto res = query::query::drop()
|
auto res = query::query::drop()
|
||||||
.table(table_name)
|
.table(table_name)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res);
|
REQUIRE(res);
|
||||||
|
|
@ -50,5 +48,4 @@ void QueryFixture::drop_table_if_exists(const std::string &table_name) const {
|
||||||
return utils::ok(true);
|
return utils::ok(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -207,8 +207,7 @@ TEST_CASE_METHOD(QueryFixture, "Create and drop table statement with foreign key
|
||||||
check_table_not_exists("airplane");
|
check_table_not_exists("airplane");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Execute insert record statement", "[query][record]")
|
TEST_CASE_METHOD(QueryFixture, "Execute insert record statement", "[query][record]") {
|
||||||
{
|
|
||||||
auto res = query::create()
|
auto res = query::create()
|
||||||
.table("person")
|
.table("person")
|
||||||
.columns({
|
.columns({
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "matador/query/table_column.hpp"
|
#include "matador/query/table_column.hpp"
|
||||||
|
|
||||||
#include "models/person.hpp"
|
#include "models/person.hpp"
|
||||||
|
#include "models/model_metas.hpp"
|
||||||
|
|
||||||
#include "QueryFixture.hpp"
|
#include "QueryFixture.hpp"
|
||||||
|
|
||||||
|
|
@ -16,11 +17,12 @@
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::object;
|
using namespace matador::object;
|
||||||
using namespace matador::query;
|
using namespace matador::query;
|
||||||
|
using namespace matador::query::meta;
|
||||||
|
using namespace matador::utils;
|
||||||
using namespace matador::test;
|
using namespace matador::test;
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][create]") {
|
TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][create]") {
|
||||||
REQUIRE(repo.attach<matador::test::person>("person"));
|
const auto obj = object_generator::generate<person>(repo.repo(), "persons");
|
||||||
const auto obj = object_generator::generate<person>(repo.repo(), "person");
|
|
||||||
auto stmt = query::create()
|
auto stmt = query::create()
|
||||||
.table(obj->name())
|
.table(obj->name())
|
||||||
.columns(obj->attributes())
|
.columns(obj->attributes())
|
||||||
|
|
@ -31,11 +33,11 @@ TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][crea
|
||||||
auto res = stmt->execute();
|
auto res = stmt->execute();
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 0);
|
REQUIRE(*res == 0);
|
||||||
tables_to_drop.emplace("person");
|
tables_to_drop.emplace("persons");
|
||||||
|
|
||||||
check_table_exists("person");
|
check_table_exists("persons");
|
||||||
const std::vector<std::string> cols = {"id", "name", "age", "image"};
|
const std::vector<std::string> cols = {"id", "name", "age", "image"};
|
||||||
const auto fields = db.describe("person");
|
const auto fields = db.describe("persons");
|
||||||
REQUIRE(fields.is_ok());
|
REQUIRE(fields.is_ok());
|
||||||
|
|
||||||
for (const auto &fld : *fields) {
|
for (const auto &fld : *fields) {
|
||||||
|
|
@ -44,39 +46,27 @@ TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][crea
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test insert statement", "[query][statement][insert]") {
|
TEST_CASE_METHOD(QueryFixture, "Test insert statement", "[query][statement][insert]") {
|
||||||
using namespace matador::test;
|
|
||||||
|
|
||||||
REQUIRE(repo.attach<person>("person"));
|
REQUIRE(repo.attach<person>("persons")
|
||||||
const auto obj = object_generator::generate<person>(repo.repo(), "person");
|
.and_then([this] { return repo.create(db);}));
|
||||||
auto stmt = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.prepare(db);
|
|
||||||
REQUIRE(stmt);
|
|
||||||
|
|
||||||
auto res = stmt->execute();
|
check_table_exists(PERSON.table_name());
|
||||||
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}};
|
person george{1, "george", 45, {1,2,3,4}};
|
||||||
|
|
||||||
stmt = query::insert()
|
auto stmt = query::insert()
|
||||||
.into<person>("person", repo)
|
.into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.values(generator::placeholders<person>())
|
.values(generator::placeholders<person>())
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
||||||
res = stmt->bind(george)
|
auto res = stmt->bind(george)
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
auto row = query::select<person>(repo)
|
auto row = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.fetch_one<person>(db);
|
.fetch_one<person>(db);
|
||||||
REQUIRE(row.is_ok());
|
REQUIRE(row.is_ok());
|
||||||
|
|
||||||
|
|
@ -88,40 +78,26 @@ TEST_CASE_METHOD(QueryFixture, "Test insert statement", "[query][statement][inse
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][update]") {
|
TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][update]") {
|
||||||
using namespace matador::test;
|
REQUIRE(repo.attach<person>("persons")
|
||||||
using namespace matador::utils;
|
.and_then([this] { return repo.create(db);}));
|
||||||
|
|
||||||
REQUIRE(repo.attach<matador::test::person>("person"));
|
check_table_exists(PERSON.table_name());
|
||||||
const auto obj = object_generator::generate<person>(repo.repo(), "person");
|
|
||||||
auto stmt = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.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}};
|
person george{1, "george", 45, {1,2,3,4}};
|
||||||
|
|
||||||
stmt = query::insert()
|
auto stmt = query::insert()
|
||||||
.into<person>("person", repo)
|
.into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.values(generator::placeholders<person>())
|
.values(generator::placeholders<person>())
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
||||||
res = stmt->bind(george)
|
auto res = stmt->bind(george)
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
auto row = query::select<person>(repo)
|
auto row = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.fetch_one<person>(db);
|
.fetch_one<person>(db);
|
||||||
REQUIRE(row.is_ok());
|
REQUIRE(row.is_ok());
|
||||||
|
|
||||||
|
|
@ -133,9 +109,9 @@ TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][upda
|
||||||
|
|
||||||
george.age = 36;
|
george.age = 36;
|
||||||
george.image = {5,6,7,8};
|
george.image = {5,6,7,8};
|
||||||
stmt = query::update("person")
|
stmt = query::update(PERSON)
|
||||||
.set(generator::column_value_pairs<person>())
|
.set(generator::column_value_pairs<person>())
|
||||||
.where("id"_col == _)
|
.where(PERSON.id == _)
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
||||||
|
|
@ -145,8 +121,8 @@ TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][upda
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
row = query::select<person>(repo)
|
row = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.fetch_one<person>(db);
|
.fetch_one<person>(db);
|
||||||
REQUIRE(row.is_ok());
|
REQUIRE(row.is_ok());
|
||||||
|
|
||||||
|
|
@ -158,26 +134,13 @@ TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][upda
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][delete]") {
|
TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][delete]") {
|
||||||
using namespace matador::test;
|
REQUIRE(repo.attach<person>("persons")
|
||||||
|
.and_then([this] { return repo.create(db);}));
|
||||||
|
|
||||||
REQUIRE(repo.attach<matador::test::person>("person"));
|
check_table_exists(PERSON.table_name());
|
||||||
const auto obj = object_generator::generate<person>(repo.repo(), "person");
|
|
||||||
auto stmt = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.prepare(db);
|
|
||||||
REQUIRE(stmt);
|
|
||||||
|
|
||||||
auto res = stmt->execute();
|
auto stmt = query::insert()
|
||||||
REQUIRE(res.is_ok());
|
.into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
REQUIRE(*res == 0);
|
|
||||||
tables_to_drop.emplace("person");
|
|
||||||
|
|
||||||
check_table_exists("person");
|
|
||||||
|
|
||||||
stmt = query::insert()
|
|
||||||
.into<person>("person", repo)
|
|
||||||
.values(generator::placeholders<person>())
|
.values(generator::placeholders<person>())
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
@ -190,16 +153,16 @@ TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][dele
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &p : peoples) {
|
for (const auto &p : peoples) {
|
||||||
res = stmt->bind(p)
|
auto res = stmt->bind(p)
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
stmt->reset();
|
stmt->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto select_stmt = query::select<person>(repo)
|
auto select_stmt = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.where("name"_col == matador::utils::_)
|
.where(PERSON.name ==_)
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(select_stmt);
|
REQUIRE(select_stmt);
|
||||||
|
|
||||||
|
|
@ -216,12 +179,12 @@ TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][dele
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt = query::remove()
|
stmt = query::remove()
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.where("name"_col == matador::utils::_)
|
.where(PERSON.name == _)
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
||||||
res = stmt->bind(0, "jane")
|
auto res = stmt->bind(0, "jane")
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
@ -248,26 +211,13 @@ TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][dele
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test reuse prepared statement", "[query][statement][reuse]") {
|
TEST_CASE_METHOD(QueryFixture, "Test reuse prepared statement", "[query][statement][reuse]") {
|
||||||
using namespace matador::test;
|
REQUIRE(repo.attach<matador::test::person>("persons")
|
||||||
|
.and_then([this] { return repo.create(db);}));
|
||||||
|
|
||||||
REQUIRE(repo.attach<matador::test::person>("person"));
|
check_table_exists(PERSON.table_name());
|
||||||
const auto obj = object_generator::generate<person>(repo.repo(), "person");
|
|
||||||
auto stmt = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.prepare(db);
|
|
||||||
REQUIRE(stmt);
|
|
||||||
|
|
||||||
auto res = stmt->execute();
|
auto stmt = query::insert()
|
||||||
REQUIRE(res.is_ok());
|
.into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
REQUIRE(*res == 0);
|
|
||||||
tables_to_drop.emplace("person");
|
|
||||||
|
|
||||||
check_table_exists("person");
|
|
||||||
|
|
||||||
stmt = query::insert()
|
|
||||||
.into<person>("person", repo)
|
|
||||||
.values(generator::placeholders<person>())
|
.values(generator::placeholders<person>())
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
@ -280,15 +230,15 @@ TEST_CASE_METHOD(QueryFixture, "Test reuse prepared statement", "[query][stateme
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &p : peoples) {
|
for (const auto &p : peoples) {
|
||||||
res = stmt->bind(p)
|
auto res = stmt->bind(p)
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
stmt->reset();
|
stmt->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt = query::select<person>(repo)
|
stmt = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "models/person.hpp"
|
#include "models/person.hpp"
|
||||||
#include "models/recipe.hpp"
|
#include "models/recipe.hpp"
|
||||||
#include "models/shipment.hpp"
|
#include "models/shipment.hpp"
|
||||||
|
#include "models/model_metas.hpp"
|
||||||
|
|
||||||
#include "../test/utils/record_printer.hpp"
|
#include "../test/utils/record_printer.hpp"
|
||||||
|
|
||||||
|
|
@ -20,93 +21,59 @@ using namespace matador::object;
|
||||||
using namespace matador::query;
|
using namespace matador::query;
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::test;
|
using namespace matador::test;
|
||||||
|
using namespace matador::query::meta;
|
||||||
META_TABLE(recipes, RECIPE, id, name);
|
|
||||||
META_TABLE(ingredients, INGREDIENT, id, name);
|
|
||||||
META_TABLE(recipe_ingredients, RECIPE_INGREDIENT, recipe_id, ingredient_id);
|
|
||||||
META_TABLE(airplanes, AIRPLANE, id, brand, model);
|
|
||||||
META_TABLE(flights, FLIGHT, id, airplane_id, pilot_name);
|
|
||||||
META_TABLE(shipments, SHIPMENT, id, tracking_number)
|
|
||||||
META_TABLE(packages, PACKAGE, id, weight, shipment_id)
|
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Create table with foreign key relation", "[query][foreign][relation]") {
|
TEST_CASE_METHOD(QueryFixture, "Create table with foreign key relation", "[query][foreign][relation]") {
|
||||||
auto result = repo.attach<airplane>("airplane")
|
auto result = repo.attach<airplane>("airplane")
|
||||||
.and_then( [this] { return repo.attach<flight>("flight");} );
|
.and_then([this] { return repo.attach<flight>("flight");})
|
||||||
|
.and_then([this] {return repo.create(db); });
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
|
|
||||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplane");
|
|
||||||
auto res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
check_table_exists("airplane");
|
check_table_exists("airplane");
|
||||||
tables_to_drop.emplace("airplane");
|
|
||||||
|
|
||||||
obj = object_generator::generate<flight>(repo.repo(), "flight");
|
|
||||||
res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
check_table_exists("flight");
|
check_table_exists("flight");
|
||||||
tables_to_drop.emplace("flight");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[query][where]") {
|
TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[query][where]") {
|
||||||
REQUIRE(repo.attach<person>("person"));
|
REQUIRE(repo.attach<person>("persons"));
|
||||||
const auto obj = object_generator::generate<person>(repo.repo(), "person");
|
auto result = repo.create(db);
|
||||||
auto res = query::create()
|
REQUIRE(result.is_ok());
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
check_table_exists("person");
|
check_table_exists(PERSON.table_name());
|
||||||
tables_to_drop.emplace("person");
|
|
||||||
|
|
||||||
person george{7, "george", 45};
|
person george{7, "george", 45};
|
||||||
george.image.emplace_back(37);
|
george.image.emplace_back(37);
|
||||||
|
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("person", generator::columns<person>(repo))
|
.into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.values(george)
|
.values(george)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
// fetch person as record
|
// fetch person as record
|
||||||
auto result_record = query::select(generator::columns<person>(repo))
|
auto result_record = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.where("id"_col == 7)
|
.where(PERSON.id == 7)
|
||||||
.fetch_all(db);
|
.fetch_all(db);
|
||||||
REQUIRE(result_record.is_ok());
|
REQUIRE(result_record.is_ok());
|
||||||
|
|
||||||
for (const auto &i: *result_record) {
|
for (const auto &i: *result_record) {
|
||||||
REQUIRE(i.size() == 4);
|
REQUIRE(i.size() == 4);
|
||||||
REQUIRE(i.at(0).name() == "person.id");
|
REQUIRE(i.at(0).name() == "persons.id");
|
||||||
REQUIRE(i.at(0).is_integer());
|
REQUIRE(i.at(0).is_integer());
|
||||||
REQUIRE(i.at(0).as<uint32_t>() == george.id);
|
REQUIRE(i.at(0).as<uint32_t>() == george.id);
|
||||||
REQUIRE(i.at(1).name() == "person.name");
|
REQUIRE(i.at(1).name() == "persons.name");
|
||||||
REQUIRE(i.at(1).is_varchar());
|
REQUIRE(i.at(1).is_varchar());
|
||||||
REQUIRE(i.at(1).as<std::string>() == george.name);
|
REQUIRE(i.at(1).as<std::string>() == george.name);
|
||||||
REQUIRE(i.at(2).name() == "person.age");
|
REQUIRE(i.at(2).name() == "persons.age");
|
||||||
REQUIRE(i.at(2).is_integer());
|
REQUIRE(i.at(2).is_integer());
|
||||||
REQUIRE(i.at(2).as<uint32_t>() == george.age);
|
REQUIRE(i.at(2).as<uint32_t>() == george.age);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch person as person
|
// fetch person as person
|
||||||
auto result_person = query::select(generator::columns<person>(repo))
|
auto result_person = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image})
|
||||||
.from("person")
|
.from(PERSON)
|
||||||
.where("id"_col == 7)
|
.where(PERSON.id == 7)
|
||||||
.fetch_all<person>(db);
|
.fetch_all<person>(db);
|
||||||
REQUIRE(result_person.is_ok());
|
REQUIRE(result_person.is_ok());
|
||||||
|
|
||||||
|
|
@ -164,33 +131,13 @@ TEST_CASE_METHOD(QueryFixture, "Execute insert statement", "[query][insert]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][foreign]") {
|
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][foreign]") {
|
||||||
auto result = repo.attach<airplane>("airplane")
|
auto result = repo.attach<airplane>("airplanes")
|
||||||
.and_then( [this] { return repo.attach<flight>("flight");} );
|
.and_then( [this] { return repo.attach<flight>("flights");} )
|
||||||
|
.and_then([this] {return repo.create(db); });
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
|
|
||||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplane");
|
REQUIRE(db.exists(AIRPLANE.table_name()));
|
||||||
auto res = query::create()
|
REQUIRE(db.exists(FLIGHT.table_name()));
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("airplane"));
|
|
||||||
tables_to_drop.emplace("airplane");
|
|
||||||
|
|
||||||
obj = object_generator::generate<flight>(repo.repo(), "flight");
|
|
||||||
res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("flight"));
|
|
||||||
tables_to_drop.emplace("flight");
|
|
||||||
|
|
||||||
std::vector planes{
|
std::vector planes{
|
||||||
object_ptr(new airplane{1, "Airbus", "A380"}),
|
object_ptr(new airplane{1, "Airbus", "A380"}),
|
||||||
|
|
@ -199,8 +146,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("airplane", generator::columns<airplane>(repo))
|
.into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model})
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -208,22 +155,22 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for
|
||||||
}
|
}
|
||||||
|
|
||||||
auto count = query::select({count_all()})
|
auto count = query::select({count_all()})
|
||||||
.from("airplane")
|
.from(AIRPLANE)
|
||||||
.fetch_value<int>(db);
|
.fetch_value<int>(db);
|
||||||
REQUIRE(count.is_ok());
|
REQUIRE(count.is_ok());
|
||||||
REQUIRE(*count == 3);
|
REQUIRE(*count == 3);
|
||||||
|
|
||||||
flight f4711{4, planes.at(1), "hans"};
|
flight f4711{4, planes.at(1), "hans"};
|
||||||
|
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("flight", generator::columns<flight>(repo))
|
.into(FLIGHT, {FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name})
|
||||||
.values(f4711)
|
.values(f4711)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
auto f = query::select(generator::columns<flight>(repo))
|
auto f = query::select({FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name})
|
||||||
.from("flight")
|
.from(FLIGHT)
|
||||||
.fetch_one(db);
|
.fetch_one(db);
|
||||||
REQUIRE(f.is_ok());
|
REQUIRE(f.is_ok());
|
||||||
|
|
||||||
|
|
@ -234,32 +181,12 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left", "[query][foreign][join_left]") {
|
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left", "[query][foreign][join_left]") {
|
||||||
auto result = repo.attach<airplane>("airplanes")
|
auto result = repo.attach<airplane>("airplanes")
|
||||||
.and_then( [this] { return repo.attach<flight>("flights");} );
|
.and_then( [this] { return repo.attach<flight>("flights");} )
|
||||||
|
.and_then([this] {return repo.create(db); });
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
|
|
||||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplanes");
|
REQUIRE(db.exists(AIRPLANE.table_name()));
|
||||||
auto res = query::create()
|
REQUIRE(db.exists(FLIGHT.table_name()));
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("airplanes"));
|
|
||||||
tables_to_drop.emplace("airplanes");
|
|
||||||
|
|
||||||
obj = object_generator::generate<flight>(repo.repo(), "flights");
|
|
||||||
res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("flights"));
|
|
||||||
tables_to_drop.emplace("flights");
|
|
||||||
|
|
||||||
std::vector planes{
|
std::vector planes{
|
||||||
object_ptr(new airplane{1, "Airbus", "A380"}),
|
object_ptr(new airplane{1, "Airbus", "A380"}),
|
||||||
|
|
@ -268,8 +195,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("airplanes", generator::columns<airplane>(repo))
|
.into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model})
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -277,7 +204,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
||||||
}
|
}
|
||||||
|
|
||||||
auto count = query::select({count_all()})
|
auto count = query::select({count_all()})
|
||||||
.from("airplanes")
|
.from(AIRPLANE)
|
||||||
.fetch_value<int>(db).value();
|
.fetch_value<int>(db).value();
|
||||||
REQUIRE(count == 3);
|
REQUIRE(count == 3);
|
||||||
|
|
||||||
|
|
@ -289,16 +216,16 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &f: flights) {
|
for (const auto &f: flights) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("flights", {"id", "airplane_id", "pilot_name"})
|
.into(FLIGHT, {FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name})
|
||||||
.values(*f)
|
.values(*f)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flight_result = query::select(generator::columns<flight>(repo))
|
auto flight_result = query::select({FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name})
|
||||||
.from("flights")
|
.from(FLIGHT)
|
||||||
.fetch_one(db);
|
.fetch_one(db);
|
||||||
REQUIRE(flight_result.is_ok());
|
REQUIRE(flight_result.is_ok());
|
||||||
REQUIRE(flight_result->has_value());
|
REQUIRE(flight_result->has_value());
|
||||||
|
|
@ -306,7 +233,6 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
||||||
REQUIRE(flight_result.value()->at(1).as<uint32_t>() == 1);
|
REQUIRE(flight_result.value()->at(1).as<uint32_t>() == 1);
|
||||||
REQUIRE(flight_result.value()->at(2).as<std::string>() == "hans");
|
REQUIRE(flight_result.value()->at(2).as<std::string>() == "hans");
|
||||||
|
|
||||||
using namespace matador::query::meta;
|
|
||||||
const auto f = FLIGHT.as("f");
|
const auto f = FLIGHT.as("f");
|
||||||
const auto ap = AIRPLANE.as("ap");
|
const auto ap = AIRPLANE.as("ap");
|
||||||
|
|
||||||
|
|
@ -334,32 +260,12 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single entity", "[query][join_left][find]") {
|
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single entity", "[query][join_left][find]") {
|
||||||
auto result = repo.attach<airplane>("airplanes")
|
auto result = repo.attach<airplane>("airplanes")
|
||||||
.and_then( [this] { return repo.attach<flight>("flights");} );
|
.and_then([this] { return repo.attach<flight>("flights");})
|
||||||
|
.and_then([this] {return repo.create(db); });
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
|
|
||||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplanes");
|
REQUIRE(db.exists(AIRPLANE.table_name()));
|
||||||
auto res = query::create()
|
REQUIRE(db.exists(FLIGHT.table_name()));
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("airplanes"));
|
|
||||||
tables_to_drop.emplace("airplanes");
|
|
||||||
|
|
||||||
obj = object_generator::generate<flight>(repo.repo(), "flights");
|
|
||||||
res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("flights"));
|
|
||||||
tables_to_drop.emplace("flights");
|
|
||||||
|
|
||||||
std::vector planes{
|
std::vector planes{
|
||||||
object_ptr(new airplane{1, "Airbus", "A380"}),
|
object_ptr(new airplane{1, "Airbus", "A380"}),
|
||||||
|
|
@ -368,8 +274,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("airplanes", generator::columns<airplane>(repo))
|
.into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model})
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -377,7 +283,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
||||||
}
|
}
|
||||||
|
|
||||||
auto count = query::select({count_all()})
|
auto count = query::select({count_all()})
|
||||||
.from("airplanes")
|
.from(AIRPLANE)
|
||||||
.fetch_value<int>(db);
|
.fetch_value<int>(db);
|
||||||
REQUIRE(count.is_ok());
|
REQUIRE(count.is_ok());
|
||||||
REQUIRE(count->has_value());
|
REQUIRE(count->has_value());
|
||||||
|
|
@ -391,16 +297,16 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &f: flights) {
|
for (const auto &f: flights) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("flights", generator::columns<flight>(repo))
|
.into(FLIGHT, {FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name})
|
||||||
.values(*f)
|
.values(*f)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flight_result = query::select(generator::columns<flight>(repo))
|
auto flight_result = query::select({FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name})
|
||||||
.from("flights")
|
.from(FLIGHT)
|
||||||
.fetch_one(db);
|
.fetch_one(db);
|
||||||
REQUIRE(flight_result.is_ok());
|
REQUIRE(flight_result.is_ok());
|
||||||
REQUIRE(flight_result->has_value());
|
REQUIRE(flight_result->has_value());
|
||||||
|
|
@ -408,7 +314,6 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
||||||
REQUIRE(flight_result.value()->at(1).as<uint32_t>() == 1);
|
REQUIRE(flight_result.value()->at(1).as<uint32_t>() == 1);
|
||||||
REQUIRE(flight_result.value()->at(2).as<std::string>() == "hans");
|
REQUIRE(flight_result.value()->at(2).as<std::string>() == "hans");
|
||||||
|
|
||||||
using namespace matador::query::meta;
|
|
||||||
const auto f = FLIGHT.as("f");
|
const auto f = FLIGHT.as("f");
|
||||||
const auto ap = AIRPLANE.as("ap");
|
const auto ap = AIRPLANE.as("ap");
|
||||||
|
|
||||||
|
|
@ -434,46 +339,12 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship", "[query][join][many_to_many]") {
|
TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship", "[query][join][many_to_many]") {
|
||||||
auto result = repo.attach<ingredient>("ingredients")
|
auto result = repo.attach<ingredient>("ingredients")
|
||||||
.and_then( [this] { return repo.attach<recipe>("recipes"); } );
|
.and_then( [this] { return repo.attach<recipe>("recipes"); } )
|
||||||
|
.and_then([this] {return repo.create(db); });
|
||||||
|
|
||||||
auto obj = object_generator::generate<recipe>(repo.repo(), "recipes");
|
REQUIRE(db.exists(RECIPE.table_name()));
|
||||||
auto res = query::create()
|
REQUIRE(db.exists(INGREDIENT.table_name()));
|
||||||
.table(obj->name())
|
REQUIRE(db.exists(RECIPE_INGREDIENT.table_name()));
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("recipes"));
|
|
||||||
tables_to_drop.emplace("recipes");
|
|
||||||
|
|
||||||
obj = object_generator::generate<ingredient>(repo.repo(), "ingredients");
|
|
||||||
res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("ingredients"));
|
|
||||||
tables_to_drop.emplace("ingredients");
|
|
||||||
|
|
||||||
const auto it = repo.find("recipe_ingredients");
|
|
||||||
REQUIRE(it != repo.end());
|
|
||||||
obj = it->second.node().info().object();
|
|
||||||
// obj = object_generator::generate<recipe_ingredient>(repo.repo(), "recipe_ingredients");
|
|
||||||
res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
REQUIRE(*res == 0);
|
|
||||||
|
|
||||||
REQUIRE(db.exists("recipe_ingredients"));
|
|
||||||
tables_to_drop.emplace("recipe_ingredients");
|
|
||||||
|
|
||||||
std::vector<ingredient> ingredients {
|
std::vector<ingredient> ingredients {
|
||||||
{1, "Apple"},
|
{1, "Apple"},
|
||||||
|
|
@ -486,8 +357,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &i: ingredients) {
|
for (const auto &i: ingredients) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("ingredients", generator::columns<ingredient>(repo))
|
.into(INGREDIENT, {INGREDIENT.id, INGREDIENT.name})
|
||||||
.values(i)
|
.values(i)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -501,8 +372,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &r: recipes) {
|
for (const auto &r: recipes) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("recipes", generator::columns<recipe>(repo))
|
.into(RECIPE, {RECIPE.id, RECIPE.name})
|
||||||
.values(r)
|
.values(r)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -520,11 +391,9 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
||||||
{ 9, 3 }
|
{ 9, 3 }
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace matador::query::meta;
|
|
||||||
|
|
||||||
for (const auto & [recipe_id, ingredient_id]: recipe_ingredients) {
|
for (const auto & [recipe_id, ingredient_id]: recipe_ingredients) {
|
||||||
res = query::insert()
|
auto res = query::insert()
|
||||||
.into("recipe_ingredients", RECIPE_INGREDIENT)
|
.into(RECIPE_INGREDIENT, {RECIPE_INGREDIENT.recipe_id, RECIPE_INGREDIENT.ingredient_id})
|
||||||
.values({recipe_id, ingredient_id})
|
.values({recipe_id, ingredient_id})
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -618,12 +487,8 @@ void print(std::ostream& out, const record& row) {
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many relation", "[query][has_many][eager]") {
|
TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many relation", "[query][has_many][eager]") {
|
||||||
auto result = repo.attach<package>("packages")
|
auto result = repo.attach<package>("packages")
|
||||||
.and_then( [this] { return repo.attach<shipment>("shipments"); } );
|
.and_then([this] { return repo.attach<shipment>("shipments"); })
|
||||||
REQUIRE(result.is_ok());
|
.and_then([this] {return repo.create(db); });
|
||||||
tables_to_drop.emplace("shipments");
|
|
||||||
tables_to_drop.emplace("packages");
|
|
||||||
|
|
||||||
result = repo.create(db);
|
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
|
|
||||||
const std::vector shipments {
|
const std::vector shipments {
|
||||||
|
|
@ -631,8 +496,6 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many relation",
|
||||||
object_ptr{new shipment{2, "0815"}}
|
object_ptr{new shipment{2, "0815"}}
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace matador::query::meta;
|
|
||||||
|
|
||||||
for (const auto &sh: shipments) {
|
for (const auto &sh: shipments) {
|
||||||
auto res = query::insert()
|
auto res = query::insert()
|
||||||
.into(SHIPMENT, SHIPMENT)
|
.into(SHIPMENT, SHIPMENT)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
#include "matador/object/attribute.hpp"
|
|
||||||
#include "matador/object/object_generator.hpp"
|
#include "matador/object/object_generator.hpp"
|
||||||
|
|
||||||
#include "matador/sql/connection.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
|
|
@ -14,12 +13,13 @@
|
||||||
#include "QueryFixture.hpp"
|
#include "QueryFixture.hpp"
|
||||||
|
|
||||||
#include "models/airplane.hpp"
|
#include "models/airplane.hpp"
|
||||||
#include "models/location.hpp"
|
#include "models/model_metas.hpp"
|
||||||
|
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::object;
|
using namespace matador::object;
|
||||||
using namespace matador::query;
|
using namespace matador::query;
|
||||||
using namespace matador::test;
|
using namespace matador::test;
|
||||||
|
using namespace matador::query::meta;
|
||||||
|
|
||||||
namespace matador::test::detail {
|
namespace matador::test::detail {
|
||||||
template<class Type, typename... Args>
|
template<class Type, typename... Args>
|
||||||
|
|
@ -31,14 +31,7 @@ template<class Type, typename... Args>
|
||||||
class StatementTestFixture : public QueryFixture {
|
class StatementTestFixture : public QueryFixture {
|
||||||
public:
|
public:
|
||||||
StatementTestFixture() {
|
StatementTestFixture() {
|
||||||
const auto obj = object_generator::generate<airplane>(repo.repo(), "airplane");
|
REQUIRE(repo.attach<airplane>("airplanes"));
|
||||||
const auto res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
REQUIRE(res.is_ok());
|
|
||||||
tables_to_drop.emplace("airplane");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -51,11 +44,10 @@ protected:
|
||||||
|
|
||||||
TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]") {
|
TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]") {
|
||||||
using namespace matador::utils;
|
using namespace matador::utils;
|
||||||
REQUIRE(repo.attach<airplane>("airplane"));
|
REQUIRE(repo.create(db));
|
||||||
table ap{"airplane"};
|
|
||||||
SECTION("Insert with prepared statement and placeholder") {
|
SECTION("Insert with prepared statement and placeholder") {
|
||||||
auto stmt = query::insert()
|
auto stmt = query::insert()
|
||||||
.into("airplane", generator::columns<airplane>(repo))
|
.into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model})
|
||||||
.values(generator::placeholders<airplane>())
|
.values(generator::placeholders<airplane>())
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt.is_ok());
|
REQUIRE(stmt.is_ok());
|
||||||
|
|
@ -67,8 +59,8 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]
|
||||||
stmt->reset();
|
stmt->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = query::select(generator::columns<airplane>(repo))
|
auto result = query::select({AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model})
|
||||||
.from(ap)
|
.from(AIRPLANE)
|
||||||
.fetch_all<airplane>(db);
|
.fetch_all<airplane>(db);
|
||||||
|
|
||||||
REQUIRE(result.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
|
|
@ -83,7 +75,7 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]
|
||||||
SECTION("Select with prepared statement") {
|
SECTION("Select with prepared statement") {
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
auto res = query::insert()
|
auto res = query::insert()
|
||||||
.into("airplane", generator::columns<airplane>(repo))
|
.into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model})
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -91,8 +83,8 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stmt = query::select(generator::columns<airplane>(repo))
|
auto stmt = query::select(generator::columns<airplane>(repo))
|
||||||
.from(ap)
|
.from(AIRPLANE)
|
||||||
.where("brand"_col == _)
|
.where(AIRPLANE.brand == _)
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt.is_ok());
|
REQUIRE(stmt.is_ok());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,18 +22,12 @@ class TypeTraitsTestFixture : public QueryFixture
|
||||||
public:
|
public:
|
||||||
TypeTraitsTestFixture() {
|
TypeTraitsTestFixture() {
|
||||||
REQUIRE(db.open());
|
REQUIRE(db.open());
|
||||||
const auto obj = matador::object::object_generator::generate<location>(repo.repo(), "location");
|
REQUIRE(repo.attach<location>("location"));
|
||||||
const auto res = query::create()
|
|
||||||
.table(obj->name())
|
|
||||||
.columns(obj->attributes())
|
|
||||||
.constraints(obj->constraints())
|
|
||||||
.execute(db);
|
|
||||||
tables_to_drop.emplace("location");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]") {
|
TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]") {
|
||||||
REQUIRE(repo.attach<location>("location"));
|
REQUIRE(repo.create(db));
|
||||||
SECTION("Insert and select with direct execution") {
|
SECTION("Insert and select with direct execution") {
|
||||||
location loc{1, "center", {1, 2, 3}, Color::Black};
|
location loc{1, "center", {1, 2, 3}, Color::Black};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef MATADOR_MODEL_METAS_HPP
|
||||||
|
#define MATADOR_MODEL_METAS_HPP
|
||||||
|
|
||||||
|
#include "matador/query/meta_table_macro.hpp"
|
||||||
|
|
||||||
|
META_TABLE(recipes, RECIPE, id, name);
|
||||||
|
META_TABLE(ingredients, INGREDIENT, id, name);
|
||||||
|
META_TABLE(recipe_ingredients, RECIPE_INGREDIENT, recipe_id, ingredient_id);
|
||||||
|
META_TABLE(airplanes, AIRPLANE, id, brand, model);
|
||||||
|
META_TABLE(flights, FLIGHT, id, airplane_id, pilot_name);
|
||||||
|
META_TABLE(shipments, SHIPMENT, id, tracking_number)
|
||||||
|
META_TABLE(packages, PACKAGE, id, weight, shipment_id)
|
||||||
|
META_TABLE(persons, PERSON, id, name, age, image)
|
||||||
|
|
||||||
|
#endif //MATADOR_MODEL_METAS_HPP
|
||||||
Loading…
Reference in New Issue