Compare commits
2 Commits
7c02d745c8
...
f13837e515
| Author | SHA1 | Date |
|---|---|---|
|
|
f13837e515 | |
|
|
c025fb282a |
|
|
@ -234,19 +234,15 @@ sql::record mysql_connection::describe(const std::string &table)
|
||||||
while (reader.fetch()) {
|
while (reader.fetch()) {
|
||||||
|
|
||||||
char *end = nullptr;
|
char *end = nullptr;
|
||||||
// Todo: Handle error
|
|
||||||
auto index = strtoul(reader.column(0), &end, 10);
|
|
||||||
std::string name = reader.column(0);
|
std::string name = reader.column(0);
|
||||||
|
|
||||||
// Todo: extract size
|
|
||||||
auto typeinfo = determine_type_info(reader.column(1));
|
auto typeinfo = determine_type_info(reader.column(1));
|
||||||
end = nullptr;
|
end = nullptr;
|
||||||
sql::null_option null_opt{sql::null_option::NULLABLE};
|
sql::null_option null_opt{sql::null_option::NULLABLE};
|
||||||
if (strtoul(reader.column(2), &end, 10) == 0) {
|
if (strtoul(reader.column(2), &end, 10) == 0) {
|
||||||
null_opt = sql::null_option::NOT_NULL;
|
null_opt = sql::null_option::NOT_NULL;
|
||||||
}
|
}
|
||||||
// f.default_value(res->column(4));
|
prototype.append({name, typeinfo.type, {typeinfo.size}, null_opt, prototype.size()});
|
||||||
prototype.append({name, typeinfo.type, {typeinfo.size}, null_opt});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return prototype;
|
return prototype;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ set(TEST_SOURCES
|
||||||
../../tests/ConnectionTest.cpp
|
../../tests/ConnectionTest.cpp
|
||||||
../../tests/SessionRecordTest.cpp
|
../../tests/SessionRecordTest.cpp
|
||||||
../../tests/StatementTest.cpp
|
../../tests/StatementTest.cpp
|
||||||
../../tests/TypeTraitsTest.cpp)
|
../../tests/TypeTraitsTest.cpp
|
||||||
|
../../tests/StatementCacheTest.cpp)
|
||||||
|
|
||||||
set(LIBRARY_TEST_TARGET mysql_tests)
|
set(LIBRARY_TEST_TARGET mysql_tests)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,12 @@ void throw_postgres_error(PGconn *db, const std::string &source)
|
||||||
|
|
||||||
void throw_postgres_error(PGresult *res, PGconn *db, const std::string &source, const std::string &sql)
|
void throw_postgres_error(PGresult *res, PGconn *db, const std::string &source, const std::string &sql)
|
||||||
{
|
{
|
||||||
if (res == nullptr ||
|
if (res == nullptr) {
|
||||||
(PQresultStatus(res) != PGRES_COMMAND_OK &&
|
std::stringstream msg;
|
||||||
PQresultStatus(res) != PGRES_TUPLES_OK)) {
|
msg << "postgres error (" << source << ", " << PQerrorMessage(db) << ": " << sql;
|
||||||
|
throw std::logic_error(msg.str());
|
||||||
|
} else if ((PQresultStatus(res) != PGRES_COMMAND_OK &&
|
||||||
|
PQresultStatus(res) != PGRES_TUPLES_OK)) {
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "postgres error (" << source << ", " << PQresultErrorField(res, PG_DIAG_SQLSTATE) << ") " << PQerrorMessage(db) << ": " << sql;
|
msg << "postgres error (" << source << ", " << PQresultErrorField(res, PG_DIAG_SQLSTATE) << ") " << PQerrorMessage(db) << ": " << sql;
|
||||||
throw std::logic_error(msg.str());
|
throw std::logic_error(msg.str());
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ set(TEST_SOURCES
|
||||||
../../tests/ConnectionTest.cpp
|
../../tests/ConnectionTest.cpp
|
||||||
../../tests/SessionRecordTest.cpp
|
../../tests/SessionRecordTest.cpp
|
||||||
../../tests/StatementTest.cpp
|
../../tests/StatementTest.cpp
|
||||||
../../tests/TypeTraitsTest.cpp)
|
../../tests/TypeTraitsTest.cpp
|
||||||
|
../../tests/StatementCacheTest.cpp)
|
||||||
|
|
||||||
set(LIBRARY_TEST_TARGET postgres_tests)
|
set(LIBRARY_TEST_TARGET postgres_tests)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ sql::record sqlite_connection::describe(const std::string& table)
|
||||||
null_opt = sql::null_option::NOT_NULL;
|
null_opt = sql::null_option::NOT_NULL;
|
||||||
}
|
}
|
||||||
// f.default_value(res->column(4));
|
// f.default_value(res->column(4));
|
||||||
prototype.append({name, type, utils::null_attributes, null_opt});
|
prototype.append({name, type, utils::null_attributes, null_opt, index});
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(prototype);
|
return std::move(prototype);
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ set(TEST_SOURCES
|
||||||
../../tests/ConnectionTest.cpp
|
../../tests/ConnectionTest.cpp
|
||||||
../../tests/SessionRecordTest.cpp
|
../../tests/SessionRecordTest.cpp
|
||||||
../../tests/StatementTest.cpp
|
../../tests/StatementTest.cpp
|
||||||
../../tests/TypeTraitsTest.cpp)
|
../../tests/TypeTraitsTest.cpp
|
||||||
|
../../tests/StatementCacheTest.cpp)
|
||||||
|
|
||||||
set(LIBRARY_TEST_TARGET sqlite_tests)
|
set(LIBRARY_TEST_TARGET sqlite_tests)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "matador/sql/column.hpp"
|
#include "matador/sql/column.hpp"
|
||||||
#include "matador/sql/condition.hpp"
|
#include "matador/sql/condition.hpp"
|
||||||
#include "matador/sql/session.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
|
|
||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
|
|
||||||
|
|
@ -12,8 +12,10 @@ class SessionRecordFixture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SessionRecordFixture()
|
SessionRecordFixture()
|
||||||
: pool(matador::test::connection::dns, 4), ses(pool)
|
: db(matador::test::connection::dns)
|
||||||
{}
|
{
|
||||||
|
db.open();
|
||||||
|
}
|
||||||
~SessionRecordFixture() {
|
~SessionRecordFixture() {
|
||||||
drop_table_if_exists("flight");
|
drop_table_if_exists("flight");
|
||||||
drop_table_if_exists("airplane");
|
drop_table_if_exists("airplane");
|
||||||
|
|
@ -22,13 +24,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
matador::sql::connection_pool<matador::sql::connection> pool;
|
matador::sql::connection db;
|
||||||
matador::sql::session ses;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void drop_table_if_exists(const std::string &table_name) {
|
void drop_table_if_exists(const std::string &table_name) {
|
||||||
if (ses.table_exists(table_name)) {
|
if (db.exists(table_name)) {
|
||||||
ses.drop().table(table_name).execute();
|
db.drop().table(table_name).execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -37,8 +38,8 @@ using namespace matador::sql;
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement", "[session][record]")
|
||||||
{
|
{
|
||||||
REQUIRE(!ses.table_exists("person"));
|
REQUIRE(!db.exists("person"));
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -46,18 +47,18 @@ TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement", "[ses
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(ses.table_exists("person"));
|
REQUIRE(db.exists("person"));
|
||||||
|
|
||||||
ses.drop()
|
db.drop()
|
||||||
.table("person")
|
.table("person")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(!ses.table_exists("person"));
|
REQUIRE(!db.exists("person"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement with foreign key", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement with foreign key", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("airplane", {
|
.table("airplane", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("brand", 255),
|
make_column<std::string>("brand", 255),
|
||||||
|
|
@ -65,9 +66,9 @@ TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement with fo
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(ses.table_exists("airplane"));
|
REQUIRE(db.exists("airplane"));
|
||||||
|
|
||||||
ses.create()
|
db.create()
|
||||||
.table("flight", {
|
.table("flight", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_fk_column<unsigned long>("airplane_id", "airplane", "id"),
|
make_fk_column<unsigned long>("airplane_id", "airplane", "id"),
|
||||||
|
|
@ -75,24 +76,24 @@ TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement with fo
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(ses.table_exists("flight"));
|
REQUIRE(db.exists("flight"));
|
||||||
|
|
||||||
ses.drop()
|
db.drop()
|
||||||
.table("flight")
|
.table("flight")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(!ses.table_exists("flight"));
|
REQUIRE(!db.exists("flight"));
|
||||||
|
|
||||||
ses.drop()
|
db.drop()
|
||||||
.table("airplane")
|
.table("airplane")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(!ses.table_exists("airplane"));
|
REQUIRE(!db.exists("airplane"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -100,14 +101,14 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement", "[ses
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
auto res = ses.insert()
|
auto res = db.insert()
|
||||||
.into("person", {"id", "name", "age"})
|
.into("person", {"id", "name", "age"})
|
||||||
.values({7, "george", 45})
|
.values({7, "george", 45})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto result = ses.select({"id", "name", "age"})
|
auto result = db.select({"id", "name", "age"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
||||||
|
|
@ -124,14 +125,14 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement", "[ses
|
||||||
REQUIRE(i.at(2).template as<int>() == 45);
|
REQUIRE(i.at(2).template as<int>() == 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
ses.drop()
|
db.drop()
|
||||||
.table("person")
|
.table("person")
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement with foreign key", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement with foreign key", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("airplane", {
|
.table("airplane", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("brand", 255),
|
make_column<std::string>("brand", 255),
|
||||||
|
|
@ -139,7 +140,7 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement with fo
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
ses.create()
|
db.create()
|
||||||
.table("flight", {
|
.table("flight", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_fk_column<unsigned long>("airplane_id", "airplane", "id"),
|
make_fk_column<unsigned long>("airplane_id", "airplane", "id"),
|
||||||
|
|
@ -147,31 +148,31 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement with fo
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
auto res = ses.insert().into("airplane", {"id", "brand", "model"}).values({1, "Airbus", "A380"}).execute();
|
auto res = db.insert().into("airplane", {"id", "brand", "model"}).values({1, "Airbus", "A380"}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
res = ses.insert().into("airplane", {"id", "brand", "model"}).values({2, "Boeing", "707"}).execute();
|
res = db.insert().into("airplane", {"id", "brand", "model"}).values({2, "Boeing", "707"}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
res = ses.insert().into("airplane", {"id", "brand", "model"}).values({3, "Boeing", "747"}).execute();
|
res = db.insert().into("airplane", {"id", "brand", "model"}).values({3, "Boeing", "747"}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto count = ses.select({count_all()}).from("airplane").fetch_value<int>();
|
auto count = db.select({count_all()}).from("airplane").fetch_value<int>();
|
||||||
REQUIRE(count == 3);
|
REQUIRE(count == 3);
|
||||||
|
|
||||||
res = ses.insert().into("flight", {"id", "airplane_id", "pilot_name"}).values({4, 1, "George"}).execute();
|
res = db.insert().into("flight", {"id", "airplane_id", "pilot_name"}).values({4, 1, "George"}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
ses.drop().table("flight").execute();
|
db.drop().table("flight").execute();
|
||||||
ses.drop().table("airplane").execute();
|
db.drop().table("airplane").execute();
|
||||||
|
|
||||||
REQUIRE(!ses.table_exists("flight"));
|
REQUIRE(!db.exists("flight"));
|
||||||
REQUIRE(!ses.table_exists("airplane"));
|
REQUIRE(!db.exists("airplane"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Execute update record statement", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Execute update record statement", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -179,14 +180,14 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute update record statement", "[ses
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
auto res = ses.insert()
|
auto res = db.insert()
|
||||||
.into("person", {"id", "name", "age"})
|
.into("person", {"id", "name", "age"})
|
||||||
.values({7, "george", 45})
|
.values({7, "george", 45})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
res = ses.update("person")
|
res = db.update("person")
|
||||||
.set({{"id", 7},
|
.set({{"id", 7},
|
||||||
{"name", "jane"},
|
{"name", "jane"},
|
||||||
{"age", 35}})
|
{"age", 35}})
|
||||||
|
|
@ -195,7 +196,7 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute update record statement", "[ses
|
||||||
|
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto result = ses.select({"id", "name", "age"})
|
auto result = db.select({"id", "name", "age"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
||||||
|
|
@ -212,12 +213,12 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute update record statement", "[ses
|
||||||
REQUIRE(i.at(2).as<int>() == 35);
|
REQUIRE(i.at(2).as<int>() == 35);
|
||||||
}
|
}
|
||||||
|
|
||||||
ses.drop().table("person").execute();
|
db.drop().table("person").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -225,16 +226,16 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement", "[session][r
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto result = ses.select({"id", "name", "age"})
|
auto result = db.select({"id", "name", "age"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
||||||
|
|
@ -245,22 +246,22 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement", "[session][r
|
||||||
}
|
}
|
||||||
REQUIRE(expected_names.empty());
|
REQUIRE(expected_names.empty());
|
||||||
|
|
||||||
auto rec = ses.select({"id", "name", "age"})
|
auto rec = db.select({"id", "name", "age"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.fetch_one();
|
.fetch_one();
|
||||||
REQUIRE(rec.at(1).str() == "george");
|
REQUIRE(rec.at(1).str() == "george");
|
||||||
|
|
||||||
auto name = ses.select({"name"})
|
auto name = db.select({"name"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.fetch_value<std::string>();
|
.fetch_value<std::string>();
|
||||||
REQUIRE(name == "george");
|
REQUIRE(name == "george");
|
||||||
|
|
||||||
ses.drop().table("person").execute();
|
db.drop().table("person").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with order by", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with order by", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -268,16 +269,16 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with order by"
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto result = ses.select({"id", "name", "age"})
|
auto result = db.select({"id", "name", "age"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.order_by("name").asc()
|
.order_by("name").asc()
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
@ -289,12 +290,12 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with order by"
|
||||||
}
|
}
|
||||||
REQUIRE(expected_names.empty());
|
REQUIRE(expected_names.empty());
|
||||||
|
|
||||||
ses.drop().table("person").execute();
|
db.drop().table("person").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with group by and order by", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with group by and order by", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -302,18 +303,18 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with group by
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({3, "michael", 13}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({3, "michael", 13}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({5, "charlie", 67}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({5, "charlie", 67}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto result = ses.select({alias(count("age"), "age_count"), "age"})
|
auto result = db.select({alias(count("age"), "age_count"), "age"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.group_by("age")
|
.group_by("age")
|
||||||
.order_by("age_count").desc()
|
.order_by("age_count").desc()
|
||||||
|
|
@ -328,41 +329,41 @@ TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with group by
|
||||||
expected_values.pop_front();
|
expected_values.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
ses.drop().table("person").execute();
|
db.drop().table("person").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Execute delete statement", "[session][record]")
|
TEST_CASE_METHOD(SessionRecordFixture, " Execute delete statement", "[session][record]")
|
||||||
{
|
{
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
make_column<unsigned short>("age")
|
make_column<unsigned short>("age")
|
||||||
}).execute();
|
}).execute();
|
||||||
|
|
||||||
auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto count = ses.select({count_all()}).from("person").fetch_value<int>();
|
auto count = db.select({count_all()}).from("person").fetch_value<int>();
|
||||||
REQUIRE(count == 2);
|
REQUIRE(count == 2);
|
||||||
|
|
||||||
res = ses.remove()
|
res = db.remove()
|
||||||
.from("person")
|
.from("person")
|
||||||
.where("id"_col == 1)
|
.where("id"_col == 1)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
count = ses.select({count_all()}).from("person").fetch_value<int>();
|
count = db.select({count_all()}).from("person").fetch_value<int>();
|
||||||
REQUIRE(count == 1);
|
REQUIRE(count == 1);
|
||||||
|
|
||||||
ses.drop().table("person").execute();
|
db.drop().table("person").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionRecordFixture, " Test quoted identifier", "[session][record]") {
|
TEST_CASE_METHOD(SessionRecordFixture, " Test quoted identifier", "[session][record]") {
|
||||||
ses.create()
|
db.create()
|
||||||
.table("quotes", {
|
.table("quotes", {
|
||||||
make_column<std::string>("from", 255),
|
make_column<std::string>("from", 255),
|
||||||
make_column<std::string>("to", 255)
|
make_column<std::string>("to", 255)
|
||||||
|
|
@ -371,26 +372,26 @@ TEST_CASE_METHOD(SessionRecordFixture, " Test quoted identifier", "[session][rec
|
||||||
// check table description
|
// check table description
|
||||||
std::vector<std::string> columns = { "from", "to"};
|
std::vector<std::string> columns = { "from", "to"};
|
||||||
std::vector<data_type_t> types = {data_type_t::type_varchar, data_type_t::type_varchar};
|
std::vector<data_type_t> types = {data_type_t::type_varchar, data_type_t::type_varchar};
|
||||||
auto fields = ses.describe_table("quotes");
|
auto fields = db.describe("quotes");
|
||||||
|
|
||||||
for (const auto &field : fields) {
|
for (const auto &field : fields) {
|
||||||
REQUIRE(field.name() == columns[field.index()]);
|
REQUIRE(field.name() == columns[field.index()]);
|
||||||
REQUIRE(field.type() == types[field.index()]);
|
REQUIRE(field.type() == types[field.index()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ses.insert().into("quotes", {"from", "to"}).values({"Berlin", "London"}).execute();
|
db.insert().into("quotes", {"from", "to"}).values({"Berlin", "London"}).execute();
|
||||||
|
|
||||||
auto res = ses.select({"from", "to"}).from("quotes").fetch_one();
|
auto res = db.select({"from", "to"}).from("quotes").fetch_one();
|
||||||
|
|
||||||
REQUIRE("Berlin" == res.at("from").str());
|
REQUIRE("Berlin" == res.at("from").str());
|
||||||
REQUIRE("London" == res.at("to").str());
|
REQUIRE("London" == res.at("to").str());
|
||||||
|
|
||||||
ses.update("quotes").set({{"from", "Hamburg"}, {"to", "New York"}}).where("from"_col == "Berlin").execute();
|
db.update("quotes").set({{"from", "Hamburg"}, {"to", "New York"}}).where("from"_col == "Berlin").execute();
|
||||||
|
|
||||||
res = ses.select({"from", "to"}).from("quotes").fetch_one();
|
res = db.select({"from", "to"}).from("quotes").fetch_one();
|
||||||
|
|
||||||
REQUIRE("Hamburg" == res.at("from").str());
|
REQUIRE("Hamburg" == res.at("from").str());
|
||||||
REQUIRE("New York" == res.at("to").str());
|
REQUIRE("New York" == res.at("to").str());
|
||||||
|
|
||||||
ses.drop().table("quotes").execute();
|
db.drop().table("quotes").execute();
|
||||||
}
|
}
|
||||||
|
|
@ -13,65 +13,66 @@
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::test;
|
using namespace matador::test;
|
||||||
|
|
||||||
class SessionFixture
|
class QueryFixture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SessionFixture()
|
QueryFixture()
|
||||||
: pool(matador::test::connection::dns, 4), ses(pool)
|
: db(matador::test::connection::dns)
|
||||||
{}
|
{
|
||||||
~SessionFixture() {
|
db.open();
|
||||||
|
}
|
||||||
|
~QueryFixture() {
|
||||||
drop_table_if_exists("flight");
|
drop_table_if_exists("flight");
|
||||||
drop_table_if_exists("airplane");
|
drop_table_if_exists("airplane");
|
||||||
drop_table_if_exists("person");
|
drop_table_if_exists("person");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
matador::sql::connection_pool<matador::sql::connection> pool;
|
matador::sql::connection db;
|
||||||
matador::sql::session ses;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void drop_table_if_exists(const std::string &table_name) {
|
void drop_table_if_exists(const std::string &table_name) {
|
||||||
if (ses.table_exists(table_name)) {
|
if (db.exists(table_name)) {
|
||||||
ses.drop().table(table_name).execute();
|
db.drop().table(table_name).execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionFixture, " Create table with foreign key relation", "[session]") {
|
TEST_CASE_METHOD(QueryFixture, " Create table with foreign key relation", "[session]") {
|
||||||
ses.create()
|
db.create()
|
||||||
.table<airplane>("airplane")
|
.table<airplane>("airplane")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(ses.table_exists("airplane"));
|
REQUIRE(db.exists("airplane"));
|
||||||
|
|
||||||
ses.create()
|
db.create()
|
||||||
.table<flight>("flight")
|
.table<flight>("flight")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
REQUIRE(ses.table_exists("flight"));
|
REQUIRE(db.exists("flight"));
|
||||||
|
|
||||||
ses.drop().table("flight").execute();
|
db.drop().table("flight").execute();
|
||||||
ses.drop().table("airplane").execute();
|
db.drop().table("airplane").execute();
|
||||||
|
|
||||||
REQUIRE(!ses.table_exists("flight"));
|
REQUIRE(!db.exists("flight"));
|
||||||
REQUIRE(!ses.table_exists("airplane"));
|
REQUIRE(!db.exists("airplane"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionFixture, " Execute select statement with where clause", "[session]") {
|
TEST_CASE_METHOD(QueryFixture, " Execute select statement with where clause", "[session]") {
|
||||||
ses.create()
|
db.create()
|
||||||
.table<person>("person")
|
.table<person>("person")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
person george{7, "george", 45};
|
person george{7, "george", 45};
|
||||||
george.image.push_back(37);
|
george.image.push_back(37);
|
||||||
|
|
||||||
auto res = ses.insert()
|
auto res = db.insert()
|
||||||
.into("person", george)
|
.into("person", george)
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
// fetch person as record
|
// fetch person as record
|
||||||
auto result_record = ses.select<person>()
|
auto result_record = db.select<person>()
|
||||||
.from("person")
|
.from("person")
|
||||||
.where("id"_col == 7)
|
.where("id"_col == 7)
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
@ -90,7 +91,7 @@ TEST_CASE_METHOD(SessionFixture, " Execute select statement with where clause",
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch person as person
|
// fetch person as person
|
||||||
auto result_person = ses.select<person>()
|
auto result_person = db.select<person>()
|
||||||
.from("person")
|
.from("person")
|
||||||
.where("id"_col == 7)
|
.where("id"_col == 7)
|
||||||
.fetch_all<person>();
|
.fetch_all<person>();
|
||||||
|
|
@ -101,11 +102,11 @@ TEST_CASE_METHOD(SessionFixture, " Execute select statement with where clause",
|
||||||
REQUIRE(i.age == 45);
|
REQUIRE(i.age == 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
ses.drop().table("person").execute();
|
db.drop().table("person").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionFixture, " Execute insert statement", "[session]") {
|
TEST_CASE_METHOD(QueryFixture, " Execute insert statement", "[session]") {
|
||||||
ses.create()
|
db.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -113,7 +114,7 @@ TEST_CASE_METHOD(SessionFixture, " Execute insert statement", "[session]") {
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
auto res = ses.insert()
|
auto res = db.insert()
|
||||||
.into("person", {"id", "name", "color"})
|
.into("person", {"id", "name", "color"})
|
||||||
.values({7, "george", "green"})
|
.values({7, "george", "green"})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
@ -121,7 +122,7 @@ TEST_CASE_METHOD(SessionFixture, " Execute insert statement", "[session]") {
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
// fetch person as record
|
// fetch person as record
|
||||||
auto result_record = ses.select({"id", "name", "color"})
|
auto result_record = db.select({"id", "name", "color"})
|
||||||
.from("person")
|
.from("person")
|
||||||
.where("id"_col == 7)
|
.where("id"_col == 7)
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
@ -139,15 +140,15 @@ TEST_CASE_METHOD(SessionFixture, " Execute insert statement", "[session]") {
|
||||||
REQUIRE(i.at(2).as<std::string>() == "green");
|
REQUIRE(i.at(2).as<std::string>() == "green");
|
||||||
}
|
}
|
||||||
|
|
||||||
ses.drop().table("person").execute();
|
db.drop().table("person").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionFixture, " Select statement with foreign key", "[session]") {
|
TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key", "[session]") {
|
||||||
ses.create()
|
db.create()
|
||||||
.table<airplane>("airplane")
|
.table<airplane>("airplane")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
ses.create()
|
db.create()
|
||||||
.table<flight>("flight")
|
.table<flight>("flight")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
|
|
@ -158,24 +159,24 @@ TEST_CASE_METHOD(SessionFixture, " Select statement with foreign key", "[session
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &plane : planes) {
|
for (const auto &plane : planes) {
|
||||||
auto res = ses.insert().into<airplane>("airplane").values(*plane).execute();
|
auto res = db.insert().into<airplane>("airplane").values(*plane).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto count = ses.select({count_all()}).from("airplane").fetch_value<int>();
|
auto count = db.select({count_all()}).from("airplane").fetch_value<int>();
|
||||||
REQUIRE(count == 3);
|
REQUIRE(count == 3);
|
||||||
|
|
||||||
flight f4711{4, planes.at(1), "hans"};
|
flight f4711{4, planes.at(1), "hans"};
|
||||||
|
|
||||||
auto res = ses.insert().into<flight>("flight").values(f4711).execute();
|
auto res = db.insert().into<flight>("flight").values(f4711).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto f = *ses.select<flight>().from("flight").fetch_all<flight>().begin();
|
auto f = *db.select<flight>().from("flight").fetch_all<flight>().begin();
|
||||||
REQUIRE(f.id == 4);
|
REQUIRE(f.id == 4);
|
||||||
REQUIRE(f.pilot_name == "hans");
|
REQUIRE(f.pilot_name == "hans");
|
||||||
REQUIRE(f.airplane.get() != nullptr);
|
REQUIRE(f.airplane.get() != nullptr);
|
||||||
REQUIRE(f.airplane->id == 2);
|
REQUIRE(f.airplane->id == 2);
|
||||||
|
|
||||||
ses.drop().table("flight").execute();
|
db.drop().table("flight").execute();
|
||||||
ses.drop().table("airplane").execute();
|
db.drop().table("airplane").execute();
|
||||||
}
|
}
|
||||||
|
|
@ -5,18 +5,28 @@
|
||||||
#include "matador/sql/session.hpp"
|
#include "matador/sql/session.hpp"
|
||||||
#include "matador/sql/statement_cache.hpp"
|
#include "matador/sql/statement_cache.hpp"
|
||||||
|
|
||||||
|
#include "connection.hpp"
|
||||||
|
|
||||||
using namespace matador;
|
using namespace matador;
|
||||||
|
|
||||||
TEST_CASE("Acquire prepared statement", "[statement cache]") {
|
class StatementCacheFixture
|
||||||
sql::statement_cache cache;
|
{
|
||||||
sql::connection_pool<sql::connection> pool("sqlite://sqlite.db", 4);
|
public:
|
||||||
|
StatementCacheFixture()
|
||||||
|
: pool(matador::test::connection::dns, 4), ses(pool)
|
||||||
|
{}
|
||||||
|
~StatementCacheFixture() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
matador::sql::connection_pool<matador::sql::connection> pool;
|
||||||
|
matador::sql::session ses;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(StatementCacheFixture, " Acquire prepared statement", "[statement cache]") {
|
||||||
|
sql::statement_cache cache;
|
||||||
|
|
||||||
sql::session s(pool);
|
|
||||||
auto conn = pool.acquire();
|
auto conn = pool.acquire();
|
||||||
|
|
||||||
std::string sql = R"(SELECT * FROM person WHERE name = 'george')";
|
std::string sql = R"(SELECT * FROM person WHERE name = 'george')";
|
||||||
// auto &stmt = cache.acquire(sql, *conn);
|
// auto &stmt = cache.acquire(sql, *conn);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
#include "matador/sql/column.hpp"
|
#include "matador/sql/column.hpp"
|
||||||
#include "matador/sql/condition.hpp"
|
#include "matador/sql/condition.hpp"
|
||||||
#include "matador/sql/connection_info.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
#include "matador/sql/connection_pool.hpp"
|
|
||||||
#include "matador/sql/session.hpp"
|
|
||||||
|
|
||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
|
|
||||||
|
|
@ -17,9 +15,10 @@ class StatementTestFixture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StatementTestFixture()
|
StatementTestFixture()
|
||||||
: pool(matador::test::connection::dns, 4), ses(pool)
|
: db(matador::test::connection::dns)
|
||||||
{
|
{
|
||||||
ses.create().table<airplane>("airplane").execute();
|
db.open();
|
||||||
|
db.create().table<airplane>("airplane").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
~StatementTestFixture()
|
~StatementTestFixture()
|
||||||
|
|
@ -28,8 +27,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
matador::sql::connection_pool<matador::sql::connection> pool;
|
matador::sql::connection db;
|
||||||
matador::sql::session ses;
|
|
||||||
|
|
||||||
std::vector<entity<airplane>> planes{
|
std::vector<entity<airplane>> planes{
|
||||||
make_entity<airplane>(1, "Airbus", "A380"),
|
make_entity<airplane>(1, "Airbus", "A380"),
|
||||||
|
|
@ -39,8 +37,8 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void drop_table_if_exists(const std::string &table_name) {
|
void drop_table_if_exists(const std::string &table_name) {
|
||||||
if (ses.table_exists(table_name)) {
|
if (db.exists(table_name)) {
|
||||||
ses.drop().table(table_name).execute();
|
db.drop().table(table_name).execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,7 +47,7 @@ private:
|
||||||
TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement]")
|
TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement]")
|
||||||
{
|
{
|
||||||
SECTION("Insert with prepared statement and placeholder") {
|
SECTION("Insert with prepared statement and placeholder") {
|
||||||
auto stmt = ses.insert()
|
auto stmt = db.insert()
|
||||||
.into<airplane>("airplane")
|
.into<airplane>("airplane")
|
||||||
.values<airplane>().prepare();
|
.values<airplane>().prepare();
|
||||||
|
|
||||||
|
|
@ -59,7 +57,7 @@ TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement
|
||||||
stmt.reset();
|
stmt.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = ses.select<airplane>().from("airplane").fetch_all<airplane>();
|
auto result = db.select<airplane>().from("airplane").fetch_all<airplane>();
|
||||||
|
|
||||||
size_t index{0};
|
size_t index{0};
|
||||||
for (const auto &i: result) {
|
for (const auto &i: result) {
|
||||||
|
|
@ -71,11 +69,11 @@ 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 = ses.insert().into<airplane>("airplane").values(*plane).execute();
|
auto res = db.insert().into<airplane>("airplane").values(*plane).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stmt = ses.select<airplane>().from("airplane").where("brand"_col == _).prepare();
|
auto stmt = db.select<airplane>().from("airplane").where("brand"_col == _).prepare();
|
||||||
|
|
||||||
stmt.bind(0, "Airbus");
|
stmt.bind(0, "Airbus");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
#include "matador/sql/session.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
|
|
||||||
#include "matador/utils/enum_mapper.hpp"
|
#include "matador/utils/enum_mapper.hpp"
|
||||||
|
|
||||||
|
|
@ -14,26 +14,26 @@ class TypeTraitsTestFixture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TypeTraitsTestFixture()
|
TypeTraitsTestFixture()
|
||||||
: pool(matador::test::connection::dns, 4), ses(pool)
|
: db(matador::test::connection::dns)
|
||||||
{
|
{
|
||||||
ses.create()
|
db.open();
|
||||||
|
db.create()
|
||||||
.table<location>("location")
|
.table<location>("location")
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
~TypeTraitsTestFixture()
|
~TypeTraitsTestFixture()
|
||||||
{
|
{
|
||||||
ses.drop().table("location").execute();
|
db.drop().table("location").execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
matador::sql::connection_pool<matador::sql::connection> pool;
|
matador::sql::connection db;
|
||||||
matador::sql::session ses;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void drop_table_if_exists(const std::string &table_name) {
|
void drop_table_if_exists(const std::string &table_name) {
|
||||||
if (ses.table_exists(table_name)) {
|
if (db.exists(table_name)) {
|
||||||
ses.drop().table(table_name).execute();
|
db.drop().table(table_name).execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -85,10 +85,10 @@ TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with typ
|
||||||
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};
|
||||||
|
|
||||||
auto res = ses.insert().into<location>("location").values(loc).execute();
|
auto res = db.insert().into<location>("location").values(loc).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto result = ses.select<location>().from("location").fetch_all<location>();
|
auto result = db.select<location>().from("location").fetch_all<location>();
|
||||||
|
|
||||||
for (const auto &l: result) {
|
for (const auto &l: result) {
|
||||||
REQUIRE(l.name == "center");
|
REQUIRE(l.name == "center");
|
||||||
|
|
@ -98,11 +98,11 @@ TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with typ
|
||||||
SECTION("Insert and select with prepared statement") {
|
SECTION("Insert and select with prepared statement") {
|
||||||
location loc{1, "center", {1, 2, 3}, Color::Black};
|
location loc{1, "center", {1, 2, 3}, Color::Black};
|
||||||
|
|
||||||
auto stmt = ses.insert().into<location>("location").values<location>().prepare();
|
auto stmt = db.insert().into<location>("location").values<location>().prepare();
|
||||||
auto res = stmt.bind(loc).execute();
|
auto res = stmt.bind(loc).execute();
|
||||||
REQUIRE(res == 1);
|
REQUIRE(res == 1);
|
||||||
|
|
||||||
auto result = ses.select<location>().from("location").
|
auto result = db.select<location>().from("location").
|
||||||
template fetch_all<location>();
|
template fetch_all<location>();
|
||||||
|
|
||||||
for (const auto &l: result) {
|
for (const auto &l: result) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "matador/sql/connection_info.hpp"
|
#include "matador/sql/connection_info.hpp"
|
||||||
#include "matador/sql/connection_impl.hpp"
|
#include "matador/sql/connection_impl.hpp"
|
||||||
#include "matador/sql/dialect.hpp"
|
#include "matador/sql/dialect.hpp"
|
||||||
|
#include "matador/sql/query_intermediates.hpp"
|
||||||
#include "matador/sql/query_context.hpp"
|
#include "matador/sql/query_context.hpp"
|
||||||
#include "matador/sql/query_result.hpp"
|
#include "matador/sql/query_result.hpp"
|
||||||
#include "matador/sql/record.hpp"
|
#include "matador/sql/record.hpp"
|
||||||
|
|
@ -18,12 +19,11 @@ namespace matador::sql {
|
||||||
class connection
|
class connection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit connection(connection_info info);
|
explicit connection(connection_info info, const std::shared_ptr<table_repository> &repo = std::make_shared<table_repository>());
|
||||||
explicit connection(const std::string& dns);
|
explicit connection(const std::string& dns, const std::shared_ptr<table_repository> &repo = std::make_shared<table_repository>());
|
||||||
connection(const connection &x);
|
connection(const connection &x);
|
||||||
connection& operator=(const connection &x);
|
connection& operator=(const connection &x);
|
||||||
connection(connection &&x) noexcept = default;
|
connection(connection &&x) noexcept = default;
|
||||||
connection& operator=(connection &&x) noexcept = default;
|
|
||||||
~connection();
|
~connection();
|
||||||
|
|
||||||
void open();
|
void open();
|
||||||
|
|
@ -31,22 +31,41 @@ public:
|
||||||
[[nodiscard]] bool is_open() const;
|
[[nodiscard]] bool is_open() const;
|
||||||
[[nodiscard]] const connection_info& info() const;
|
[[nodiscard]] const connection_info& info() const;
|
||||||
|
|
||||||
|
query_create_intermediate create();
|
||||||
|
query_drop_intermediate drop();
|
||||||
|
template < class Type >
|
||||||
|
query_select_intermediate select();
|
||||||
|
query_select_intermediate select(std::initializer_list<column> columns);
|
||||||
|
query_insert_intermediate insert();
|
||||||
|
query_update_intermediate update(const std::string &table);
|
||||||
|
query_delete_intermediate remove();
|
||||||
|
|
||||||
[[nodiscard]] record describe(const std::string &table_name) const;
|
[[nodiscard]] record describe(const std::string &table_name) const;
|
||||||
[[nodiscard]] bool exists(const std::string &schema_name, const std::string &table_name) const;
|
[[nodiscard]] bool exists(const std::string &schema_name, const std::string &table_name) const;
|
||||||
|
[[nodiscard]] bool exists(const std::string &table_name) const;
|
||||||
|
|
||||||
|
query_result<record> fetch(const query_context &q) const;
|
||||||
[[nodiscard]] std::unique_ptr<query_result_impl> fetch(const std::string &sql) const;
|
[[nodiscard]] std::unique_ptr<query_result_impl> fetch(const std::string &sql) const;
|
||||||
[[nodiscard]] size_t execute(const std::string &sql) const;
|
[[nodiscard]] size_t execute(const std::string &sql) const;
|
||||||
|
|
||||||
statement prepare(query_context &&query) const;
|
statement prepare(query_context &&query) const;
|
||||||
|
|
||||||
const class dialect& dialect() const;
|
const class dialect& dialect() const;
|
||||||
|
std::shared_ptr<table_repository> tables() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
connection_info connection_info_;
|
connection_info connection_info_;
|
||||||
std::unique_ptr<connection_impl> connection_;
|
std::unique_ptr<connection_impl> connection_;
|
||||||
utils::logger logger_;
|
utils::logger logger_;
|
||||||
const class dialect &dialect_;
|
const class dialect &dialect_;
|
||||||
|
std::shared_ptr<table_repository> table_repository_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
query_select_intermediate connection::select()
|
||||||
|
{
|
||||||
|
return query_select_intermediate{*this, column_generator::generate<Type>(*table_repository_)};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //QUERY_CONNECTION_HPP
|
#endif //QUERY_CONNECTION_HPP
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ public:
|
||||||
COLUMNS,
|
COLUMNS,
|
||||||
COLUMN,
|
COLUMN,
|
||||||
FROM,
|
FROM,
|
||||||
|
JOIN,
|
||||||
|
ON,
|
||||||
INTO,
|
INTO,
|
||||||
WHERE,
|
WHERE,
|
||||||
WHERE_CLAUSE,
|
WHERE_CLAUSE,
|
||||||
|
|
@ -161,6 +163,8 @@ private:
|
||||||
{token_t::COLUMNS, "COLUMNS"},
|
{token_t::COLUMNS, "COLUMNS"},
|
||||||
{token_t::COLUMN, "COLUMN"},
|
{token_t::COLUMN, "COLUMN"},
|
||||||
{token_t::FROM, "FROM"},
|
{token_t::FROM, "FROM"},
|
||||||
|
{token_t::JOIN, "INNER JOIN"},
|
||||||
|
{token_t::ON, "ON"},
|
||||||
{token_t::WHERE, "WHERE"},
|
{token_t::WHERE, "WHERE"},
|
||||||
{token_t::AND, "AND"},
|
{token_t::AND, "AND"},
|
||||||
{token_t::OR, "OR"},
|
{token_t::OR, "OR"},
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ private:
|
||||||
QUERY_DELETE,
|
QUERY_DELETE,
|
||||||
QUERY_SET,
|
QUERY_SET,
|
||||||
QUERY_FROM,
|
QUERY_FROM,
|
||||||
|
QUERY_JOIN,
|
||||||
|
QUERY_ON,
|
||||||
QUERY_INTO,
|
QUERY_INTO,
|
||||||
QUERY_WHERE,
|
QUERY_WHERE,
|
||||||
QUERY_VALUES,
|
QUERY_VALUES,
|
||||||
|
|
@ -129,7 +131,7 @@ public:
|
||||||
query_builder& values(std::initializer_list<any_type> values);
|
query_builder& values(std::initializer_list<any_type> values);
|
||||||
query_builder& values(const std::vector<any_type> &values);
|
query_builder& values(const std::vector<any_type> &values);
|
||||||
query_builder& from(const std::string &table, const std::string &as = "");
|
query_builder& from(const std::string &table, const std::string &as = "");
|
||||||
query_builder& join(const std::string &table, join_type_t);
|
query_builder& join(const std::string &table, join_type_t, const std::string &as = "");
|
||||||
query_builder& on(const std::string &column, const std::string &join_column);
|
query_builder& on(const std::string &column, const std::string &join_column);
|
||||||
query_builder& set(std::initializer_list<key_value_pair> key_values);
|
query_builder& set(std::initializer_list<key_value_pair> key_values);
|
||||||
query_builder& set(const std::vector<key_value_pair> &key_values);
|
query_builder& set(const std::vector<key_value_pair> &key_values);
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,15 @@
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
class basic_condition;
|
class basic_condition;
|
||||||
class session;
|
class connection;
|
||||||
|
|
||||||
class query_intermediate
|
class query_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
query_intermediate(session &db, query_builder &query);
|
query_intermediate(connection &db, query_builder &query);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
session &session_;
|
connection &connection_;
|
||||||
query_builder &builder_;
|
query_builder &builder_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -130,17 +130,17 @@ public:
|
||||||
class query_start_intermediate
|
class query_start_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit query_start_intermediate(session &s);
|
explicit query_start_intermediate(connection &s);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
session &session_;
|
connection &connection_;
|
||||||
query_builder builder_;
|
query_builder builder_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_select_intermediate : public query_start_intermediate
|
class query_select_intermediate : public query_start_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
query_select_intermediate(session &s, const std::vector<column>& columns);
|
query_select_intermediate(connection &s, const std::vector<column>& columns);
|
||||||
|
|
||||||
query_from_intermediate from(const std::string &table, const std::string &as = "");
|
query_from_intermediate from(const std::string &table, const std::string &as = "");
|
||||||
};
|
};
|
||||||
|
|
@ -164,36 +164,38 @@ public:
|
||||||
query_execute_finish values()
|
query_execute_finish values()
|
||||||
{
|
{
|
||||||
Type obj;
|
Type obj;
|
||||||
return {session_, builder_.values(as_placeholder(obj))};
|
return {connection_, builder_.values(as_placeholder(obj))};
|
||||||
}
|
}
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_execute_finish values(const Type &obj)
|
query_execute_finish values(const Type &obj)
|
||||||
{
|
{
|
||||||
return {session_, builder_.values(value_extractor::extract(obj))};
|
return {connection_, builder_.values(value_extractor::extract(obj))};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_create_intermediate : query_start_intermediate
|
class query_create_intermediate : public query_start_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
query_create_intermediate(session &s, table_repository &repo);
|
explicit query_create_intermediate(connection &db);
|
||||||
|
|
||||||
query_execute_finish table(const std::string &table, std::initializer_list<column> columns);
|
query_execute_finish table(const std::string &table, std::initializer_list<column> columns);
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_execute_finish table(const std::string &table_name)
|
query_execute_finish table(const std::string &table_name)
|
||||||
{
|
{
|
||||||
const auto &info = repository_.attach<Type>(table_name);
|
if (!tables()->exists<Type>()) {
|
||||||
return {session_, builder_.table(table_name, info.prototype.columns())};
|
tables()->attach<Type>(table_name);
|
||||||
|
}
|
||||||
|
return {connection_, builder_.table(table_name, column_generator::generate<Type>(*tables()))};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
table_repository &repository_;
|
std::shared_ptr<table_repository> tables() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_drop_intermediate : query_start_intermediate
|
class query_drop_intermediate : query_start_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit query_drop_intermediate(session &s);
|
explicit query_drop_intermediate(connection &s);
|
||||||
|
|
||||||
query_execute_finish table(const std::string &table);
|
query_execute_finish table(const std::string &table);
|
||||||
};
|
};
|
||||||
|
|
@ -201,18 +203,18 @@ public:
|
||||||
class query_insert_intermediate : public query_start_intermediate
|
class query_insert_intermediate : public query_start_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit query_insert_intermediate(session &s);
|
explicit query_insert_intermediate(connection &s);
|
||||||
|
|
||||||
query_into_intermediate into(const std::string &table, std::initializer_list<std::string> column_names);
|
query_into_intermediate into(const std::string &table, std::initializer_list<std::string> column_names);
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_into_intermediate into(const std::string &table)
|
query_into_intermediate into(const std::string &table)
|
||||||
{
|
{
|
||||||
return {session_, builder_.into(table, column_name_generator::generate<Type>())};
|
return {connection_, builder_.into(table, column_name_generator::generate<Type>())};
|
||||||
}
|
}
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_execute_finish into(const std::string &table, const Type &obj)
|
query_execute_finish into(const std::string &table, const Type &obj)
|
||||||
{
|
{
|
||||||
return {session_, builder_.into(table, column_name_generator::generate<Type>())
|
return {connection_, builder_.into(table, column_name_generator::generate<Type>())
|
||||||
.values(value_extractor::extract(obj))};
|
.values(value_extractor::extract(obj))};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -236,13 +238,13 @@ public:
|
||||||
class query_update_intermediate : public query_start_intermediate
|
class query_update_intermediate : public query_start_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
query_update_intermediate(session &s, const std::string& table_name);
|
query_update_intermediate(connection &s, const std::string& table_name);
|
||||||
|
|
||||||
query_set_intermediate set(std::initializer_list<key_value_pair> columns);
|
query_set_intermediate set(std::initializer_list<key_value_pair> columns);
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_set_intermediate set(const Type &obj)
|
query_set_intermediate set(const Type &obj)
|
||||||
{
|
{
|
||||||
return {session_, builder_.set(key_value_generator::generate(obj))};
|
return {connection_, builder_.set(key_value_generator::generate(obj))};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -257,7 +259,7 @@ public:
|
||||||
class query_delete_intermediate : public query_start_intermediate
|
class query_delete_intermediate : public query_start_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit query_delete_intermediate(session &s);
|
explicit query_delete_intermediate(connection &s);
|
||||||
|
|
||||||
query_delete_from_intermediate from(const std::string &table);
|
query_delete_from_intermediate from(const std::string &table);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,8 @@ public:
|
||||||
[[nodiscard]] bool empty() const;
|
[[nodiscard]] bool empty() const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
[[nodiscard]] bool unknown() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
void add_to_map(column &col, size_t index);
|
void add_to_map(column &col, size_t index);
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,6 @@ class session
|
||||||
public:
|
public:
|
||||||
explicit session(connection_pool<connection> &pool);
|
explicit session(connection_pool<connection> &pool);
|
||||||
|
|
||||||
query_create_intermediate create();
|
|
||||||
query_drop_intermediate drop();
|
|
||||||
template < class Type >
|
|
||||||
query_select_intermediate select();
|
|
||||||
query_select_intermediate select(std::initializer_list<column> columns);
|
|
||||||
query_insert_intermediate insert();
|
|
||||||
query_update_intermediate update(const std::string &table);
|
|
||||||
query_delete_intermediate remove();
|
|
||||||
|
|
||||||
[[nodiscard]] query_result<record> fetch(const query_context &q) const;
|
[[nodiscard]] query_result<record> fetch(const query_context &q) const;
|
||||||
// [[nodiscard]] query_result<record> fetch(const std::string &sql) const;
|
// [[nodiscard]] query_result<record> fetch(const std::string &sql) const;
|
||||||
[[nodiscard]] size_t execute(const std::string &sql) const;
|
[[nodiscard]] size_t execute(const std::string &sql) const;
|
||||||
|
|
@ -60,11 +51,5 @@ private:
|
||||||
mutable std::unordered_map<std::string, record> prototypes_;
|
mutable std::unordered_map<std::string, record> prototypes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
query_select_intermediate session::select()
|
|
||||||
{
|
|
||||||
return query_select_intermediate{*this, column_generator::generate<Type>(table_repository_)};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //QUERY_SESSION_HPP
|
#endif //QUERY_SESSION_HPP
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,18 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] std::pair<std::string, std::string> reference(const std::type_index &ti) const;
|
[[nodiscard]] std::pair<std::string, std::string> reference(const std::type_index &ti) const;
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
[[nodiscard]] bool exists() const
|
||||||
|
{
|
||||||
|
return exists(std::type_index(typeid(Type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool exists(const std::type_index &ti) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using repository = std::unordered_map<std::type_index, table_info>;
|
using repository = std::unordered_map<std::type_index, table_info>;
|
||||||
repository repository_;
|
repository repository_;
|
||||||
};
|
};
|
||||||
;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,17 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
connection::connection(connection_info info)
|
connection::connection(connection_info info, const std::shared_ptr<table_repository> &repo)
|
||||||
: connection_info_(std::move(info))
|
: connection_info_(std::move(info))
|
||||||
, logger_(stdout, "SQL")
|
, logger_(stdout, "SQL")
|
||||||
, dialect_(backend_provider::instance().connection_dialect(info.type))
|
, dialect_(backend_provider::instance().connection_dialect(connection_info_.type))
|
||||||
|
, table_repository_(repo)
|
||||||
{
|
{
|
||||||
connection_.reset(backend_provider::instance().create_connection(connection_info_.type, connection_info_));
|
connection_.reset(backend_provider::instance().create_connection(connection_info_.type, connection_info_));
|
||||||
}
|
}
|
||||||
|
|
||||||
connection::connection(const std::string& dns)
|
connection::connection(const std::string& dns, const std::shared_ptr<table_repository> &repo)
|
||||||
: connection(connection_info::parse(dns))
|
: connection(connection_info::parse(dns), repo)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
connection::connection(const connection &x)
|
connection::connection(const connection &x)
|
||||||
|
|
@ -68,6 +69,36 @@ const connection_info &connection::info() const
|
||||||
return connection_info_;
|
return connection_info_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query_create_intermediate connection::create()
|
||||||
|
{
|
||||||
|
return query_create_intermediate(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
query_drop_intermediate connection::drop()
|
||||||
|
{
|
||||||
|
return query_drop_intermediate{*this};
|
||||||
|
}
|
||||||
|
|
||||||
|
query_select_intermediate connection::select(std::initializer_list<column> columns)
|
||||||
|
{
|
||||||
|
return {*this, columns};
|
||||||
|
}
|
||||||
|
|
||||||
|
query_insert_intermediate connection::insert()
|
||||||
|
{
|
||||||
|
return query_insert_intermediate{*this};
|
||||||
|
}
|
||||||
|
|
||||||
|
query_update_intermediate connection::update(const std::string &table)
|
||||||
|
{
|
||||||
|
return query_update_intermediate{*this, table};
|
||||||
|
}
|
||||||
|
|
||||||
|
query_delete_intermediate connection::remove()
|
||||||
|
{
|
||||||
|
return query_delete_intermediate{*this};
|
||||||
|
}
|
||||||
|
|
||||||
record connection::describe(const std::string &table_name) const
|
record connection::describe(const std::string &table_name) const
|
||||||
{
|
{
|
||||||
return std::move(connection_->describe(table_name));
|
return std::move(connection_->describe(table_name));
|
||||||
|
|
@ -78,12 +109,41 @@ bool connection::exists(const std::string &schema_name, const std::string &table
|
||||||
return connection_->exists(schema_name, table_name);
|
return connection_->exists(schema_name, table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool connection::exists(const std::string &table_name) const
|
||||||
|
{
|
||||||
|
return connection_->exists(dialect_.default_schema_name(), table_name);
|
||||||
|
}
|
||||||
|
|
||||||
size_t connection::execute(const std::string &sql) const
|
size_t connection::execute(const std::string &sql) const
|
||||||
{
|
{
|
||||||
logger_.debug(sql);
|
logger_.debug(sql);
|
||||||
return connection_->execute(sql);
|
return connection_->execute(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query_result<record> connection::fetch(const query_context &q) const
|
||||||
|
{
|
||||||
|
if (q.prototype.empty() || q.prototype.unknown()) {
|
||||||
|
const auto table_prototype = describe(q.table_name);
|
||||||
|
for (auto &col : q.prototype) {
|
||||||
|
if (const auto rit = table_prototype.find(col.name()); col.type() == data_type_t::type_unknown && rit != table_prototype.end()) {
|
||||||
|
const_cast<column&>(col).type(rit->type());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// auto it = prototypes_.find(q.table_name);
|
||||||
|
// if (it == prototypes_.end()) {
|
||||||
|
// it = prototypes_.emplace(q.table_name, describe(q.table_name)).first;
|
||||||
|
// }
|
||||||
|
// // adjust columns from given query
|
||||||
|
// for (auto &col : q.prototype) {
|
||||||
|
// if (const auto rit = it->second.find(col.name()); col.type() == data_type_t::type_unknown && rit != it->second.end()) {
|
||||||
|
// const_cast<column&>(col).type(rit->type());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
auto res = fetch(q.sql);
|
||||||
|
return query_result<record>{std::move(res), q.prototype};
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<query_result_impl> connection::fetch(const std::string &sql) const
|
std::unique_ptr<query_result_impl> connection::fetch(const std::string &sql) const
|
||||||
{
|
{
|
||||||
logger_.debug(sql);
|
logger_.debug(sql);
|
||||||
|
|
@ -100,4 +160,9 @@ const class dialect &connection::dialect() const
|
||||||
return dialect_;
|
return dialect_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<table_repository> connection::tables() const
|
||||||
|
{
|
||||||
|
return table_repository_;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ namespace matador::sql {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
any_type_to_string_visitor::any_type_to_string_visitor(const dialect &d, query_context &query)
|
any_type_to_string_visitor::any_type_to_string_visitor(const dialect &d, query_context &query)
|
||||||
: d(d), query(query) {}
|
: d(d), query(query)
|
||||||
|
{}
|
||||||
|
|
||||||
void any_type_to_string_visitor::to_string(const char *val)
|
void any_type_to_string_visitor::to_string(const char *val)
|
||||||
{
|
{
|
||||||
|
|
@ -52,8 +53,10 @@ query_builder::query_state_transition_map query_builder::transitions_{
|
||||||
{state_t::QUERY_DELETE, {state_t::QUERY_FROM}},
|
{state_t::QUERY_DELETE, {state_t::QUERY_FROM}},
|
||||||
{state_t::QUERY_TABLE_CREATE, {state_t::QUERY_FINISH}},
|
{state_t::QUERY_TABLE_CREATE, {state_t::QUERY_FINISH}},
|
||||||
{state_t::QUERY_TABLE_DROP, {state_t::QUERY_FINISH}},
|
{state_t::QUERY_TABLE_DROP, {state_t::QUERY_FINISH}},
|
||||||
{state_t::QUERY_FROM, {state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_WHERE, state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_FINISH}},
|
{state_t::QUERY_FROM, {state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_WHERE, state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_JOIN, state_t::QUERY_FINISH}},
|
||||||
{state_t::QUERY_SET, {state_t::QUERY_WHERE, state_t::QUERY_FINISH}},
|
{state_t::QUERY_SET, {state_t::QUERY_WHERE, state_t::QUERY_FINISH}},
|
||||||
|
{state_t::QUERY_JOIN, {state_t::QUERY_ON}},
|
||||||
|
{state_t::QUERY_ON, {state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_WHERE, state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_JOIN, state_t::QUERY_FINISH}},
|
||||||
{state_t::QUERY_INTO, {state_t::QUERY_VALUES}},
|
{state_t::QUERY_INTO, {state_t::QUERY_VALUES}},
|
||||||
{state_t::QUERY_WHERE, {state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_FINISH}},
|
{state_t::QUERY_WHERE, {state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_FINISH}},
|
||||||
{state_t::QUERY_ORDER_BY, {state_t::QUERY_ORDER_DIRECTION}},
|
{state_t::QUERY_ORDER_BY, {state_t::QUERY_ORDER_DIRECTION}},
|
||||||
|
|
@ -324,26 +327,38 @@ query_builder &query_builder::from(const std::string &table, const std::string &
|
||||||
|
|
||||||
if (dialect_.default_schema_name().empty()) {
|
if (dialect_.default_schema_name().empty()) {
|
||||||
query_parts_.emplace_back(dialect::token_t::FROM, " " + dialect_.token_at(dialect::token_t::FROM) +
|
query_parts_.emplace_back(dialect::token_t::FROM, " " + dialect_.token_at(dialect::token_t::FROM) +
|
||||||
" " + dialect_.prepare_identifier(table) +
|
" " + dialect_.prepare_identifier(table) +
|
||||||
(as.empty() ? "" : " " + as));
|
(as.empty() ? "" : " AS " + dialect_.prepare_identifier(as)));
|
||||||
} else {
|
} else {
|
||||||
query_parts_.emplace_back(dialect::token_t::FROM, " " + dialect_.token_at(dialect::token_t::FROM) +
|
query_parts_.emplace_back(dialect::token_t::FROM, " " + dialect_.token_at(dialect::token_t::FROM) +
|
||||||
" " + dialect_.prepare_identifier(dialect_.default_schema_name()) +
|
" " + dialect_.prepare_identifier(dialect_.default_schema_name()) +
|
||||||
"." + dialect_.prepare_identifier(table) +
|
"." + dialect_.prepare_identifier(table) +
|
||||||
(as.empty() ? "" : " " + as));
|
(as.empty() ? "" : " AS " + dialect_.prepare_identifier(as)));
|
||||||
}
|
}
|
||||||
query_.table_name = table;
|
query_.table_name = table;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
query_builder &query_builder::join(const std::string &table, join_type_t)
|
query_builder &query_builder::join(const std::string &table, join_type_t, const std::string &as)
|
||||||
{
|
{
|
||||||
|
transition_to(state_t::QUERY_JOIN);
|
||||||
|
|
||||||
|
query_parts_.emplace_back(dialect::token_t::JOIN, " " + dialect_.token_at(dialect::token_t::JOIN) +
|
||||||
|
" " + dialect_.prepare_identifier(table) +
|
||||||
|
(as.empty() ? "" : " AS " + dialect_.prepare_identifier(as)));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
query_builder &query_builder::on(const std::string &column, const std::string &join_column)
|
query_builder &query_builder::on(const std::string &column, const std::string &join_column)
|
||||||
{
|
{
|
||||||
|
transition_to(state_t::QUERY_ON);
|
||||||
|
|
||||||
|
query_parts_.emplace_back(dialect::token_t::ON, " " + dialect_.token_at(dialect::token_t::ON) +
|
||||||
|
" " + dialect_.prepare_identifier(column) +
|
||||||
|
"=" + dialect_.prepare_identifier(join_column));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,83 +5,83 @@ namespace matador::sql {
|
||||||
|
|
||||||
query_result<record> query_select_finish::fetch_all()
|
query_result<record> query_select_finish::fetch_all()
|
||||||
{
|
{
|
||||||
return session_.fetch(builder_.compile());
|
return connection_.fetch(builder_.compile());
|
||||||
}
|
}
|
||||||
|
|
||||||
record query_select_finish::fetch_one()
|
record query_select_finish::fetch_one()
|
||||||
{
|
{
|
||||||
return *session_.fetch(builder_.compile()).begin().get();
|
return *connection_.fetch(builder_.compile()).begin().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<query_result_impl> query_select_finish::fetch()
|
std::unique_ptr<query_result_impl> query_select_finish::fetch()
|
||||||
{
|
{
|
||||||
return session_.fetch(builder_.compile().sql);
|
return connection_.fetch(builder_.compile().sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement query_select_finish::prepare()
|
statement query_select_finish::prepare()
|
||||||
{
|
{
|
||||||
return session_.prepare(builder_.compile());
|
return connection_.prepare(builder_.compile());
|
||||||
}
|
}
|
||||||
|
|
||||||
query_intermediate::query_intermediate(session &db, query_builder &query)
|
query_intermediate::query_intermediate(connection &db, query_builder &query)
|
||||||
: session_(db), builder_(query) {}
|
: connection_(db), builder_(query) {}
|
||||||
|
|
||||||
query_offset_intermediate query_order_direction_intermediate::offset(size_t offset)
|
query_offset_intermediate query_order_direction_intermediate::offset(size_t offset)
|
||||||
{
|
{
|
||||||
return {session_, builder_};
|
return {connection_, builder_};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_limit_intermediate query_offset_intermediate::limit(size_t limit)
|
query_limit_intermediate query_offset_intermediate::limit(size_t limit)
|
||||||
{
|
{
|
||||||
return {session_, builder_};
|
return {connection_, builder_};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_limit_intermediate query_order_direction_intermediate::limit(size_t limit)
|
query_limit_intermediate query_order_direction_intermediate::limit(size_t limit)
|
||||||
{
|
{
|
||||||
return {session_, builder_};
|
return {connection_, builder_};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_order_by_intermediate query_group_by_intermediate::order_by(const std::string &name)
|
query_order_by_intermediate query_group_by_intermediate::order_by(const std::string &name)
|
||||||
{
|
{
|
||||||
return {session_, builder_.order_by(name)};
|
return {connection_, builder_.order_by(name)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_order_direction_intermediate query_order_by_intermediate::asc()
|
query_order_direction_intermediate query_order_by_intermediate::asc()
|
||||||
{
|
{
|
||||||
return {session_, builder_.asc()};
|
return {connection_, builder_.asc()};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_order_direction_intermediate query_order_by_intermediate::desc()
|
query_order_direction_intermediate query_order_by_intermediate::desc()
|
||||||
{
|
{
|
||||||
return {session_, builder_.desc()};
|
return {connection_, builder_.desc()};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_group_by_intermediate query_from_intermediate::group_by(const std::string &name)
|
query_group_by_intermediate query_from_intermediate::group_by(const std::string &name)
|
||||||
{
|
{
|
||||||
return {session_, builder_.group_by(name)};
|
return {connection_, builder_.group_by(name)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_order_by_intermediate query_from_intermediate::order_by(const std::string &name)
|
query_order_by_intermediate query_from_intermediate::order_by(const std::string &name)
|
||||||
{
|
{
|
||||||
return {session_, builder_.order_by(name)};
|
return {connection_, builder_.order_by(name)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_group_by_intermediate query_where_intermediate::group_by(const std::string &name)
|
query_group_by_intermediate query_where_intermediate::group_by(const std::string &name)
|
||||||
{
|
{
|
||||||
return {session_, builder_.group_by(name)};
|
return {connection_, builder_.group_by(name)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_order_by_intermediate query_where_intermediate::order_by(const std::string &name)
|
query_order_by_intermediate query_where_intermediate::order_by(const std::string &name)
|
||||||
{
|
{
|
||||||
return {session_, builder_.order_by(name)};
|
return {connection_, builder_.order_by(name)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_where_intermediate query_from_intermediate::where(const basic_condition &cond)
|
query_where_intermediate query_from_intermediate::where(const basic_condition &cond)
|
||||||
{
|
{
|
||||||
return query_where_intermediate{session_, builder_.where(cond)};
|
return query_where_intermediate{connection_, builder_.where(cond)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_select_intermediate::query_select_intermediate(session &s, const std::vector<column>& columns)
|
query_select_intermediate::query_select_intermediate(connection &s, const std::vector<column>& columns)
|
||||||
: query_start_intermediate(s)
|
: query_start_intermediate(s)
|
||||||
{
|
{
|
||||||
builder_.select(columns);
|
builder_.select(columns);
|
||||||
|
|
@ -89,10 +89,10 @@ query_select_intermediate::query_select_intermediate(session &s, const std::vect
|
||||||
|
|
||||||
query_from_intermediate query_select_intermediate::from(const std::string &table, const std::string &as)
|
query_from_intermediate query_select_intermediate::from(const std::string &table, const std::string &as)
|
||||||
{
|
{
|
||||||
return {session_, builder_.from(table, as)};
|
return {connection_, builder_.from(table, as)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_insert_intermediate::query_insert_intermediate(session &s)
|
query_insert_intermediate::query_insert_intermediate(connection &s)
|
||||||
: query_start_intermediate(s)
|
: query_start_intermediate(s)
|
||||||
{
|
{
|
||||||
builder_.insert();
|
builder_.insert();
|
||||||
|
|
@ -100,36 +100,40 @@ query_insert_intermediate::query_insert_intermediate(session &s)
|
||||||
|
|
||||||
query_into_intermediate query_insert_intermediate::into(const std::string &table, std::initializer_list<std::string> column_names)
|
query_into_intermediate query_insert_intermediate::into(const std::string &table, std::initializer_list<std::string> column_names)
|
||||||
{
|
{
|
||||||
return {session_, builder_.into(table, column_names)};
|
return {connection_, builder_.into(table, column_names)};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t query_execute_finish::execute()
|
size_t query_execute_finish::execute()
|
||||||
{
|
{
|
||||||
return session_.execute(builder_.compile().sql);
|
return connection_.execute(builder_.compile().sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
statement query_execute_finish::prepare()
|
statement query_execute_finish::prepare()
|
||||||
{
|
{
|
||||||
return session_.prepare(builder_.compile());
|
return connection_.prepare(builder_.compile());
|
||||||
}
|
}
|
||||||
|
|
||||||
query_execute_finish query_into_intermediate::values(std::initializer_list<any_type> values)
|
query_execute_finish query_into_intermediate::values(std::initializer_list<any_type> values)
|
||||||
{
|
{
|
||||||
return {session_, builder_.values(values)};
|
return {connection_, builder_.values(values)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_create_intermediate::query_create_intermediate(session &s, table_repository &repo)
|
query_create_intermediate::query_create_intermediate(connection &db)
|
||||||
: query_start_intermediate(s)
|
: query_start_intermediate(db) {
|
||||||
, repository_(repo) {
|
|
||||||
builder_.create();
|
builder_.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
query_execute_finish query_create_intermediate::table(const std::string &table, std::initializer_list<column> columns)
|
query_execute_finish query_create_intermediate::table(const std::string &table, std::initializer_list<column> columns)
|
||||||
{
|
{
|
||||||
return {session_, builder_.table(table, columns)};
|
return {connection_, builder_.table(table, columns)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_drop_intermediate::query_drop_intermediate(session &s)
|
std::shared_ptr<table_repository> query_create_intermediate::tables() const
|
||||||
|
{
|
||||||
|
return connection_.tables();
|
||||||
|
}
|
||||||
|
|
||||||
|
query_drop_intermediate::query_drop_intermediate(connection &s)
|
||||||
: query_start_intermediate(s)
|
: query_start_intermediate(s)
|
||||||
{
|
{
|
||||||
builder_.drop();
|
builder_.drop();
|
||||||
|
|
@ -137,20 +141,20 @@ query_drop_intermediate::query_drop_intermediate(session &s)
|
||||||
|
|
||||||
query_execute_finish query_drop_intermediate::table(const std::string &table)
|
query_execute_finish query_drop_intermediate::table(const std::string &table)
|
||||||
{
|
{
|
||||||
return {session_, builder_.table(table)};
|
return {connection_, builder_.table(table)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_execute_finish query_execute_where_intermediate::limit(int limit)
|
query_execute_finish query_execute_where_intermediate::limit(int limit)
|
||||||
{
|
{
|
||||||
return {session_, builder_.limit(limit)};
|
return {connection_, builder_.limit(limit)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_execute_where_intermediate query_set_intermediate::where(const basic_condition &cond)
|
query_execute_where_intermediate query_set_intermediate::where(const basic_condition &cond)
|
||||||
{
|
{
|
||||||
return {session_, builder_.where(cond)};
|
return {connection_, builder_.where(cond)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_update_intermediate::query_update_intermediate(session &s, const std::string& table_name)
|
query_update_intermediate::query_update_intermediate(connection &s, const std::string& table_name)
|
||||||
: query_start_intermediate(s)
|
: query_start_intermediate(s)
|
||||||
{
|
{
|
||||||
builder_.update(table_name);
|
builder_.update(table_name);
|
||||||
|
|
@ -158,15 +162,15 @@ query_update_intermediate::query_update_intermediate(session &s, const std::stri
|
||||||
|
|
||||||
query_set_intermediate query_update_intermediate::set(std::initializer_list<key_value_pair> columns)
|
query_set_intermediate query_update_intermediate::set(std::initializer_list<key_value_pair> columns)
|
||||||
{
|
{
|
||||||
return {session_, builder_.set(columns)};
|
return {connection_, builder_.set(columns)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_execute_where_intermediate query_delete_from_intermediate::where(const basic_condition &cond)
|
query_execute_where_intermediate query_delete_from_intermediate::where(const basic_condition &cond)
|
||||||
{
|
{
|
||||||
return {session_, builder_.where(cond)};
|
return {connection_, builder_.where(cond)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_delete_intermediate::query_delete_intermediate(session &s)
|
query_delete_intermediate::query_delete_intermediate(connection &s)
|
||||||
: query_start_intermediate(s)
|
: query_start_intermediate(s)
|
||||||
{
|
{
|
||||||
builder_.remove();
|
builder_.remove();
|
||||||
|
|
@ -174,11 +178,11 @@ query_delete_intermediate::query_delete_intermediate(session &s)
|
||||||
|
|
||||||
query_delete_from_intermediate query_delete_intermediate::from(const std::string &table)
|
query_delete_from_intermediate query_delete_intermediate::from(const std::string &table)
|
||||||
{
|
{
|
||||||
return {session_, builder_.from(table)};
|
return {connection_, builder_.from(table)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_start_intermediate::query_start_intermediate(session &s)
|
query_start_intermediate::query_start_intermediate(connection &s)
|
||||||
: session_(s)
|
: connection_(s)
|
||||||
, builder_(s.dialect())
|
, builder_(s.dialect())
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "matador/sql/record.hpp"
|
#include "matador/sql/record.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
@ -133,6 +134,13 @@ void record::clear()
|
||||||
columns_by_name_.clear();
|
columns_by_name_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool record::unknown() const
|
||||||
|
{
|
||||||
|
return std::all_of(std::begin(columns_), std::end(columns_), [](const auto &col) {
|
||||||
|
return col.type() == data_type_t::type_unknown;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void record::init()
|
void record::init()
|
||||||
{
|
{
|
||||||
size_t index{0};
|
size_t index{0};
|
||||||
|
|
|
||||||
|
|
@ -10,36 +10,6 @@ session::session(connection_pool<connection> &pool)
|
||||||
: pool_(pool)
|
: pool_(pool)
|
||||||
, dialect_(backend_provider::instance().connection_dialect(pool_.info().type)) {}
|
, dialect_(backend_provider::instance().connection_dialect(pool_.info().type)) {}
|
||||||
|
|
||||||
query_create_intermediate session::create()
|
|
||||||
{
|
|
||||||
return query_create_intermediate{*this, table_repository_};
|
|
||||||
}
|
|
||||||
|
|
||||||
query_drop_intermediate session::drop()
|
|
||||||
{
|
|
||||||
return query_drop_intermediate{*this};
|
|
||||||
}
|
|
||||||
|
|
||||||
query_select_intermediate session::select(std::initializer_list<column> columns)
|
|
||||||
{
|
|
||||||
return {*this, columns};
|
|
||||||
}
|
|
||||||
|
|
||||||
query_insert_intermediate session::insert()
|
|
||||||
{
|
|
||||||
return query_insert_intermediate{*this};
|
|
||||||
}
|
|
||||||
|
|
||||||
query_update_intermediate session::update(const std::string &table)
|
|
||||||
{
|
|
||||||
return query_update_intermediate{*this, table};
|
|
||||||
}
|
|
||||||
|
|
||||||
query_delete_intermediate session::remove()
|
|
||||||
{
|
|
||||||
return query_delete_intermediate{*this};
|
|
||||||
}
|
|
||||||
|
|
||||||
query_result<record> session::fetch(const query_context &q) const
|
query_result<record> session::fetch(const query_context &q) const
|
||||||
{
|
{
|
||||||
auto c = pool_.acquire();
|
auto c = pool_.acquire();
|
||||||
|
|
|
||||||
|
|
@ -31,4 +31,9 @@ std::pair<std::string, std::string> table_repository::reference(const std::type_
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool table_repository::exists(const std::type_index &ti) const
|
||||||
|
{
|
||||||
|
return repository_.count(ti) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +23,6 @@ add_executable(tests QueryBuilderTest.cpp
|
||||||
models/person.hpp
|
models/person.hpp
|
||||||
AnyTypeToVisitorTest.cpp
|
AnyTypeToVisitorTest.cpp
|
||||||
ColumnTest.cpp
|
ColumnTest.cpp
|
||||||
StatementCacheTest.cpp
|
|
||||||
models/coordinate.hpp
|
models/coordinate.hpp
|
||||||
models/location.hpp
|
models/location.hpp
|
||||||
models/optional.hpp
|
models/optional.hpp
|
||||||
|
|
|
||||||
|
|
@ -175,3 +175,13 @@ TEST_CASE("Create, insert and select a blob column", "[query][blob]") {
|
||||||
REQUIRE(q.sql == R"(SELECT "id", "name", "data" FROM "person")");
|
REQUIRE(q.sql == R"(SELECT "id", "name", "data" FROM "person")");
|
||||||
REQUIRE(q.table_name == "person");
|
REQUIRE(q.table_name == "person");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Select statement with join", "[query][join]") {
|
||||||
|
dialect d = dialect_builder::builder().create().build();
|
||||||
|
query_builder query(d);
|
||||||
|
|
||||||
|
auto q = query.select({"f.id", "ap.brand", "f.pilot_name"}).from("flight", "f").join("airplane", join_type_t::INNER, "ap").on("f.airplane_id", "ap.id").compile();
|
||||||
|
|
||||||
|
REQUIRE(q.sql == R"(SELECT "f.id", "ap.brand", "f.pilot_name" FROM "flight" AS "f" INNER JOIN "airplane" AS "ap" ON "f.airplane_id"="ap.id")");
|
||||||
|
REQUIRE(q.table_name == "flight");
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue