implemented prepared statement for postgres and sqlite
This commit is contained in:
+3
-1
@@ -25,7 +25,9 @@ add_executable(tests QueryBuilderTest.cpp
|
||||
models/person.hpp
|
||||
AnyTypeToVisitorTest.cpp
|
||||
ColumnTest.cpp
|
||||
SessionRecordTest.cpp)
|
||||
SessionRecordTest.cpp
|
||||
StatementCacheTest.cpp
|
||||
StatementTest.cpp)
|
||||
target_link_libraries(tests PRIVATE
|
||||
Catch2::Catch2WithMain
|
||||
matador
|
||||
|
||||
+23
-11
@@ -2,13 +2,13 @@
|
||||
|
||||
#include <matador/sql/column.hpp>
|
||||
#include <matador/sql/condition.hpp>
|
||||
#include <matador/sql/dialect.hpp>
|
||||
#include <matador/sql/dialect_builder.hpp>
|
||||
#include <matador/sql/query_builder.hpp>
|
||||
|
||||
using namespace matador::sql;
|
||||
|
||||
TEST_CASE("Create table sql statement string", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
auto q = query.create().table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
@@ -31,7 +31,7 @@ TEST_CASE("Create table sql statement string", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Drop table sql statement string", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.drop().table("person").compile();
|
||||
|
||||
@@ -40,7 +40,7 @@ TEST_CASE("Drop table sql statement string", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Select sql statement string", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.select({"id", "name", "age"}).from("person").compile();
|
||||
|
||||
@@ -49,7 +49,7 @@ TEST_CASE("Select sql statement string", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Insert sql statement string", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.insert().into("person", {
|
||||
"id", "name", "age"
|
||||
@@ -60,7 +60,7 @@ TEST_CASE("Insert sql statement string", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Update sql statement string", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.update("person").set({
|
||||
{"id", 7UL},
|
||||
@@ -73,7 +73,7 @@ TEST_CASE("Update sql statement string", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Delete sql statement string", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.remove().from("person").compile();
|
||||
|
||||
@@ -82,7 +82,7 @@ TEST_CASE("Delete sql statement string", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Select sql statement string with where clause", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
auto q = query.select({"id", "name", "age"})
|
||||
.from("person")
|
||||
@@ -101,8 +101,20 @@ TEST_CASE("Select sql statement string with where clause", "[query]") {
|
||||
REQUIRE(q.table_name == "person");
|
||||
}
|
||||
|
||||
TEST_CASE("Insert sql statement with placeholder", "[query]") {
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.insert().into("person", {
|
||||
"id", "name", "age"
|
||||
}).values({_, _, _}).compile();
|
||||
|
||||
REQUIRE(q.sql == R"(INSERT INTO "person" ("id", "name", "age") VALUES (?, ?, ?))");
|
||||
REQUIRE(q.table_name == "person");
|
||||
REQUIRE(q.bind_vars.size() == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("Select sql statement string with order by", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.select({"id", "name", "age"})
|
||||
.from("person")
|
||||
@@ -114,7 +126,7 @@ TEST_CASE("Select sql statement string with order by", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Select sql statement string with group by", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.select({"id", "name", "age"})
|
||||
.from("person")
|
||||
@@ -126,7 +138,7 @@ TEST_CASE("Select sql statement string with group by", "[query]") {
|
||||
}
|
||||
|
||||
TEST_CASE("Select sql statement string with offset and limit", "[query]") {
|
||||
dialect d;
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
const auto q = query.select({"id", "name", "age"})
|
||||
.from("person")
|
||||
|
||||
@@ -365,7 +365,7 @@ TEST_CASE("Execute delete statement", "[session record]") {
|
||||
.where("id"_col == 1)
|
||||
.execute();
|
||||
|
||||
REQUIRE(res.second == R"(DELETE FROM "person" WHERE "id" = 1)");
|
||||
REQUIRE(res.second == R"(DELETE FROM "main"."person" WHERE "id" = 1)");
|
||||
REQUIRE(res.first == 1);
|
||||
|
||||
count = s.select({count_all()}).from("person").fetch_value<int>();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "matador/sql/connection_info.hpp"
|
||||
#include "matador/sql/connection_pool.hpp"
|
||||
#include "matador/sql/session.hpp"
|
||||
#include "matador/sql/statement_cache.hpp"
|
||||
|
||||
using namespace matador;
|
||||
|
||||
class TestConnection
|
||||
{
|
||||
public:
|
||||
explicit TestConnection(sql::connection_info info)
|
||||
: info_(std::move(info)) {}
|
||||
void open() {}
|
||||
|
||||
private:
|
||||
sql::connection_info info_;
|
||||
};
|
||||
|
||||
TEST_CASE("Acquire prepared statement", "[statement cache]") {
|
||||
sql::statement_cache cache;
|
||||
sql::connection_pool<TestConnection> pool("sqlite://sqlite.db", 4);
|
||||
|
||||
// sql::session s(pool);
|
||||
// auto conn = pool.acquire();
|
||||
|
||||
std::string sql = R"(SELECT * FROM person WHERE name = 'george')";
|
||||
// auto stmt = cache.acquire(sql, conn);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/catch_template_test_macros.hpp>
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/condition.hpp"
|
||||
#include "matador/sql/connection_info.hpp"
|
||||
#include "matador/sql/connection_pool.hpp"
|
||||
#include "matador/sql/session.hpp"
|
||||
|
||||
#include "models/airplane.hpp"
|
||||
|
||||
using namespace matador::sql;
|
||||
using namespace matador::test;
|
||||
|
||||
struct Postgres
|
||||
{
|
||||
// constexpr static const char *dns{"postgres://test:test123@127.0.0.1:15432/test"};
|
||||
constexpr static const char *dns{"postgres://test:test123@127.0.0.1:5432/matador_test"};
|
||||
};
|
||||
|
||||
struct Sqlite
|
||||
{
|
||||
constexpr static const char *dns{"sqlite://sqlite.db"};
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
class StatementTestFixture
|
||||
{
|
||||
public:
|
||||
StatementTestFixture()
|
||||
: pool_(Type::dns, 4), session_(pool_)
|
||||
{
|
||||
auto res = session_.create()
|
||||
.table<airplane>("airplane")
|
||||
.execute();
|
||||
REQUIRE(res.first == 0);
|
||||
REQUIRE(res.second == R"(CREATE TABLE "airplane" ("id" BIGINT, "brand" VARCHAR(255), "model" VARCHAR(255), CONSTRAINT PK_airplane PRIMARY KEY (id)))");
|
||||
}
|
||||
|
||||
~StatementTestFixture()
|
||||
{
|
||||
session_.drop().table("airplane").execute();
|
||||
}
|
||||
|
||||
matador::sql::session &session()
|
||||
{ return session_; }
|
||||
|
||||
std::vector<entity<airplane>> &planes()
|
||||
{ return planes_; }
|
||||
|
||||
private:
|
||||
matador::sql::connection_pool<matador::sql::connection> pool_;
|
||||
matador::sql::session session_;
|
||||
|
||||
std::vector<entity<airplane>> planes_{
|
||||
make_entity<airplane>(1, "Airbus", "A380"),
|
||||
make_entity<airplane>(2, "Boeing", "707"),
|
||||
make_entity<airplane>(3, "Boeing", "747")
|
||||
};
|
||||
};
|
||||
|
||||
TEMPLATE_TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]", Sqlite, Postgres)
|
||||
{
|
||||
auto &s = StatementTestFixture<TestType>::session();
|
||||
auto &planes = StatementTestFixture<TestType>::planes();
|
||||
|
||||
SECTION("Insert with prepared statement and placeholder") {
|
||||
auto stmt = s.insert()
|
||||
.template into<airplane>("airplane")
|
||||
.template values<airplane>().prepare();
|
||||
|
||||
for (const auto &plane: planes) {
|
||||
auto res = stmt.bind(*plane).execute();
|
||||
REQUIRE(res == 1);
|
||||
stmt.reset();
|
||||
}
|
||||
|
||||
auto result = s.template select<airplane>().from("airplane").template fetch_all<airplane>();
|
||||
|
||||
size_t index{0};
|
||||
for (const auto &i: result) {
|
||||
REQUIRE(i.id == planes[index]->id);
|
||||
REQUIRE(i.brand == planes[index]->brand);
|
||||
REQUIRE(i.model == planes[index++]->model);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Select with prepared statement") {
|
||||
for (const auto &plane: planes) {
|
||||
auto res = s.insert().template into<airplane>("airplane").values(*plane).execute();
|
||||
REQUIRE(res.first == 1);
|
||||
}
|
||||
|
||||
auto stmt = s.template select<airplane>().from("airplane").where("brand"_col == _).prepare();
|
||||
|
||||
stmt.bind(0, "Airbus");
|
||||
|
||||
auto result = stmt.template fetch<airplane>();
|
||||
|
||||
for (const auto &i: result) {
|
||||
REQUIRE(i.id == planes[0]->id);
|
||||
REQUIRE(i.brand == planes[0]->brand);
|
||||
REQUIRE(i.model == planes[0]->model);
|
||||
}
|
||||
|
||||
stmt.reset();
|
||||
|
||||
stmt.bind(0, "Boeing");
|
||||
|
||||
result = stmt.template fetch<airplane>();
|
||||
|
||||
size_t index{1};
|
||||
for (const auto &i: result) {
|
||||
REQUIRE(i.id == planes[index]->id);
|
||||
REQUIRE(i.brand == planes[index]->brand);
|
||||
REQUIRE(i.model == planes[index++]->model);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user