query compiler progress
This commit is contained in:
parent
b966a7a1a7
commit
a3f467a5a8
|
|
@ -58,7 +58,7 @@ std::unique_ptr<sql::query_result_impl> postgres_connection::fetch(const std::st
|
|||
auto type = PQftype(res, i);
|
||||
auto size = PQfmod(res, i);
|
||||
// std::cout << "column " << col_name << ", type " << type << " (size: " << size << ")\n";
|
||||
prototype.append({col_name});
|
||||
prototype.append(sql::column_definition{col_name});
|
||||
}
|
||||
return std::move(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), std::move(prototype)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ int sqlite_connection::parse_result(void* param, int column_count, char** values
|
|||
|
||||
if (context->prototype.empty()) {
|
||||
for(int i = 0; i < column_count; ++i) {
|
||||
context->prototype.append(sql::column{columns[i]});
|
||||
context->prototype.append(sql::column_definition{columns[i]});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/condition.hpp"
|
||||
#include "matador/sql/connection.hpp"
|
||||
#include "matador/sql/query_builder.hpp"
|
||||
|
||||
#include "connection.hpp"
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ protected:
|
|||
private:
|
||||
void drop_table_if_exists(const std::string &table_name) {
|
||||
if (db.exists(table_name)) {
|
||||
db.drop().table(table_name).execute();
|
||||
db.query().drop().table(table_name).execute();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -39,7 +40,7 @@ using namespace matador::sql;
|
|||
TEST_CASE_METHOD(QueryRecordFixture, " Create and drop table statement", "[session][record]")
|
||||
{
|
||||
REQUIRE(!db.exists("person"));
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
|
|
@ -49,7 +50,7 @@ TEST_CASE_METHOD(QueryRecordFixture, " Create and drop table statement", "[sessi
|
|||
|
||||
REQUIRE(db.exists("person"));
|
||||
|
||||
db.drop()
|
||||
db.query().drop()
|
||||
.table("person")
|
||||
.execute();
|
||||
|
||||
|
|
@ -58,7 +59,7 @@ TEST_CASE_METHOD(QueryRecordFixture, " Create and drop table statement", "[sessi
|
|||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Create and drop table statement with foreign key", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("airplane", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("brand", 255),
|
||||
|
|
@ -68,7 +69,7 @@ TEST_CASE_METHOD(QueryRecordFixture, " Create and drop table statement with fore
|
|||
|
||||
REQUIRE(db.exists("airplane"));
|
||||
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("flight", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_fk_column<unsigned long>("airplane_id", "airplane", "id"),
|
||||
|
|
@ -78,13 +79,13 @@ TEST_CASE_METHOD(QueryRecordFixture, " Create and drop table statement with fore
|
|||
|
||||
REQUIRE(db.exists("flight"));
|
||||
|
||||
db.drop()
|
||||
db.query().drop()
|
||||
.table("flight")
|
||||
.execute();
|
||||
|
||||
REQUIRE(!db.exists("flight"));
|
||||
|
||||
db.drop()
|
||||
db.query().drop()
|
||||
.table("airplane")
|
||||
.execute();
|
||||
|
||||
|
|
@ -93,7 +94,7 @@ TEST_CASE_METHOD(QueryRecordFixture, " Create and drop table statement with fore
|
|||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Execute insert record statement", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
|
|
@ -101,14 +102,14 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute insert record statement", "[sessi
|
|||
})
|
||||
.execute();
|
||||
|
||||
auto res = db.insert()
|
||||
auto res = db.query().insert()
|
||||
.into("person", {"id", "name", "age"})
|
||||
.values({7, "george", 45})
|
||||
.execute();
|
||||
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto result = db.select({"id", "name", "age"})
|
||||
auto result = db.query().select({"id", "name", "age"})
|
||||
.from("person")
|
||||
.fetch_all();
|
||||
|
||||
|
|
@ -125,14 +126,14 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute insert record statement", "[sessi
|
|||
REQUIRE(i.at(2).template as<int>() == 45);
|
||||
}
|
||||
|
||||
db.drop()
|
||||
db.query().drop()
|
||||
.table("person")
|
||||
.execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Execute insert record statement with foreign key", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("airplane", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("brand", 255),
|
||||
|
|
@ -140,7 +141,7 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute insert record statement with fore
|
|||
})
|
||||
.execute();
|
||||
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("flight", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_fk_column<unsigned long>("airplane_id", "airplane", "id"),
|
||||
|
|
@ -148,23 +149,23 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute insert record statement with fore
|
|||
})
|
||||
.execute();
|
||||
|
||||
auto res = db.insert().into("airplane", {"id", "brand", "model"}).values({1, "Airbus", "A380"}).execute();
|
||||
auto res = db.query().insert().into("airplane", {"id", "brand", "model"}).values({1, "Airbus", "A380"}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
res = db.insert().into("airplane", {"id", "brand", "model"}).values({2, "Boeing", "707"}).execute();
|
||||
res = db.query().insert().into("airplane", {"id", "brand", "model"}).values({2, "Boeing", "707"}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
res = db.insert().into("airplane", {"id", "brand", "model"}).values({3, "Boeing", "747"}).execute();
|
||||
res = db.query().insert().into("airplane", {"id", "brand", "model"}).values({3, "Boeing", "747"}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto count = db.select({count_all()}).from("airplane").fetch_value<int>();
|
||||
auto count = db.query().select({count_all()}).from("airplane").fetch_value<int>();
|
||||
REQUIRE(count == 3);
|
||||
|
||||
res = db.insert().into("flight", {"id", "airplane_id", "pilot_name"}).values({4, 1, "George"}).execute();
|
||||
res = db.query().insert().into("flight", {"id", "airplane_id", "pilot_name"}).values({4, 1, "George"}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
db.drop().table("flight").execute();
|
||||
db.drop().table("airplane").execute();
|
||||
db.query().drop().table("flight").execute();
|
||||
db.query().drop().table("airplane").execute();
|
||||
|
||||
REQUIRE(!db.exists("flight"));
|
||||
REQUIRE(!db.exists("airplane"));
|
||||
|
|
@ -172,7 +173,7 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute insert record statement with fore
|
|||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Execute update record statement", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
|
|
@ -180,14 +181,14 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute update record statement", "[sessi
|
|||
})
|
||||
.execute();
|
||||
|
||||
auto res = db.insert()
|
||||
auto res = db.query().insert()
|
||||
.into("person", {"id", "name", "age"})
|
||||
.values({7, "george", 45})
|
||||
.execute();
|
||||
|
||||
REQUIRE(res == 1);
|
||||
|
||||
res = db.update("person")
|
||||
res = db.query().update("person")
|
||||
.set({{"id", 7},
|
||||
{"name", "jane"},
|
||||
{"age", 35}})
|
||||
|
|
@ -196,7 +197,7 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute update record statement", "[sessi
|
|||
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto result = db.select({"id", "name", "age"})
|
||||
auto result = db.query().select({"id", "name", "age"})
|
||||
.from("person")
|
||||
.fetch_all();
|
||||
|
||||
|
|
@ -213,12 +214,12 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute update record statement", "[sessi
|
|||
REQUIRE(i.at(2).as<int>() == 35);
|
||||
}
|
||||
|
||||
db.drop().table("person").execute();
|
||||
db.query().drop().table("person").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
|
|
@ -226,16 +227,16 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement", "[session][rec
|
|||
})
|
||||
.execute();
|
||||
|
||||
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
auto res = db.query().insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto result = db.select({"id", "name", "age"})
|
||||
auto result = db.query().select({"id", "name", "age"})
|
||||
.from("person")
|
||||
.fetch_all();
|
||||
|
||||
|
|
@ -246,22 +247,22 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement", "[session][rec
|
|||
}
|
||||
REQUIRE(expected_names.empty());
|
||||
|
||||
auto rec = db.select({"id", "name", "age"})
|
||||
auto rec = db.query().select({"id", "name", "age"})
|
||||
.from("person")
|
||||
.fetch_one();
|
||||
REQUIRE(rec.at(1).str() == "george");
|
||||
|
||||
auto name = db.select({"name"})
|
||||
auto name = db.query().select({"name"})
|
||||
.from("person")
|
||||
.fetch_value<std::string>();
|
||||
REQUIRE(name == "george");
|
||||
|
||||
db.drop().table("person").execute();
|
||||
db.query().drop().table("person").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement with order by", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
|
|
@ -269,16 +270,16 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement with order by",
|
|||
})
|
||||
.execute();
|
||||
|
||||
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
auto res = db.query().insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto result = db.select({"id", "name", "age"})
|
||||
auto result = db.query().select({"id", "name", "age"})
|
||||
.from("person")
|
||||
.order_by("name").asc()
|
||||
.fetch_all();
|
||||
|
|
@ -290,12 +291,12 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement with order by",
|
|||
}
|
||||
REQUIRE(expected_names.empty());
|
||||
|
||||
db.drop().table("person").execute();
|
||||
db.query().drop().table("person").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement with group by and order by", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
|
|
@ -303,18 +304,18 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement with group by an
|
|||
})
|
||||
.execute();
|
||||
|
||||
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
auto res = db.query().insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({3, "michael", 13}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({3, "michael", 13}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({5, "charlie", 67}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({5, "charlie", 67}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto result = db.select({alias(count("age"), "age_count"), "age"})
|
||||
auto result = db.query().select({alias(count("age"), "age_count"), "age"})
|
||||
.from("person")
|
||||
.group_by("age")
|
||||
.order_by("age_count").desc()
|
||||
|
|
@ -329,41 +330,41 @@ TEST_CASE_METHOD(QueryRecordFixture, " Execute select statement with group by an
|
|||
expected_values.pop_front();
|
||||
}
|
||||
|
||||
db.drop().table("person").execute();
|
||||
db.query().drop().table("person").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Execute delete statement", "[session][record]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
make_column<unsigned short>("age")
|
||||
}).execute();
|
||||
|
||||
auto res = db.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
auto res = db.query().insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute();
|
||||
REQUIRE(res == 1);
|
||||
res = db.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
||||
res = db.query().insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto count = db.select({count_all()}).from("person").fetch_value<int>();
|
||||
auto count = db.query().select({count_all()}).from("person").fetch_value<int>();
|
||||
REQUIRE(count == 2);
|
||||
|
||||
res = db.remove()
|
||||
res = db.query().remove()
|
||||
.from("person")
|
||||
.where("id"_col == 1)
|
||||
.execute();
|
||||
|
||||
REQUIRE(res == 1);
|
||||
|
||||
count = db.select({count_all()}).from("person").fetch_value<int>();
|
||||
count = db.query().select({count_all()}).from("person").fetch_value<int>();
|
||||
REQUIRE(count == 1);
|
||||
|
||||
db.drop().table("person").execute();
|
||||
db.query().drop().table("person").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryRecordFixture, " Test quoted identifier", "[session][record]") {
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("quotes", {
|
||||
make_column<std::string>("from", 255),
|
||||
make_column<std::string>("to", 255)
|
||||
|
|
@ -379,19 +380,19 @@ TEST_CASE_METHOD(QueryRecordFixture, " Test quoted identifier", "[session][recor
|
|||
REQUIRE(field.type() == types[field.index()]);
|
||||
}
|
||||
|
||||
db.insert().into("quotes", {"from", "to"}).values({"Berlin", "London"}).execute();
|
||||
db.query().insert().into("quotes", {"from", "to"}).values({"Berlin", "London"}).execute();
|
||||
|
||||
auto res = db.select({"from", "to"}).from("quotes").fetch_one();
|
||||
auto res = db.query().select({"from", "to"}).from("quotes").fetch_one();
|
||||
|
||||
REQUIRE("Berlin" == res.at("from").str());
|
||||
REQUIRE("London" == res.at("to").str());
|
||||
|
||||
db.update("quotes").set({{"from", "Hamburg"}, {"to", "New York"}}).where("from"_col == "Berlin").execute();
|
||||
db.query().update("quotes").set({{"from", "Hamburg"}, {"to", "New York"}}).where("from"_col == "Berlin").execute();
|
||||
|
||||
res = db.select({"from", "to"}).from("quotes").fetch_one();
|
||||
res = db.query().select({"from", "to"}).from("quotes").fetch_one();
|
||||
|
||||
REQUIRE("Hamburg" == res.at("from").str());
|
||||
REQUIRE("New York" == res.at("to").str());
|
||||
|
||||
db.drop().table("quotes").execute();
|
||||
db.query().drop().table("quotes").execute();
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
#include "catch2/catch_test_macros.hpp"
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/condition.hpp"
|
||||
#include "matador/sql/query_builder.hpp"
|
||||
#include "matador/sql/session.hpp"
|
||||
|
||||
#include "connection.hpp"
|
||||
|
|
@ -36,27 +37,27 @@ private:
|
|||
void drop_table_if_exists(const std::string &table_name)
|
||||
{
|
||||
if (db.exists(table_name)) {
|
||||
db.drop().table(table_name).execute();
|
||||
db.query().drop().table(table_name).execute();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, " Create table with foreign key relation", "[session]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<airplane>("airplane")
|
||||
.execute();
|
||||
|
||||
REQUIRE(db.exists("airplane"));
|
||||
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<flight>("flight")
|
||||
.execute();
|
||||
|
||||
REQUIRE(db.exists("flight"));
|
||||
|
||||
db.drop().table("flight").execute();
|
||||
db.drop().table("airplane").execute();
|
||||
db.query().drop().table("flight").execute();
|
||||
db.query().drop().table("airplane").execute();
|
||||
|
||||
REQUIRE(!db.exists("flight"));
|
||||
REQUIRE(!db.exists("airplane"));
|
||||
|
|
@ -64,20 +65,20 @@ TEST_CASE_METHOD(QueryFixture, " Create table with foreign key relation", "[sess
|
|||
|
||||
TEST_CASE_METHOD(QueryFixture, " Execute select statement with where clause", "[session]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<person>("person")
|
||||
.execute();
|
||||
|
||||
person george{7, "george", 45};
|
||||
george.image.push_back(37);
|
||||
|
||||
auto res = db.insert()
|
||||
auto res = db.query().insert()
|
||||
.into("person", george)
|
||||
.execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
// fetch person as record
|
||||
auto result_record = db.select<person>()
|
||||
auto result_record = db.query().select<person>()
|
||||
.from("person")
|
||||
.where("id"_col == 7)
|
||||
.fetch_all();
|
||||
|
|
@ -96,7 +97,7 @@ TEST_CASE_METHOD(QueryFixture, " Execute select statement with where clause", "[
|
|||
}
|
||||
|
||||
// fetch person as person
|
||||
auto result_person = db.select<person>()
|
||||
auto result_person = db.query().select<person>()
|
||||
.from("person")
|
||||
.where("id"_col == 7)
|
||||
.fetch_all<person>();
|
||||
|
|
@ -107,12 +108,12 @@ TEST_CASE_METHOD(QueryFixture, " Execute select statement with where clause", "[
|
|||
REQUIRE(i.age == 45);
|
||||
}
|
||||
|
||||
db.drop().table("person").execute();
|
||||
db.query().drop().table("person").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, " Execute insert statement", "[session]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table("person", {
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
|
|
@ -120,7 +121,7 @@ TEST_CASE_METHOD(QueryFixture, " Execute insert statement", "[session]")
|
|||
})
|
||||
.execute();
|
||||
|
||||
auto res = db.insert()
|
||||
auto res = db.query().insert()
|
||||
.into("person", {{"", "id", ""}, {"", "name", ""}, {"", "color", ""}})
|
||||
.values({7, "george", "green"})
|
||||
.execute();
|
||||
|
|
@ -128,7 +129,7 @@ TEST_CASE_METHOD(QueryFixture, " Execute insert statement", "[session]")
|
|||
REQUIRE(res == 1);
|
||||
|
||||
// fetch person as record
|
||||
auto result_record = db.select({"id", "name", "color"})
|
||||
auto result_record = db.query().select({"id", "name", "color"})
|
||||
.from("person")
|
||||
.where("id"_col == 7)
|
||||
.fetch_all();
|
||||
|
|
@ -146,16 +147,16 @@ TEST_CASE_METHOD(QueryFixture, " Execute insert statement", "[session]")
|
|||
REQUIRE(i.at(2).as<std::string>() == "green");
|
||||
}
|
||||
|
||||
db.drop().table("person").execute();
|
||||
db.query().drop().table("person").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key", "[session]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<airplane>("airplane")
|
||||
.execute();
|
||||
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<flight>("flight")
|
||||
.execute();
|
||||
|
||||
|
|
@ -166,35 +167,35 @@ TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key", "[session]"
|
|||
};
|
||||
|
||||
for (const auto &plane: planes) {
|
||||
auto res = db.insert().into<airplane>("airplane").values(*plane).execute();
|
||||
auto res = db.query().insert().into<airplane>("airplane").values(*plane).execute();
|
||||
REQUIRE(res == 1);
|
||||
}
|
||||
|
||||
auto count = db.select({count_all()}).from("airplane").fetch_value<int>();
|
||||
auto count = db.query().select({count_all()}).from("airplane").fetch_value<int>();
|
||||
REQUIRE(count == 3);
|
||||
|
||||
flight f4711{4, planes.at(1), "hans"};
|
||||
|
||||
auto res = db.insert().into<flight>("flight").values(f4711).execute();
|
||||
auto res = db.query().insert().into<flight>("flight").values(f4711).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto f = *db.select<flight>().from("flight").fetch_all<flight>().begin();
|
||||
auto f = *db.query().select<flight>().from("flight").fetch_all<flight>().begin();
|
||||
REQUIRE(f.id == 4);
|
||||
REQUIRE(f.pilot_name == "hans");
|
||||
REQUIRE(f.airplane.get() != nullptr);
|
||||
REQUIRE(f.airplane->id == 2);
|
||||
|
||||
db.drop().table("flight").execute();
|
||||
db.drop().table("airplane").execute();
|
||||
db.query().drop().table("flight").execute();
|
||||
db.query().drop().table("airplane").execute();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key and join", "[session][join]")
|
||||
TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key and join_left", "[session][join_left]")
|
||||
{
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<airplane>("airplane")
|
||||
.execute();
|
||||
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<flight>("flight")
|
||||
.execute();
|
||||
|
||||
|
|
@ -205,11 +206,11 @@ TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key and join", "[
|
|||
};
|
||||
|
||||
for (const auto &plane: planes) {
|
||||
auto res = db.insert().into<airplane>("airplane").values(*plane).execute();
|
||||
auto res = db.query().insert().into<airplane>("airplane").values(*plane).execute();
|
||||
REQUIRE(res == 1);
|
||||
}
|
||||
|
||||
auto count = db.select({count_all()}).from("airplane").fetch_value<int>();
|
||||
auto count = db.query().select({count_all()}).from("airplane").fetch_value<int>();
|
||||
REQUIRE(count == 3);
|
||||
|
||||
std::vector<entity<flight>> flights{
|
||||
|
|
@ -220,20 +221,20 @@ TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key and join", "[
|
|||
};
|
||||
|
||||
for (const auto &f: flights) {
|
||||
auto res = db.insert().into<flight>("flight").values(*f).execute();
|
||||
auto res = db.query().insert().into<flight>("flight").values(*f).execute();
|
||||
REQUIRE(res == 1);
|
||||
}
|
||||
|
||||
auto f = *db.select<flight>().from("flight").fetch_all<flight>().begin();
|
||||
auto f = *db.query().select<flight>().from("flight").fetch_all<flight>().begin();
|
||||
REQUIRE(f.id == 4);
|
||||
REQUIRE(f.pilot_name == "hans");
|
||||
REQUIRE(f.airplane.get() != nullptr);
|
||||
REQUIRE(f.airplane->id == 1);
|
||||
|
||||
auto result = db.select({"f.id", "ap.brand", "ap.model", "f.pilot_name"})
|
||||
auto result = db.query().select({"f.id", "ap.brand", "ap.model", "f.pilot_name"})
|
||||
.from("flight", "f")
|
||||
.join("airplane", "ap")
|
||||
.on("f.airplane_id", "ap.id")
|
||||
.join_left("airplane", "ap")
|
||||
.on("f.airplane_id"_col == "ap.id"_col)
|
||||
.order_by("f.id").asc()
|
||||
.fetch_all();
|
||||
|
||||
|
|
@ -250,7 +251,7 @@ TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key and join", "[
|
|||
REQUIRE(r.at(3).as<std::string>() == expected_result[index++].second);
|
||||
}
|
||||
|
||||
db.drop().table("flight").execute();
|
||||
db.drop().table("airplane").execute();
|
||||
db.query().drop().table("flight").execute();
|
||||
db.query().drop().table("airplane").execute();
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/condition.hpp"
|
||||
#include "matador/sql/connection.hpp"
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ public:
|
|||
: db(matador::test::connection::dns)
|
||||
{
|
||||
db.open();
|
||||
db.create().table<airplane>("airplane").execute();
|
||||
db.query().create().table<airplane>("airplane").execute();
|
||||
}
|
||||
|
||||
~StatementTestFixture()
|
||||
|
|
@ -38,7 +38,7 @@ protected:
|
|||
private:
|
||||
void drop_table_if_exists(const std::string &table_name) {
|
||||
if (db.exists(table_name)) {
|
||||
db.drop().table(table_name).execute();
|
||||
db.query().drop().table(table_name).execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ private:
|
|||
TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement]")
|
||||
{
|
||||
SECTION("Insert with prepared statement and placeholder") {
|
||||
auto stmt = db.insert()
|
||||
auto stmt = db.query().insert()
|
||||
.into<airplane>("airplane")
|
||||
.values<airplane>().prepare();
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement
|
|||
stmt.reset();
|
||||
}
|
||||
|
||||
auto result = db.select<airplane>().from("airplane").fetch_all<airplane>();
|
||||
auto result = db.query().select<airplane>().from("airplane").fetch_all<airplane>();
|
||||
|
||||
size_t index{0};
|
||||
for (const auto &i: result) {
|
||||
|
|
@ -69,11 +69,11 @@ TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement
|
|||
|
||||
SECTION("Select with prepared statement") {
|
||||
for (const auto &plane: planes) {
|
||||
auto res = db.insert().into<airplane>("airplane").values(*plane).execute();
|
||||
auto res = db.query().insert().into<airplane>("airplane").values(*plane).execute();
|
||||
REQUIRE(res == 1);
|
||||
}
|
||||
|
||||
auto stmt = db.select<airplane>().from("airplane").where("brand"_col == _).prepare();
|
||||
auto stmt = db.query().select<airplane>().from("airplane").where("brand"_col == _).prepare();
|
||||
|
||||
stmt.bind(0, "Airbus");
|
||||
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ public:
|
|||
: db(matador::test::connection::dns)
|
||||
{
|
||||
db.open();
|
||||
db.create()
|
||||
db.query().create()
|
||||
.table<location>("location")
|
||||
.execute();
|
||||
}
|
||||
|
||||
~TypeTraitsTestFixture()
|
||||
{
|
||||
db.drop().table("location").execute();
|
||||
db.query().drop().table("location").execute();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -33,7 +33,7 @@ protected:
|
|||
private:
|
||||
void drop_table_if_exists(const std::string &table_name) {
|
||||
if (db.exists(table_name)) {
|
||||
db.drop().table(table_name).execute();
|
||||
db.query().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") {
|
||||
location loc{1, "center", {1, 2, 3}, Color::Black};
|
||||
|
||||
auto res = db.insert().into<location>("location").values(loc).execute();
|
||||
auto res = db.query().insert().into<location>("location").values(loc).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto result = db.select<location>().from("location").fetch_all<location>();
|
||||
auto result = db.query().select<location>().from("location").fetch_all<location>();
|
||||
|
||||
for (const auto &l: result) {
|
||||
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") {
|
||||
location loc{1, "center", {1, 2, 3}, Color::Black};
|
||||
|
||||
auto stmt = db.insert().into<location>("location").values<location>().prepare();
|
||||
auto stmt = db.query().insert().into<location>("location").values<location>().prepare();
|
||||
auto res = stmt.bind(loc).execute();
|
||||
REQUIRE(res == 1);
|
||||
|
||||
auto result = db.select<location>().from("location").
|
||||
auto result = db.query().select<location>().from("location").
|
||||
template fetch_all<location>();
|
||||
|
||||
for (const auto &l: result) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,75 @@
|
|||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/condition.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
#include "matador/sql/connection.hpp"
|
||||
#include "matador/sql/entity.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
struct author
|
||||
{
|
||||
unsigned long id{};
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
std::string date_of_birth;
|
||||
unsigned short year_of_birth{};
|
||||
bool distinguished{false};
|
||||
|
||||
template < typename Operator >
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::utils::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "first_name", first_name, 63);
|
||||
field::attribute(op, "last_name", last_name, 63);
|
||||
field::attribute(op, "date_of_birth", date_of_birth, 31);
|
||||
field::attribute(op, "year_of_birth", year_of_birth);
|
||||
field::attribute(op, "distinguished", distinguished);
|
||||
}
|
||||
};
|
||||
|
||||
struct book
|
||||
{
|
||||
unsigned long id{};
|
||||
matador::sql::entity<author> book_author;
|
||||
std::string title;
|
||||
unsigned short published_in{};
|
||||
|
||||
template < typename Operator >
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::utils::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "title", title, 511);
|
||||
field::attribute(op, "published_in", published_in);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace matador::sql;
|
||||
const std::string env_var{"MATADOR_BACKENDS_PATH"};
|
||||
|
||||
std::string dns;
|
||||
auto s = std::make_shared<schema>();
|
||||
connection c(dns, s);
|
||||
|
||||
auto books = c.query()
|
||||
.select<book>({"author.name"})
|
||||
.from("book")
|
||||
.join_left("author")
|
||||
.on("book.author_id"_col == "author.id"_col)
|
||||
.where("book.published_in"_col < 2008 && "author.name"_col == "Michael Crichton")
|
||||
.order_by("book.title").asc()
|
||||
.fetch_all<book>();
|
||||
|
||||
// SELECT book.title, book.id, book.author_id, book.published_in, author.name
|
||||
// FROM book
|
||||
// INNER JOIN author ON book.author_id = author.id
|
||||
// WHERE book.published_in < 2008 AND author.name = "Michael Crichton"
|
||||
// ORDER BY "book.title" ASC
|
||||
|
||||
|
||||
// char var[1024];
|
||||
// size_t len{};
|
||||
// const auto error = getenv_s(&len, var, 1024, env_var.c_str());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef QUERY_COLUMN_HPP
|
||||
#define QUERY_COLUMN_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class column {
|
||||
public:
|
||||
column(const char *name); // NOLINT(*-explicit-constructor)
|
||||
column(std::string name); // NOLINT(*-explicit-constructor)
|
||||
column(std::string table_name, std::string name, std::string as);
|
||||
|
||||
column& as(std::string a);
|
||||
|
||||
std::string table;
|
||||
std::string name;
|
||||
std::string alias;
|
||||
};
|
||||
|
||||
column operator "" _col(const char *name, size_t len);
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_COLUMN_HPP
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef QUERY_QUERY_HPP
|
||||
#define QUERY_QUERY_HPP
|
||||
|
||||
#include "matador/query/query_parts.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class connection;
|
||||
class query
|
||||
{
|
||||
public:
|
||||
explicit query(connection &c);
|
||||
|
||||
query& select(const std::vector<column> &columns);
|
||||
query& from(const std::string &table, const std::string &as = "");
|
||||
|
||||
private:
|
||||
connection &connection_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_HPP
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef QUERY_QUERY_BUILDER_HPP
|
||||
#define QUERY_QUERY_BUILDER_HPP
|
||||
|
||||
#include "matador/query/column.hpp"
|
||||
#include "matador/query/query_intermediates.hpp"
|
||||
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_builder
|
||||
{
|
||||
public:
|
||||
explicit query_builder(const std::shared_ptr<sql::schema> &scm);
|
||||
query_select_intermediate select(std::initializer_list<column> columns);
|
||||
|
||||
private:
|
||||
std::shared_ptr<sql::schema> schema_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_BUILDER_HPP
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef QUERY_QUERY_COMPILER_HPP
|
||||
#define QUERY_QUERY_COMPILER_HPP
|
||||
|
||||
#include "matador/query/query_part_visitor.hpp"
|
||||
#include "matador/query/query_parts.hpp"
|
||||
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
class dialect;
|
||||
}
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct query_data;
|
||||
|
||||
class query_compiler : public query_part_visitor
|
||||
{
|
||||
public:
|
||||
explicit query_compiler(sql::dialect& d);
|
||||
|
||||
std::string compile(const query_data *data);
|
||||
|
||||
private:
|
||||
void visit(query_select_part &select_part) override;
|
||||
void visit(query_from_part &from_part) override;
|
||||
|
||||
private:
|
||||
sql::dialect &dialect_;
|
||||
std::string sql_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_COMPILER_HPP
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef QUERY_QUERY_DATA_HPP
|
||||
#define QUERY_QUERY_DATA_HPP
|
||||
|
||||
#include "matador/query/query_parts.hpp"
|
||||
#include "matador/query/sql_commands.hpp"
|
||||
#include "matador/query/table.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct query_data
|
||||
{
|
||||
SqlCommands command;
|
||||
std::vector<std::unique_ptr<query_part>> parts;
|
||||
std::vector<column> columns;
|
||||
std::unordered_map<std::type_index, table_data> table_map_by_index;
|
||||
using table_data_ref = std::reference_wrapper<table_data>;
|
||||
std::unordered_map<std::string, table_data_ref> table_map_by_name;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_DATA_HPP
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
#ifndef QUERY_QUERY_INTERMEDIATES_HPP
|
||||
#define QUERY_QUERY_INTERMEDIATES_HPP
|
||||
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
class basic_condition;
|
||||
}
|
||||
namespace matador::query {
|
||||
|
||||
class query_from_intermediate;
|
||||
class query_join_intermediate;
|
||||
class query_on_intermediate;
|
||||
class query_where_intermediate;
|
||||
class query_group_by_intermediate;
|
||||
class query_order_by_intermediate;
|
||||
class query_order_direction_intermediate;
|
||||
class query_offset_intermediate;
|
||||
class query_limit_intermediate;
|
||||
|
||||
class query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit query_intermediate(const std::shared_ptr<sql::schema> &scm);
|
||||
|
||||
protected:
|
||||
sql::schema& schema() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<sql::schema> schema_;
|
||||
};
|
||||
|
||||
class query_select_finish_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
void compile();
|
||||
};
|
||||
|
||||
class query_select_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_from_intermediate from(const std::string &table, const std::string &as = "");
|
||||
};
|
||||
|
||||
class query_from_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_join_intermediate join(const std::string &join_table_name, const std::string &as);
|
||||
query_where_intermediate where(const sql::basic_condition &cond);
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_join_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_on_intermediate on(const std::string &column, const std::string &join_column);
|
||||
};
|
||||
|
||||
class query_on_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_join_intermediate join(const std::string &join_table_name, const std::string &as);
|
||||
query_where_intermediate where(const sql::basic_condition &cond);
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_where_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_group_by_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_order_by_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_order_direction_intermediate asc();
|
||||
query_order_direction_intermediate desc();
|
||||
};
|
||||
|
||||
class query_order_direction_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_offset_intermediate offset(size_t offset);
|
||||
query_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
class query_offset_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
class query_limit_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_INTERMEDIATES_HPP
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef QUERY_QUERY_PART_VISITOR_HPP
|
||||
#define QUERY_QUERY_PART_VISITOR_HPP
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_select_part;
|
||||
class query_from_part;
|
||||
|
||||
class query_part_visitor
|
||||
{
|
||||
public:
|
||||
virtual ~query_part_visitor() = default;
|
||||
|
||||
virtual void visit(query_select_part &select_part) = 0;
|
||||
virtual void visit(query_from_part &from_part) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PART_VISITOR_HPP
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef QUERY_QUERY_PARTS_HPP
|
||||
#define QUERY_QUERY_PARTS_HPP
|
||||
|
||||
#include "matador/query/query_part_visitor.hpp"
|
||||
#include "matador/query/column.hpp"
|
||||
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_part
|
||||
{
|
||||
protected:
|
||||
explicit query_part(sql::dialect::token_t token);
|
||||
|
||||
public:
|
||||
virtual ~query_part() = default;
|
||||
virtual void accept(query_part_visitor &visitor) = 0;
|
||||
|
||||
protected:
|
||||
sql::dialect::token_t token_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL SELECT part
|
||||
*/
|
||||
class query_select_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_select_part(std::vector<column> columns);
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::vector<column> columns_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL FROM part
|
||||
*/
|
||||
class query_from_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_from_part(std::string table_name);
|
||||
query_from_part(std::string table_name, std::string as);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::string table_;
|
||||
std::string alias_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PARTS_HPP
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef QUERY_SQL_COMMANDS_HPP
|
||||
#define QUERY_SQL_COMMANDS_HPP
|
||||
|
||||
#include "matador/utils/enum_mapper.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
enum class SqlCommands
|
||||
{
|
||||
UNKNOWN, /**< Unknown query command */
|
||||
CREATE, /**< Create query command */
|
||||
DROP, /**< Drop query command */
|
||||
SELECT, /**< Select query command */
|
||||
INSERT, /**< Insert query command */
|
||||
UPDATE, /**< Update query command */
|
||||
REMOVE /**< Remove query command */
|
||||
};
|
||||
|
||||
static const utils::enum_mapper<SqlCommands> sql_command_enum({
|
||||
{SqlCommands::UNKNOWN, "unknown"},
|
||||
{SqlCommands::CREATE, "create"},
|
||||
{SqlCommands::DROP, "drop"},
|
||||
{SqlCommands::SELECT, "select"},
|
||||
{SqlCommands::INSERT, "insert"},
|
||||
{SqlCommands::UPDATE, "update"},
|
||||
{SqlCommands::REMOVE, "delete"}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_SQL_COMMANDS_HPP
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef QUERY_TABLE_HPP
|
||||
#define QUERY_TABLE_HPP
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct table_data
|
||||
{
|
||||
std::type_index index;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_TABLE_HPP
|
||||
|
|
@ -1,174 +1,45 @@
|
|||
#ifndef QUERY_COLUMN_HPP
|
||||
#define QUERY_COLUMN_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
enum class null_option : uint8_t {
|
||||
NULLABLE, NOT_NULL
|
||||
enum class sql_function_t {
|
||||
NONE,
|
||||
COUNT,
|
||||
AVG,
|
||||
SUM,
|
||||
MIN,
|
||||
MAX
|
||||
};
|
||||
|
||||
class column {
|
||||
public:
|
||||
column(sql_function_t func, std::string name);
|
||||
column(const char *name, std::string alias = ""); // NOLINT(*-explicit-constructor)
|
||||
column(std::string name, std::string alias = ""); // NOLINT(*-explicit-constructor)
|
||||
|
||||
column(const column&) = default;
|
||||
column& operator=(const column&) = default;
|
||||
column(column&&) noexcept = default;
|
||||
column& operator=(column&&) noexcept = default;
|
||||
|
||||
template<typename Type>
|
||||
explicit column(std::string name, utils::field_attributes attr)
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr)
|
||||
{}
|
||||
|
||||
template<typename Type>
|
||||
column(std::string name, const Type &, utils::field_attributes attr, null_option null_opt)
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr, null_opt)
|
||||
{}
|
||||
|
||||
column(std::string name, data_type_t type, utils::field_attributes attr, null_option null_opt, size_t index = 0);
|
||||
|
||||
template<typename Type>
|
||||
column(std::string name, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt)
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), ref_table, ref_column, attr, null_opt)
|
||||
{}
|
||||
|
||||
column(std::string name, data_type_t type, size_t index, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] size_t index() const;
|
||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||
[[nodiscard]] bool is_nullable() const;
|
||||
[[nodiscard]] data_type_t type() const;
|
||||
[[nodiscard]] const std::string& alias() const;
|
||||
[[nodiscard]] const std::string& ref_table() const;
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
void type(data_type_t type);
|
||||
void alias(const std::string &as);
|
||||
|
||||
template< typename Type >
|
||||
[[nodiscard]] bool is_type_of() const {
|
||||
return std::holds_alternative<Type>(value_);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string str() const;
|
||||
|
||||
template<typename Type>
|
||||
void set(const Type &value, const utils::field_attributes &attr = utils::null_attributes)
|
||||
struct column
|
||||
{
|
||||
type_ = data_type_traits<Type>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
column(const char *name) : name(name) {} // NOLINT(*-explicit-constructor)
|
||||
column(std::string name) : name(std::move(name)) {} // NOLINT(*-explicit-constructor)
|
||||
column(sql_function_t func, std::string name) : name(std::move(name)), function_(func) {} // NOLINT(*-explicit-constructor)
|
||||
column(std::string table_name, std::string name, std::string as)
|
||||
: table(std::move(table_name))
|
||||
, name(std::move(name))
|
||||
, alias(std::move(as)) {} // NOLINT(*-explicit-constructor)
|
||||
|
||||
column& as(std::string a) {
|
||||
alias = std::move(a);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void set(const std::string &value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
[[nodiscard]] bool is_function() const {
|
||||
return function_ != sql_function_t::NONE;
|
||||
}
|
||||
|
||||
void set(const char *value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
Type as() const
|
||||
{
|
||||
const Type* ptr= std::get_if<Type>(&value_);
|
||||
if (ptr) {
|
||||
return *ptr;
|
||||
}
|
||||
any_type_to_visitor<Type> visitor;
|
||||
std::visit(visitor, const_cast<any_type&>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_function() const;
|
||||
[[nodiscard]] sql_function_t function() const;
|
||||
|
||||
private:
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
op.on_attribute(name_.c_str(), value_, type_, attributes_);
|
||||
}
|
||||
|
||||
using data_type_index = std::vector<data_type_t>;
|
||||
|
||||
private:
|
||||
friend class record;
|
||||
|
||||
static const data_type_index data_type_index_;
|
||||
|
||||
std::string name_;
|
||||
size_t index_{};
|
||||
utils::field_attributes attributes_;
|
||||
null_option null_option_{null_option::NOT_NULL};
|
||||
data_type_t type_{data_type_t::type_unknown};
|
||||
any_type value_;
|
||||
std::string table;
|
||||
std::string name;
|
||||
std::string alias;
|
||||
sql_function_t function_{sql_function_t::NONE};
|
||||
std::string alias_;
|
||||
std::string ref_table_;
|
||||
std::string ref_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
* User defined literal to have a shortcut creating a column object
|
||||
* @param name Name of the column
|
||||
* @param len Length of the column name
|
||||
* @return A column object with given name
|
||||
*/
|
||||
column operator "" _col(const char *name, size_t len);
|
||||
|
||||
column make_column(const std::string &name, data_type_t type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL);
|
||||
|
||||
template < typename Type >
|
||||
column make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL)
|
||||
{
|
||||
return make_column(name, data_type_traits<Type>::builtin_type(0), attr, null_opt);
|
||||
}
|
||||
template <>
|
||||
column make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
template < typename Type >
|
||||
column make_pk_column(const std::string &name, size_t size = 0)
|
||||
{
|
||||
return make_column<Type>(name, { size, utils::constraints::PRIMARY_KEY });
|
||||
}
|
||||
|
||||
template <>
|
||||
column make_pk_column<std::string>(const std::string &name, size_t size);
|
||||
|
||||
template < typename Type >
|
||||
column make_fk_column(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(size), ref_table, ref_column, { size, utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
template < typename Type >
|
||||
[[maybe_unused]] column make_fk_column(const std::string &name, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(0), 0, ref_table, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
}
|
||||
|
||||
template <>
|
||||
column make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column);
|
||||
|
||||
}
|
||||
#endif //QUERY_COLUMN_HPP
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
#ifndef QUERY_COLUMN_DEFINITION_HPP
|
||||
#define QUERY_COLUMN_DEFINITION_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
enum class null_option : uint8_t {
|
||||
NULLABLE, NOT_NULL
|
||||
};
|
||||
|
||||
class column_definition {
|
||||
public:
|
||||
explicit column_definition(const char *name); // NOLINT(*-explicit-constructor)
|
||||
explicit column_definition(std::string name); // NOLINT(*-explicit-constructor)
|
||||
|
||||
column_definition(const column_definition&) = default;
|
||||
column_definition& operator=(const column_definition&) = default;
|
||||
column_definition(column_definition&&) noexcept = default;
|
||||
column_definition& operator=(column_definition&&) noexcept = default;
|
||||
|
||||
template<typename Type>
|
||||
explicit column_definition(std::string name, utils::field_attributes attr)
|
||||
: column_definition(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr)
|
||||
{}
|
||||
|
||||
template<typename Type>
|
||||
column_definition(std::string name, const Type &, utils::field_attributes attr, null_option null_opt)
|
||||
: column_definition(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr, null_opt)
|
||||
{}
|
||||
|
||||
column_definition(std::string name, data_type_t type, utils::field_attributes attr, null_option null_opt, size_t index = 0);
|
||||
|
||||
template<typename Type>
|
||||
column_definition(std::string name, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt)
|
||||
: column_definition(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), ref_table, ref_column, attr, null_opt)
|
||||
{}
|
||||
|
||||
column_definition(std::string name, data_type_t type, size_t index, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] size_t index() const;
|
||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||
[[nodiscard]] bool is_nullable() const;
|
||||
[[nodiscard]] data_type_t type() const;
|
||||
[[nodiscard]] const std::string& ref_table() const;
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
void type(data_type_t type);
|
||||
|
||||
template< typename Type >
|
||||
[[nodiscard]] bool is_type_of() const {
|
||||
return std::holds_alternative<Type>(value_);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string str() const;
|
||||
|
||||
template<typename Type>
|
||||
void set(const Type &value, const utils::field_attributes &attr = utils::null_attributes)
|
||||
{
|
||||
type_ = data_type_traits<Type>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
void set(const std::string &value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
void set(const char *value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
Type as() const
|
||||
{
|
||||
const Type* ptr= std::get_if<Type>(&value_);
|
||||
if (ptr) {
|
||||
return *ptr;
|
||||
}
|
||||
any_type_to_visitor<Type> visitor;
|
||||
std::visit(visitor, const_cast<any_type&>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
private:
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
op.on_attribute(name_.c_str(), value_, type_, attributes_);
|
||||
}
|
||||
|
||||
using data_type_index = std::vector<data_type_t>;
|
||||
|
||||
private:
|
||||
friend class record;
|
||||
|
||||
static const data_type_index data_type_index_;
|
||||
|
||||
std::string name_;
|
||||
size_t index_{};
|
||||
utils::field_attributes attributes_;
|
||||
null_option null_option_{null_option::NOT_NULL};
|
||||
data_type_t type_{data_type_t::type_unknown};
|
||||
any_type value_;
|
||||
std::string ref_table_;
|
||||
std::string ref_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
* User defined literal to have a shortcut creating a column object
|
||||
* @param name Name of the column
|
||||
* @param len Length of the column name
|
||||
* @return A column object with given name
|
||||
*/
|
||||
column_definition make_column(const std::string &name, data_type_t type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL);
|
||||
|
||||
template < typename Type >
|
||||
column_definition make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL)
|
||||
{
|
||||
return make_column(name, data_type_traits<Type>::builtin_type(0), attr, null_opt);
|
||||
}
|
||||
template <>
|
||||
column_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
template < typename Type >
|
||||
column_definition make_pk_column(const std::string &name, size_t size = 0)
|
||||
{
|
||||
return make_column<Type>(name, { size, utils::constraints::PRIMARY_KEY });
|
||||
}
|
||||
|
||||
template <>
|
||||
column_definition make_pk_column<std::string>(const std::string &name, size_t size);
|
||||
|
||||
template < typename Type >
|
||||
column_definition make_fk_column(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(size), ref_table, ref_column, { size, utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
template < typename Type >
|
||||
[[maybe_unused]] column_definition make_fk_column(const std::string &name, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(0), 0, ref_table, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
}
|
||||
|
||||
template <>
|
||||
column_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column);
|
||||
|
||||
}
|
||||
#endif //QUERY_COLUMN_DEFINITION_HPP
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef QUERY_COLUMN_GENERATOR_HPP
|
||||
#define QUERY_COLUMN_GENERATOR_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
|
@ -21,10 +21,10 @@ public:
|
|||
fk_column_generator() = default;
|
||||
|
||||
template<class Type>
|
||||
column generate(const char *id, Type &x, const std::string &ref_table, const std::string &ref_column)
|
||||
column_definition generate(const char *id, Type &x, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
utils::access::process(*this, x);
|
||||
return column{id, type_, 0, ref_table, ref_column, { utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
return column_definition{id, type_, 0, ref_table, ref_column, {utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
|
|
@ -53,15 +53,15 @@ private:
|
|||
class column_generator
|
||||
{
|
||||
private:
|
||||
column_generator(std::vector<column> &columns, const schema &repo);
|
||||
column_generator(std::vector<column_definition> &columns, const schema &repo);
|
||||
|
||||
public:
|
||||
~column_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<column> generate(const schema &repo)
|
||||
static std::vector<column_definition> generate(const schema &repo)
|
||||
{
|
||||
std::vector<column> columns;
|
||||
std::vector<column_definition> columns;
|
||||
column_generator gen(columns, repo);
|
||||
Type obj;
|
||||
matador::utils::access::process(gen, obj);
|
||||
|
|
@ -101,7 +101,7 @@ private:
|
|||
|
||||
private:
|
||||
size_t index_ = 0;
|
||||
std::vector<column> &columns_;
|
||||
std::vector<column_definition> &columns_;
|
||||
const schema &repo_;
|
||||
|
||||
fk_column_generator fk_column_generator_;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/foreign_attributes.hpp"
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <string>
|
||||
|
|
@ -13,29 +14,22 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
struct column_info
|
||||
{
|
||||
std::string table;
|
||||
std::string name;
|
||||
std::string alias;
|
||||
};
|
||||
|
||||
class column_name_generator
|
||||
{
|
||||
private:
|
||||
column_name_generator(std::vector<column_info> &column_infos, const sql::schema &ts, const std::string &table_name);
|
||||
column_name_generator(std::vector<column> &column_infos, const sql::schema &ts, const std::string &table_name);
|
||||
|
||||
public:
|
||||
~column_name_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<column_info> generate(const sql::schema &ts)
|
||||
static std::vector<column> generate(const sql::schema &ts)
|
||||
{
|
||||
const auto info = ts.info<Type>();
|
||||
if (!info) {
|
||||
return {};
|
||||
}
|
||||
std::vector<column_info> columns;
|
||||
std::vector<column> columns;
|
||||
column_name_generator gen(columns, ts, info.value().name);
|
||||
Type obj;
|
||||
matador::utils::access::process(gen, obj);
|
||||
|
|
@ -93,7 +87,7 @@ private:
|
|||
|
||||
private:
|
||||
std::stack<std::string> table_name_stack_;
|
||||
std::vector<column_info> &column_infos_;
|
||||
std::vector<column> &column_infos_;
|
||||
const sql::schema &table_schema_;
|
||||
int column_index{0};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "matador/sql/query_context.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
|
|
@ -55,8 +56,8 @@ public:
|
|||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
return d.prepare_identifier(field_.name()) + " " + operand + " " + std::to_string(value);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_.name) + " " + operand + " " + std::to_string(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -75,8 +76,8 @@ public:
|
|||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
return d.prepare_identifier(field_.name()) + " " + operand + " '" + value + "'";
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_.name) + " " + operand + " '" + value + "'";
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ public:
|
|||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
return std::to_string(value) + " " + operand + " " + d.prepare_identifier(field_.name());
|
||||
return std::to_string(value) + " " + operand + " " + d.prepare_identifier(field_.name);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -115,7 +116,7 @@ public:
|
|||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
return "'" + std::to_string(value) + "' " + operand + " " + d.prepare_identifier(field_.name());
|
||||
return "'" + std::to_string(value) + "' " + operand + " " + d.prepare_identifier(field_.name);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -158,10 +159,10 @@ public:
|
|||
std::string evaluate(dialect &d, query_context &query) const override {
|
||||
auto count = size();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
}
|
||||
|
||||
std::string result = d.prepare_identifier(field_.name()) + " IN (";
|
||||
std::string result = d.prepare_identifier(field_.name) + " IN (";
|
||||
if (args_.size() < 2) {
|
||||
for (const auto &val : args_) {
|
||||
result.append(std::to_string(val));
|
||||
|
|
@ -261,9 +262,9 @@ public:
|
|||
* @return A condition BETWEEN part of the query
|
||||
*/
|
||||
std::string evaluate(dialect &d, query_context &query) const override {
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
return d.prepare_identifier(field_.name()) + " BETWEEN " + std::to_string(range_.first) + " AND " + std::to_string(range_.second);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_.name) + " BETWEEN " + std::to_string(range_.first) + " AND " + std::to_string(range_.second);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -355,6 +356,28 @@ private:
|
|||
std::string operand;
|
||||
};
|
||||
|
||||
template<>
|
||||
class condition<column, column> : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(const column &a, basic_condition::operand_t op, column b)
|
||||
: basic_column_condition(a, op)
|
||||
, other_column_(std::move(b)) {}
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @return The evaluated string based on the compile type
|
||||
*/
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
return d.prepare_identifier(field_.name) + " " + operand + " " + d.prepare_identifier(other_column_.name);
|
||||
}
|
||||
|
||||
private:
|
||||
column other_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @file condition.hpp
|
||||
* @brief Contains functions to create query conditions
|
||||
|
|
@ -441,6 +464,8 @@ condition<column, T> operator==(const column &col, T val)
|
|||
return condition<column, T>(col, basic_condition::operand_t::EQUAL, val);
|
||||
}
|
||||
|
||||
condition<column, column> operator==(const column &a, const column &b);
|
||||
|
||||
/**
|
||||
* @brief Condition equality method for a column and a query
|
||||
*
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@
|
|||
#include "matador/sql/connection_info.hpp"
|
||||
#include "matador/sql/connection_impl.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/query_intermediates.hpp"
|
||||
#include "matador/sql/query.hpp"
|
||||
#include "matador/sql/query_context.hpp"
|
||||
#include "matador/sql/query_result.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/statement.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include "matador/utils/logger.hpp"
|
||||
|
||||
|
|
@ -19,8 +20,8 @@ namespace matador::sql {
|
|||
class connection
|
||||
{
|
||||
public:
|
||||
explicit connection(connection_info info, const std::shared_ptr<schema> &repo = std::make_shared<schema>());
|
||||
explicit connection(const std::string& dns, const std::shared_ptr<schema> &repo = std::make_shared<schema>());
|
||||
explicit connection(connection_info info, const std::shared_ptr<schema> &repo = std::make_shared<sql::schema>());
|
||||
explicit connection(const std::string& dns, const std::shared_ptr<schema> &repo = std::make_shared<sql::schema>());
|
||||
connection(const connection &x);
|
||||
connection& operator=(const connection &x);
|
||||
connection(connection &&x) noexcept = default;
|
||||
|
|
@ -31,19 +32,12 @@ public:
|
|||
[[nodiscard]] bool is_open() 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]] bool exists(const std::string &schema_name, const std::string &table_name) const;
|
||||
[[nodiscard]] bool exists(const std::string &table_name) const;
|
||||
|
||||
sql::query query() const;
|
||||
|
||||
query_result<record> fetch(const query_context &q) const;
|
||||
[[nodiscard]] std::unique_ptr<query_result_impl> fetch(const std::string &sql) const;
|
||||
[[nodiscard]] size_t execute(const std::string &sql) const;
|
||||
|
|
@ -51,21 +45,15 @@ public:
|
|||
statement prepare(query_context &&query) const;
|
||||
|
||||
const class dialect& dialect() const;
|
||||
std::shared_ptr<schema> tables() const;
|
||||
std::shared_ptr<sql::schema> schema() const;
|
||||
|
||||
private:
|
||||
connection_info connection_info_;
|
||||
std::unique_ptr<connection_impl> connection_;
|
||||
utils::logger logger_;
|
||||
const class dialect &dialect_;
|
||||
std::shared_ptr<schema> schema_;
|
||||
std::shared_ptr<sql::schema> schema_;
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
query_select_intermediate connection::select()
|
||||
{
|
||||
return query_select_intermediate{*this, column_generator::generate<Type>(*schema_)};
|
||||
}
|
||||
|
||||
}
|
||||
#endif //QUERY_CONNECTION_HPP
|
||||
|
|
|
|||
|
|
@ -41,16 +41,6 @@ enum class data_type_t : uint8_t {
|
|||
type_unknown /*!< Data type unknown */
|
||||
};
|
||||
|
||||
enum class sql_function_t {
|
||||
NONE,
|
||||
COUNT,
|
||||
AVG,
|
||||
SUM,
|
||||
MIN,
|
||||
MAX
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @tparam T The type of the traits
|
||||
* @brief Type traits for database types
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef QUERY_DIALECT_HPP
|
||||
#define QUERY_DIALECT_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
|
@ -11,8 +12,6 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
class column;
|
||||
|
||||
class dialect final
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef QUERY_QUERY_HPP
|
||||
#define QUERY_QUERY_HPP
|
||||
|
||||
#include "matador/sql/query_intermediates.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class connection;
|
||||
|
||||
class query
|
||||
{
|
||||
public:
|
||||
explicit query(connection &c);
|
||||
query(const query &) = delete;
|
||||
query& operator=(const query &) = delete;
|
||||
|
||||
query_create_intermediate create();
|
||||
query_drop_intermediate drop();
|
||||
template < class Type >
|
||||
query_select_intermediate select();
|
||||
template < class Type >
|
||||
query_select_intermediate select(std::initializer_list<column> columns);
|
||||
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();
|
||||
|
||||
private:
|
||||
[[nodiscard]] const sql::schema& schema() const;
|
||||
|
||||
private:
|
||||
connection &connection_;
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
query_select_intermediate query::select()
|
||||
{
|
||||
return query_select_intermediate{connection_, column_name_generator::generate<Type>(this->schema())};
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
query_select_intermediate query::select(std::initializer_list<column> columns)
|
||||
{
|
||||
return query_select_intermediate{connection_, column_name_generator::generate<Type>(this->schema())};
|
||||
}
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_HPP
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#define QUERY_QUERY_BUILDER_HPP
|
||||
|
||||
#include "matador/sql/basic_condition.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/key_value_pair.hpp"
|
||||
|
|
@ -123,11 +124,11 @@ public:
|
|||
query_builder& update(const std::string &table);
|
||||
query_builder& remove();
|
||||
|
||||
query_builder& table(const std::string &table, std::initializer_list<column> columns);
|
||||
query_builder& table(const std::string &table, const std::vector<column> &columns);
|
||||
query_builder& table(const std::string &table, std::initializer_list<column_definition> columns);
|
||||
query_builder& table(const std::string &table, const std::vector<column_definition> &columns);
|
||||
query_builder& table(const std::string &table);
|
||||
query_builder& into(const std::string &table, std::initializer_list<column_info> column_names);
|
||||
query_builder& into(const std::string &table, const std::vector<column_info> &column_names);
|
||||
query_builder& into(const std::string &table, std::initializer_list<column> column_names);
|
||||
query_builder& into(const std::string &table, const std::vector<column> &column_names);
|
||||
query_builder& values(std::initializer_list<any_type> values);
|
||||
query_builder& values(const std::vector<any_type> &values);
|
||||
query_builder& from(const std::string &table, const std::string &as = "");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef QUERY_QUERY_COMPILER_HPP
|
||||
#define QUERY_QUERY_COMPILER_HPP
|
||||
|
||||
#include "matador/sql/query_part_visitor.hpp"
|
||||
#include "matador/sql/query_parts.hpp"
|
||||
#include "matador/sql/query_context.hpp"
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class dialect;
|
||||
|
||||
struct query_data;
|
||||
|
||||
class query_compiler : public query_part_visitor
|
||||
{
|
||||
public:
|
||||
explicit query_compiler(const sql::dialect& d);
|
||||
|
||||
query_context compile(const query_data *data);
|
||||
|
||||
private:
|
||||
void visit(query_select_part &select_part) override;
|
||||
void visit(query_from_part &from_part) override;
|
||||
void visit(query_where_part &where_part) override;
|
||||
void visit(query_group_by_part &group_by_part) override;
|
||||
void visit(query_order_by_part &order_by_part) override;
|
||||
void visit(query_order_by_asc_part &order_by_asc_part) override;
|
||||
void visit(query_order_by_desc_part &order_by_desc_part) override;
|
||||
|
||||
void visit(query_insert_part &insert_part) override;
|
||||
void visit(query_values_part &values_part) override;
|
||||
|
||||
void visit(query_update_part &update_part) override;
|
||||
|
||||
void visit(query_delete_part &delete_part) override;
|
||||
|
||||
void visit(query_create_part &create_part) override;
|
||||
|
||||
void visit(query_drop_part &drop_part) override;
|
||||
|
||||
private:
|
||||
const sql::dialect &dialect_;
|
||||
query_context query_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_COMPILER_HPP
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef QUERY_QUERY_DATA_HPP
|
||||
#define QUERY_QUERY_DATA_HPP
|
||||
|
||||
#include "matador/sql/query_parts.hpp"
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
struct query_data
|
||||
{
|
||||
// SqlCommands command;
|
||||
std::vector<std::unique_ptr<query_part>> parts;
|
||||
std::vector<column_definition> columns;
|
||||
std::unordered_map<std::type_index, table> table_map_by_index;
|
||||
using table_ref = std::reference_wrapper<table>;
|
||||
std::unordered_map<std::string, table_ref> table_map_by_name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_DATA_HPP
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#ifndef QUERY_QUERY_INTERMEDIATES_HPP
|
||||
#define QUERY_QUERY_INTERMEDIATES_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/column_name_generator.hpp"
|
||||
#include "matador/sql/key_value_generator.hpp"
|
||||
#include "matador/sql/key_value_pair.hpp"
|
||||
#include "matador/sql/placeholder_generator.hpp"
|
||||
#include "matador/sql/query_builder.hpp"
|
||||
#include "matador/sql/query_result.hpp"
|
||||
#include "matador/sql/query_data.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/statement.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
|
@ -36,10 +36,10 @@ protected:
|
|||
class query_intermediate : public basic_query_intermediate
|
||||
{
|
||||
public:
|
||||
query_intermediate(connection &db, query_builder &query);
|
||||
query_intermediate(connection &db, query_data &data);
|
||||
|
||||
protected:
|
||||
query_builder &builder_;
|
||||
query_data &data_;
|
||||
};
|
||||
|
||||
class query_execute_finish : public query_intermediate
|
||||
|
|
@ -146,7 +146,7 @@ class query_join_intermediate : public query_intermediate
|
|||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_on_intermediate on(const std::string &column, const std::string &join_column);
|
||||
query_on_intermediate on(const basic_condition &cond);
|
||||
};
|
||||
|
||||
class query_from_intermediate : public query_select_finish
|
||||
|
|
@ -154,7 +154,7 @@ class query_from_intermediate : public query_select_finish
|
|||
public:
|
||||
using query_select_finish::query_select_finish;
|
||||
|
||||
query_join_intermediate join(const std::string &join_table_name, const std::string &as);
|
||||
query_join_intermediate join_left(const std::string &join_table_name, const std::string &as = "");
|
||||
query_where_intermediate where(const basic_condition &cond);
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
|
|
@ -163,10 +163,10 @@ public:
|
|||
class query_start_intermediate : public basic_query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit query_start_intermediate(connection &s);
|
||||
explicit query_start_intermediate(connection &db);
|
||||
|
||||
protected:
|
||||
query_builder builder_;
|
||||
query_data data_;
|
||||
};
|
||||
|
||||
class query_select_intermediate : public query_start_intermediate
|
||||
|
|
@ -192,16 +192,19 @@ public:
|
|||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_execute_finish values(std::initializer_list<any_type> values);
|
||||
query_execute_finish values(const std::vector<any_type>& values);
|
||||
template<class Type>
|
||||
query_execute_finish values()
|
||||
{
|
||||
Type obj;
|
||||
return {connection_, builder_.values(as_placeholder(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.values(as_placeholder(obj))};
|
||||
}
|
||||
template<class Type>
|
||||
query_execute_finish values(const Type &obj)
|
||||
{
|
||||
return {connection_, builder_.values(value_extractor::extract(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.values(value_extractor::extract(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -210,15 +213,16 @@ class query_create_intermediate : public query_start_intermediate
|
|||
public:
|
||||
explicit query_create_intermediate(connection &db);
|
||||
|
||||
query_execute_finish table(const std::string &table_name, std::initializer_list<column> columns);
|
||||
query_execute_finish table(const std::string &table_name, const std::vector<column> &columns);
|
||||
query_execute_finish table(const std::string &table_name, std::initializer_list<column_definition> columns);
|
||||
query_execute_finish table(const std::string &table_name, const std::vector<column_definition> &columns);
|
||||
template<class Type>
|
||||
query_execute_finish table(const std::string &table_name)
|
||||
{
|
||||
if (!tables()->exists<Type>()) {
|
||||
tables()->attach<Type>(table_name);
|
||||
}
|
||||
return {connection_, builder_.table(table_name, column_generator::generate<Type>(*tables()))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.table(table_name, column_generator::generate<Type>(*tables()))};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -235,17 +239,19 @@ class query_insert_intermediate : public query_start_intermediate
|
|||
public:
|
||||
explicit query_insert_intermediate(connection &s);
|
||||
|
||||
query_into_intermediate into(const std::string &table, std::initializer_list<column_info> column_names);
|
||||
query_into_intermediate into(const std::string &table, std::initializer_list<column> column_names);
|
||||
template<class Type>
|
||||
query_into_intermediate into(const std::string &table)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))};
|
||||
}
|
||||
template<class Type>
|
||||
query_execute_finish into(const std::string &table, const Type &obj)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))
|
||||
.values(value_extractor::extract(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))
|
||||
// .values(value_extractor::extract(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -274,7 +280,8 @@ public:
|
|||
template<class Type>
|
||||
query_set_intermediate set(const Type &obj)
|
||||
{
|
||||
return {connection_, builder_.set(key_value_generator::generate(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.set(key_value_generator::generate(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef QUERY_QUERY_PART_VISITOR_HPP
|
||||
#define QUERY_QUERY_PART_VISITOR_HPP
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class query_select_part;
|
||||
class query_from_part;
|
||||
class query_where_part;
|
||||
class query_group_by_part;
|
||||
class query_order_by_part;
|
||||
class query_order_by_asc_part;
|
||||
class query_order_by_desc_part;
|
||||
class query_insert_part;
|
||||
class query_values_part;
|
||||
class query_update_part;
|
||||
class query_delete_part;
|
||||
class query_create_part;
|
||||
class query_drop_part;
|
||||
|
||||
class query_part_visitor
|
||||
{
|
||||
public:
|
||||
virtual ~query_part_visitor() = default;
|
||||
|
||||
virtual void visit(query_select_part &select_part) = 0;
|
||||
virtual void visit(query_from_part &from_part) = 0;
|
||||
virtual void visit(query_where_part &where_part) = 0;
|
||||
virtual void visit(query_group_by_part &group_by_part) = 0;
|
||||
virtual void visit(query_order_by_part &order_by_part) = 0;
|
||||
virtual void visit(query_order_by_asc_part &order_by_asc_part) = 0;
|
||||
virtual void visit(query_order_by_desc_part &order_by_desc_part) = 0;
|
||||
|
||||
virtual void visit(query_insert_part &insert_part) = 0;
|
||||
virtual void visit(query_values_part &values_part) = 0;
|
||||
|
||||
virtual void visit(query_update_part &update_part) = 0;
|
||||
|
||||
virtual void visit(query_delete_part &delete_part) = 0;
|
||||
|
||||
virtual void visit(query_create_part &create_part) = 0;
|
||||
virtual void visit(query_drop_part &drop_part) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_PART_VISITOR_HPP
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
#ifndef QUERY_QUERY_PARTS_HPP
|
||||
#define QUERY_QUERY_PARTS_HPP
|
||||
|
||||
#include "matador/sql/query_part_visitor.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class basic_condition;
|
||||
|
||||
class query_part
|
||||
{
|
||||
protected:
|
||||
explicit query_part(sql::dialect::token_t token);
|
||||
|
||||
public:
|
||||
virtual ~query_part() = default;
|
||||
virtual void accept(query_part_visitor &visitor) = 0;
|
||||
|
||||
protected:
|
||||
sql::dialect::token_t token_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL SELECT part
|
||||
*/
|
||||
class query_select_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_select_part(std::vector<column> columns);
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
[[nodiscard]] const std::vector<column>& columns() const;
|
||||
|
||||
private:
|
||||
std::vector<column> columns_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL FROM part
|
||||
*/
|
||||
class query_from_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_from_part(std::string table_name);
|
||||
query_from_part(std::string table_name, std::string as);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::string table_;
|
||||
std::string alias_;
|
||||
};
|
||||
|
||||
class query_where_part : public query_part
|
||||
{
|
||||
public:
|
||||
template < class Condition >
|
||||
explicit query_where_part(const Condition &cond)
|
||||
: query_part(dialect::token_t::WHERE)
|
||||
, condition_(new Condition(cond)) {}
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<basic_condition> condition_;
|
||||
};
|
||||
|
||||
class query_table_name_part : public query_part
|
||||
{
|
||||
protected:
|
||||
explicit query_table_name_part(sql::dialect::token_t token, std::string table_name);
|
||||
|
||||
protected:
|
||||
std::string table_name_;
|
||||
};
|
||||
|
||||
class query_group_by_part : public query_table_name_part
|
||||
{
|
||||
public:
|
||||
explicit query_group_by_part(const std::string &table_name);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_order_by_part : public query_table_name_part
|
||||
{
|
||||
public:
|
||||
explicit query_order_by_part(const std::string &table_name);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_order_by_asc_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_order_by_asc_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_order_by_desc_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_order_by_desc_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_insert_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_insert_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL VALUES part
|
||||
*/
|
||||
class query_values_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_values_part(std::initializer_list<any_type> values);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::vector<any_type> values_;
|
||||
};
|
||||
|
||||
class query_update_part : public query_table_name_part
|
||||
{
|
||||
public:
|
||||
explicit query_update_part(const std::string &table_name);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_delete_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_delete_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_create_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_create_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_drop_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_drop_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PARTS_HPP
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
|
@ -13,8 +13,8 @@ namespace matador::sql {
|
|||
class record
|
||||
{
|
||||
private:
|
||||
using column_by_index = std::vector<column>;
|
||||
using column_index_pair = std::pair<std::reference_wrapper<column>, size_t>;
|
||||
using column_by_index = std::vector<column_definition>;
|
||||
using column_index_pair = std::pair<std::reference_wrapper<column_definition>, size_t>;
|
||||
using column_by_name_map = std::unordered_map<std::string, column_index_pair>;
|
||||
|
||||
public:
|
||||
|
|
@ -22,8 +22,8 @@ public:
|
|||
using const_iterator = column_by_index::const_iterator;
|
||||
|
||||
record() = default;
|
||||
record(std::initializer_list<column> columns);
|
||||
explicit record(const std::vector<column> &columns);
|
||||
record(std::initializer_list<column_definition> columns);
|
||||
explicit record(const std::vector<column_definition> &columns);
|
||||
record(const record &x);
|
||||
record& operator=(const record &x);
|
||||
record(record&&) noexcept = default;
|
||||
|
|
@ -43,15 +43,15 @@ public:
|
|||
append(make_column<Type>(name, size));
|
||||
}
|
||||
|
||||
void append(column col);
|
||||
void append(column_definition col);
|
||||
|
||||
[[nodiscard]] bool has_primary_key() const;
|
||||
[[nodiscard]] const column& primary_key() const;
|
||||
[[nodiscard]] const column_definition& primary_key() const;
|
||||
|
||||
[[nodiscard]] const std::vector<column>& columns() const;
|
||||
[[nodiscard]] const std::vector<column_definition>& columns() const;
|
||||
|
||||
[[nodiscard]] const column& at(const std::string &name) const;
|
||||
[[nodiscard]] const column& at(size_t index) const;
|
||||
[[nodiscard]] const column_definition& at(const std::string &name) const;
|
||||
[[nodiscard]] const column_definition& at(size_t index) const;
|
||||
|
||||
iterator find(const std::string &column_name);
|
||||
[[nodiscard]] const_iterator find(const std::string &column_name) const;
|
||||
|
|
@ -72,7 +72,7 @@ public:
|
|||
|
||||
private:
|
||||
void init();
|
||||
void add_to_map(column &col, size_t index);
|
||||
void add_to_map(column_definition &col, size_t index);
|
||||
|
||||
private:
|
||||
column_by_index columns_;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ public:
|
|||
using iterator = repository::iterator;
|
||||
using const_iterator = repository::const_iterator;
|
||||
|
||||
std::string name() const;
|
||||
|
||||
template<typename Type>
|
||||
const table_info& attach(const std::string &table_name)
|
||||
{
|
||||
|
|
@ -68,6 +70,7 @@ public:
|
|||
[[nodiscard]] bool empty() const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
repository repository_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ entity<Type> session::insert(Type *obj)
|
|||
if (!info) {
|
||||
return {};
|
||||
}
|
||||
c->insert().into<Type>(info->name).values(*obj).execute();
|
||||
c->query().insert().into<Type>(info->name).values(*obj).execute();
|
||||
|
||||
return entity{obj};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef QUERY_TABLE_HPP
|
||||
#define QUERY_TABLE_HPP
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
struct table
|
||||
{
|
||||
std::type_index index;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_TABLE_HPP
|
||||
|
|
@ -38,7 +38,7 @@ std::string to_string(const blob &data);
|
|||
* given stream
|
||||
*
|
||||
* @tparam R Type og the range (e.g. map, list, vector, etc)
|
||||
* @param range The range with the elements to join
|
||||
* @param range The range with the elements to join_left
|
||||
* @param delim The delimiter for the elements
|
||||
* @return The ostream reference
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
set(SQL_SOURCES
|
||||
sql/dialect.cpp
|
||||
sql/query_builder.cpp
|
||||
sql/column.cpp
|
||||
sql/column_definition.cpp
|
||||
sql/key_value_pair.cpp
|
||||
sql/basic_condition.cpp
|
||||
sql/connection.cpp
|
||||
|
|
@ -28,12 +28,16 @@ set(SQL_SOURCES
|
|||
sql/result_parameter_binder.cpp
|
||||
sql/statement.cpp
|
||||
sql/convert.cpp
|
||||
sql/column.cpp
|
||||
sql/query.cpp
|
||||
sql/query_parts.cpp
|
||||
sql/query_compiler.cpp
|
||||
)
|
||||
|
||||
set(SQL_HEADER
|
||||
../include/matador/sql/dialect.hpp
|
||||
../include/matador/sql/query_builder.hpp
|
||||
../include/matador/sql/column.hpp
|
||||
../include/matador/sql/column_definition.hpp
|
||||
../include/matador/sql/data_type_traits.hpp
|
||||
../include/matador/sql/key_value_pair.hpp
|
||||
../include/matador/sql/basic_condition.hpp
|
||||
|
|
@ -69,6 +73,34 @@ set(SQL_HEADER
|
|||
../include/matador/sql/placeholder_generator.hpp
|
||||
../include/matador/sql/result_parameter_binder.hpp
|
||||
../include/matador/sql/convert.hpp
|
||||
../include/matador/sql/query.hpp
|
||||
../include/matador/sql/query_parts.hpp
|
||||
../include/matador/sql/query_part_visitor.hpp
|
||||
../include/matador/sql/query_compiler.hpp
|
||||
../include/matador/sql/query_data.hpp
|
||||
../include/matador/sql/table.hpp
|
||||
)
|
||||
|
||||
set(QUERY_SOURCES
|
||||
query/query.cpp
|
||||
query/query_compiler.cpp
|
||||
query/query_parts.cpp
|
||||
query/column.cpp
|
||||
query/query_builder.cpp
|
||||
query/query_intermediates.cpp
|
||||
)
|
||||
|
||||
set(QUERY_HEADER
|
||||
../include/matador/query/query.hpp
|
||||
../include/matador/query/query_part_visitor.hpp
|
||||
../include/matador/query/query_compiler.hpp
|
||||
../include/matador/query/query_parts.hpp
|
||||
../include/matador/query/column.hpp
|
||||
../include/matador/query/query_builder.hpp
|
||||
../include/matador/query/query_intermediates.hpp
|
||||
../include/matador/query/sql_commands.hpp
|
||||
../include/matador/query/query_data.hpp
|
||||
../include/matador/query/table.hpp
|
||||
)
|
||||
|
||||
set(UTILS_HEADER
|
||||
|
|
@ -84,7 +116,8 @@ set(UTILS_HEADER
|
|||
../include/matador/utils/enum_mapper.hpp
|
||||
../include/matador/utils/types.hpp
|
||||
../include/matador/utils/foreign_attributes.hpp
|
||||
../include/matador/utils/fetch_type.hpp)
|
||||
../include/matador/utils/fetch_type.hpp
|
||||
)
|
||||
|
||||
set(UTILS_SOURCES
|
||||
utils/field_attributes.cpp
|
||||
|
|
@ -95,8 +128,14 @@ set(UTILS_SOURCES
|
|||
utils/identifier.cpp
|
||||
sql/value_extractor.cpp
|
||||
utils/logger.cpp
|
||||
utils/foreign_attributes.cpp)
|
||||
utils/foreign_attributes.cpp
|
||||
)
|
||||
|
||||
add_library(matador STATIC
|
||||
${SQL_SOURCES} ${SQL_HEADER}
|
||||
# ${QUERY_SOURCES} ${QUERY_HEADER}
|
||||
${UTILS_SOURCES} ${UTILS_HEADER}
|
||||
)
|
||||
|
||||
add_library(matador STATIC ${SQL_SOURCES} ${SQL_HEADER} ${UTILS_SOURCES} ${UTILS_HEADER})
|
||||
target_include_directories(matador PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||
#set_target_properties(matador PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#include "matador/query/column.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
column::column(const char *name)
|
||||
: name(name) {}
|
||||
|
||||
column::column(std::string name)
|
||||
: name(std::move(name)) {}
|
||||
|
||||
column::column(std::string table_name, std::string name, std::string as)
|
||||
: table(std::move(table_name))
|
||||
, name(std::move(name))
|
||||
, alias(std::move(as)) {}
|
||||
|
||||
column& column::as(std::string a) {
|
||||
alias = std::move(a);
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#include "matador/query/query.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include "matador/query/query_builder.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
query_builder::query_builder(const std::shared_ptr<sql::schema> &scm)
|
||||
: schema_(scm) {}
|
||||
|
||||
query_select_intermediate query_builder::select(std::initializer_list<column> columns)
|
||||
{
|
||||
return query_select_intermediate{schema_};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#include "matador/query/query_compiler.hpp"
|
||||
#include "matador/query/query_data.hpp"
|
||||
#include "matador/query/column.hpp"
|
||||
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
query_compiler::query_compiler(sql::dialect &d)
|
||||
: dialect_(d)
|
||||
{}
|
||||
|
||||
std::string query_compiler::compile(const query_data *data)
|
||||
{
|
||||
sql_.clear();
|
||||
for (const auto &part : data->parts) {
|
||||
part->accept(*this);
|
||||
}
|
||||
|
||||
return sql_;
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_select_part &select_part)
|
||||
{
|
||||
auto ci = "name"_col.as("c01");
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_from_part &from_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#include "matador/query/query_intermediates.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
query_intermediate::query_intermediate(const std::shared_ptr<sql::schema> &scm)
|
||||
: schema_(scm) {}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#include "matador/query/query_parts.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
query_part::query_part(sql::dialect::token_t token)
|
||||
: token_(token) {}
|
||||
|
||||
query_select_part::query_select_part(std::vector<column> columns)
|
||||
: query_part(sql::dialect::token_t::SELECT)
|
||||
, columns_(std::move(columns)) {}
|
||||
|
||||
void query_select_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_from_part::query_from_part(std::string table_name)
|
||||
: query_part(sql::dialect::token_t::FROM)
|
||||
, table_(std::move(table_name)) {}
|
||||
|
||||
query_from_part::query_from_part(std::string table_name, std::string as)
|
||||
: query_part(sql::dialect::token_t::FROM)
|
||||
, table_(std::move(table_name))
|
||||
, alias_(std::move(as)) {}
|
||||
|
||||
void query_from_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,129 +1,10 @@
|
|||
#include "matador/sql/column.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
column::column(sql_function_t func, std::string name)
|
||||
: name_(std::move(name)), type_(data_type_t::type_int), attributes_(utils::null_attributes), function_(func)
|
||||
{}
|
||||
|
||||
column::column(const char *name, std::string alias)
|
||||
: name_(name), attributes_(utils::null_attributes), alias_(std::move(alias))
|
||||
{}
|
||||
|
||||
column::column(std::string name, std::string alias)
|
||||
: name_(std::move(name)), attributes_(utils::null_attributes), alias_(std::move(alias))
|
||||
{}
|
||||
|
||||
column::column(std::string name, data_type_t type, utils::field_attributes attr, null_option null_opt, size_t index)
|
||||
: name_(std::move(name)), index_(index), type_(type), attributes_(attr), null_option_(null_opt)
|
||||
{}
|
||||
|
||||
column::column(std::string name, data_type_t type, size_t index, std::string ref_table, std::string ref_column,
|
||||
utils::field_attributes attr, null_option null_opt)
|
||||
: name_(std::move(name))
|
||||
, index_(index)
|
||||
, type_(type)
|
||||
, attributes_(attr)
|
||||
, null_option_(null_opt)
|
||||
, ref_table_(std::move(ref_table))
|
||||
, ref_column_(std::move(ref_column))
|
||||
{}
|
||||
|
||||
const std::string &column::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
size_t column::index() const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
|
||||
const utils::field_attributes &column::attributes() const
|
||||
{
|
||||
return attributes_;
|
||||
}
|
||||
|
||||
bool column::is_nullable() const
|
||||
{
|
||||
return null_option_ == null_option::NULLABLE;
|
||||
}
|
||||
|
||||
data_type_t column::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
const std::string &column::alias() const
|
||||
{
|
||||
return alias_;
|
||||
}
|
||||
|
||||
const std::string &column::ref_table() const
|
||||
{
|
||||
return ref_table_;
|
||||
}
|
||||
|
||||
const std::string &column::ref_column() const
|
||||
{
|
||||
return ref_column_;
|
||||
}
|
||||
|
||||
void column::type(data_type_t type)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
void column::alias(const std::string &as)
|
||||
{
|
||||
alias_ = as;
|
||||
}
|
||||
|
||||
std::string column::str() const
|
||||
{
|
||||
any_type_to_visitor<std::string> visitor;
|
||||
std::visit(visitor, const_cast<any_type &>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
bool column::is_function() const
|
||||
{
|
||||
return function_ != sql_function_t::NONE;
|
||||
}
|
||||
|
||||
sql_function_t column::function() const
|
||||
{
|
||||
return function_;
|
||||
}
|
||||
|
||||
column operator ""_col(const char *name, size_t len)
|
||||
{
|
||||
return {std::string(name, len)};
|
||||
return {{name, len}};
|
||||
}
|
||||
|
||||
column make_column(const std::string &name, data_type_t type, utils::field_attributes attr, null_option null_opt)
|
||||
{
|
||||
return {name, type, attr, null_opt};
|
||||
}
|
||||
|
||||
template<>
|
||||
column make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt)
|
||||
{
|
||||
return make_column(name, data_type_traits<std::string>::builtin_type(attr.size()), attr, null_opt);
|
||||
}
|
||||
|
||||
template<>
|
||||
column make_pk_column<std::string>(const std::string &name, size_t size)
|
||||
{
|
||||
return make_column<std::string>(name, {size, utils::constraints::FOREIGN_KEY});
|
||||
}
|
||||
|
||||
template<>
|
||||
[[maybe_unused]] column make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table,
|
||||
const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<std::string>::builtin_type(size), 0, ref_table, ref_column, {size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
#include "matador/sql/column_definition.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
column_definition::column_definition(const char *name)
|
||||
: name_(name), attributes_(utils::null_attributes)
|
||||
{}
|
||||
|
||||
column_definition::column_definition(std::string name)
|
||||
: name_(std::move(name)), attributes_(utils::null_attributes)
|
||||
{}
|
||||
|
||||
column_definition::column_definition(std::string name, data_type_t type, utils::field_attributes attr, null_option null_opt, size_t index)
|
||||
: name_(std::move(name)), index_(index), type_(type), attributes_(attr), null_option_(null_opt)
|
||||
{}
|
||||
|
||||
column_definition::column_definition(std::string name, data_type_t type, size_t index, std::string ref_table, std::string ref_column,
|
||||
utils::field_attributes attr, null_option null_opt)
|
||||
: name_(std::move(name))
|
||||
, index_(index)
|
||||
, type_(type)
|
||||
, attributes_(attr)
|
||||
, null_option_(null_opt)
|
||||
, ref_table_(std::move(ref_table))
|
||||
, ref_column_(std::move(ref_column))
|
||||
{}
|
||||
|
||||
const std::string &column_definition::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
size_t column_definition::index() const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
|
||||
const utils::field_attributes &column_definition::attributes() const
|
||||
{
|
||||
return attributes_;
|
||||
}
|
||||
|
||||
bool column_definition::is_nullable() const
|
||||
{
|
||||
return null_option_ == null_option::NULLABLE;
|
||||
}
|
||||
|
||||
data_type_t column_definition::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
const std::string &column_definition::ref_table() const
|
||||
{
|
||||
return ref_table_;
|
||||
}
|
||||
|
||||
const std::string &column_definition::ref_column() const
|
||||
{
|
||||
return ref_column_;
|
||||
}
|
||||
|
||||
void column_definition::type(data_type_t type)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
std::string column_definition::str() const
|
||||
{
|
||||
any_type_to_visitor<std::string> visitor;
|
||||
std::visit(visitor, const_cast<any_type &>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
column_definition make_column(const std::string &name, data_type_t type, utils::field_attributes attr, null_option null_opt)
|
||||
{
|
||||
return {name, type, attr, null_opt};
|
||||
}
|
||||
|
||||
template<>
|
||||
column_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt)
|
||||
{
|
||||
return make_column(name, data_type_traits<std::string>::builtin_type(attr.size()), attr, null_opt);
|
||||
}
|
||||
|
||||
template<>
|
||||
column_definition make_pk_column<std::string>(const std::string &name, size_t size)
|
||||
{
|
||||
return make_column<std::string>(name, {size, utils::constraints::FOREIGN_KEY});
|
||||
}
|
||||
|
||||
template<>
|
||||
[[maybe_unused]] column_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table,
|
||||
const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<std::string>::builtin_type(size), 0, ref_table, ref_column, {size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL};
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
column_generator::column_generator(std::vector<column> &columns, const schema &repo)
|
||||
column_generator::column_generator(std::vector<column_definition> &columns, const schema &repo)
|
||||
: columns_(columns)
|
||||
, repo_(repo)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
column_name_generator::column_name_generator(std::vector<column_info> &column_infos,
|
||||
column_name_generator::column_name_generator(std::vector<column> &column_infos,
|
||||
const sql::schema &ts,
|
||||
const std::string &table_name)
|
||||
: column_infos_(column_infos)
|
||||
|
|
@ -25,7 +25,7 @@ void column_name_generator::push(const std::string &column_name)
|
|||
{
|
||||
char str[4];
|
||||
snprintf(str, 4, "c%02d", ++column_index);
|
||||
column_infos_.emplace_back(column_info{table_name_stack_.top(), column_name, str});
|
||||
column_infos_.emplace_back(table_name_stack_.top(), column_name, str);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,8 +8,8 @@ condition<column, placeholder, std::enable_if<true>::type>::condition(const colu
|
|||
|
||||
std::string condition<column, placeholder, std::enable_if<true>::type>::evaluate(dialect &d, query_context &query) const
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
return d.prepare_identifier(field_.name()) + " " + operand + " " + d.next_placeholder(query.bind_vars);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_.name) + " " + operand + " " + d.next_placeholder(query.bind_vars);
|
||||
}
|
||||
|
||||
condition<column, query_context>::condition(column col, basic_condition::operand_t op, query_context &q)
|
||||
|
|
@ -18,9 +18,13 @@ condition<column, query_context>::condition(column col, basic_condition::operand
|
|||
|
||||
std::string condition<column, query_context>::evaluate(dialect &d, query_context &query) const
|
||||
{
|
||||
std::string result(d.prepare_identifier(field_.name()) + " " + operand + " (");
|
||||
std::string result(d.prepare_identifier(field_.name) + " " + operand + " (");
|
||||
result += (")");
|
||||
return result;
|
||||
}
|
||||
|
||||
condition<column, column> operator==(const column &a, const column &b)
|
||||
{
|
||||
return {a, basic_condition::operand_t::EQUAL, b};
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
connection::connection(connection_info info, const std::shared_ptr<schema> &repo)
|
||||
connection::connection(connection_info info, const std::shared_ptr<sql::schema> &repo)
|
||||
: connection_info_(std::move(info))
|
||||
, logger_(stdout, "SQL")
|
||||
, dialect_(backend_provider::instance().connection_dialect(connection_info_.type))
|
||||
|
|
@ -17,7 +17,7 @@ connection::connection(connection_info info, const std::shared_ptr<schema> &repo
|
|||
connection_.reset(backend_provider::instance().create_connection(connection_info_.type, connection_info_));
|
||||
}
|
||||
|
||||
connection::connection(const std::string& dns, const std::shared_ptr<schema> &repo)
|
||||
connection::connection(const std::string& dns, const std::shared_ptr<sql::schema> &repo)
|
||||
: connection(connection_info::parse(dns), repo)
|
||||
{}
|
||||
|
||||
|
|
@ -69,36 +69,6 @@ const connection_info &connection::info() const
|
|||
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
|
||||
{
|
||||
return std::move(connection_->describe(table_name));
|
||||
|
|
@ -120,13 +90,18 @@ size_t connection::execute(const std::string &sql) const
|
|||
return connection_->execute(sql);
|
||||
}
|
||||
|
||||
sql::query connection::query() const
|
||||
{
|
||||
return sql::query(*const_cast<connection*>(this));
|
||||
}
|
||||
|
||||
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());
|
||||
const_cast<column_definition&>(col).type(rit->type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -160,7 +135,7 @@ const class dialect &connection::dialect() const
|
|||
return dialect_;
|
||||
}
|
||||
|
||||
std::shared_ptr<schema> connection::tables() const
|
||||
std::shared_ptr<schema> connection::schema() const
|
||||
{
|
||||
return schema_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
|
||||
#include "matador/utils/string.hpp"
|
||||
|
||||
|
|
@ -19,12 +19,12 @@ std::string dialect::prepare_identifier(const column &col) const
|
|||
{
|
||||
std::string result;
|
||||
if (!col.is_function()) {
|
||||
result = prepare_identifier_string(col.name());
|
||||
result = prepare_identifier_string(col.name);
|
||||
} else {
|
||||
result = sql_func_map_.at(col.function()) + "(" + col.name() + ")";
|
||||
result = sql_func_map_.at(col.function_) + "(" + col.name + ")";
|
||||
}
|
||||
if (!col.alias().empty()) {
|
||||
result += " AS " + col.alias();
|
||||
if (!col.alias.empty()) {
|
||||
result += " AS " + col.alias;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#include "matador/sql/query.hpp"
|
||||
#include "matador/sql/connection.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
query::query(connection &c)
|
||||
: connection_(c)
|
||||
{}
|
||||
|
||||
query_create_intermediate query::create()
|
||||
{
|
||||
return query_create_intermediate(connection_);
|
||||
}
|
||||
|
||||
query_drop_intermediate query::drop()
|
||||
{
|
||||
return query_drop_intermediate{connection_};
|
||||
}
|
||||
|
||||
query_select_intermediate query::select(std::initializer_list<column> columns)
|
||||
{
|
||||
return {connection_, columns};
|
||||
}
|
||||
|
||||
query_insert_intermediate query::insert()
|
||||
{
|
||||
return query_insert_intermediate{connection_};
|
||||
}
|
||||
|
||||
query_update_intermediate query::update(const std::string &table)
|
||||
{
|
||||
return query_update_intermediate{connection_, table};
|
||||
}
|
||||
|
||||
query_delete_intermediate query::remove()
|
||||
{
|
||||
return query_delete_intermediate{connection_};
|
||||
}
|
||||
|
||||
const sql::schema& query::schema() const
|
||||
{
|
||||
return *connection_.schema();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "matador/sql/query_builder.hpp"
|
||||
#include "matador/sql/column_name_generator.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
#include "matador/utils/string.hpp"
|
||||
|
|
@ -139,19 +140,19 @@ query_builder &query_builder::select(const std::vector<column> &columns)
|
|||
if (columns.size() < 2) {
|
||||
for (const auto &col: columns) {
|
||||
result.append(dialect_.prepare_identifier(col));
|
||||
query_.result_vars.emplace_back(col.name());
|
||||
query_.prototype.append(col);
|
||||
query_.result_vars.emplace_back(col.name);
|
||||
query_.prototype.append(column_definition{col.name});
|
||||
}
|
||||
} else {
|
||||
auto it = columns.begin();
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
query_.result_vars.emplace_back(it->name());
|
||||
query_.prototype.append(column{*it++});
|
||||
query_.result_vars.emplace_back(it->name);
|
||||
query_.prototype.append(column_definition{(*it++).name});
|
||||
for (; it != columns.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
query_.result_vars.emplace_back(it->name());
|
||||
query_.prototype.append(column{*it});
|
||||
query_.result_vars.emplace_back(it->name);
|
||||
query_.prototype.append(column_definition{(*it).name});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,9 +188,9 @@ query_builder &query_builder::remove()
|
|||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::table(const std::string &table, std::initializer_list<column> columns)
|
||||
query_builder &query_builder::table(const std::string &table, std::initializer_list<column_definition> columns)
|
||||
{
|
||||
return this->table(table, std::vector<column>{columns});
|
||||
return this->table(table, std::vector<column_definition>{columns});
|
||||
}
|
||||
|
||||
struct fk_context
|
||||
|
|
@ -205,9 +206,9 @@ struct column_context
|
|||
std::vector<fk_context> foreign_contexts;
|
||||
};
|
||||
|
||||
std::string build_create_column(const column &col, const dialect &d, column_context &context);
|
||||
std::string build_create_column(const column_definition &col, const dialect &d, column_context &context);
|
||||
|
||||
query_builder &query_builder::table(const std::string &table, const std::vector<column> &columns)
|
||||
query_builder &query_builder::table(const std::string &table, const std::vector<column_definition> &columns)
|
||||
{
|
||||
transition_to(state_t::QUERY_TABLE_CREATE);
|
||||
|
||||
|
|
@ -256,12 +257,12 @@ query_builder &query_builder::table(const std::string &table)
|
|||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::into(const std::string &table, std::initializer_list<column_info> column_names)
|
||||
query_builder &query_builder::into(const std::string &table, std::initializer_list<column> column_names)
|
||||
{
|
||||
return into(table, std::vector<column_info>{column_names});
|
||||
return into(table, std::vector<column>{column_names});
|
||||
}
|
||||
|
||||
query_builder &query_builder::into(const std::string &table, const std::vector<column_info> &column_names)
|
||||
query_builder &query_builder::into(const std::string &table, const std::vector<column> &column_names)
|
||||
{
|
||||
transition_to(state_t::QUERY_INTO);
|
||||
|
||||
|
|
@ -490,7 +491,7 @@ void query_builder::initialize(query_builder::command_t cmd, query_builder::stat
|
|||
query_parts_.clear();
|
||||
}
|
||||
|
||||
std::string build_create_column(const column &col, const dialect &d, column_context &context)
|
||||
std::string build_create_column(const column_definition &col, const dialect &d, column_context &context)
|
||||
{
|
||||
std::string result = d.prepare_identifier(col.name()) + " " + d.data_type_at(col.type());
|
||||
if (col.attributes().size() > 0) {
|
||||
|
|
@ -514,12 +515,12 @@ std::string build_create_column(const column &col, const dialect &d, column_cont
|
|||
|
||||
column alias(const std::string &column, const std::string &as)
|
||||
{
|
||||
return {column, as};
|
||||
return {"", column, as};
|
||||
}
|
||||
|
||||
column alias(column &&col, const std::string &as)
|
||||
{
|
||||
col.alias(as);
|
||||
col.as(as);
|
||||
return std::move(col);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
#include "matador/sql/query_compiler.hpp"
|
||||
#include "matador/sql/query_data.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
query_compiler::query_compiler(const sql::dialect &d)
|
||||
: dialect_(d)
|
||||
{}
|
||||
|
||||
query_context query_compiler::compile(const query_data *data)
|
||||
{
|
||||
for (const auto &part : data->parts) {
|
||||
part->accept(*this);
|
||||
}
|
||||
|
||||
return query_;
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_select_part &select_part)
|
||||
{
|
||||
std::string result;
|
||||
const auto &columns = select_part.columns();
|
||||
if (columns.size() < 2) {
|
||||
for (const auto &col: columns) {
|
||||
result.append(dialect_.prepare_identifier(col));
|
||||
query_.result_vars.emplace_back(col.name);
|
||||
query_.prototype.append(column_definition{col.name});
|
||||
}
|
||||
} else {
|
||||
auto it = columns.begin();
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
query_.result_vars.emplace_back(it->name);
|
||||
query_.prototype.append(column_definition{(*it++).name});
|
||||
for (; it != columns.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
query_.result_vars.emplace_back(it->name);
|
||||
query_.prototype.append(column_definition{(*it).name});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_from_part &from_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_where_part &where_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_group_by_part &group_by_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_order_by_part &order_by_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_order_by_asc_part &order_by_asc_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_order_by_desc_part &order_by_desc_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_insert_part &insert_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_values_part &values_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_update_part &update_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_delete_part &delete_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_create_part &create_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void query_compiler::visit(query_drop_part &drop_part)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "matador/sql/query_intermediates.hpp"
|
||||
#include "matador/sql/session.hpp"
|
||||
#include "matador/sql/query_compiler.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
basic_query_intermediate::basic_query_intermediate(connection &db)
|
||||
|
|
@ -7,219 +8,252 @@ basic_query_intermediate::basic_query_intermediate(connection &db)
|
|||
|
||||
std::shared_ptr<schema> basic_query_intermediate::tables() const
|
||||
{
|
||||
return connection_.tables();
|
||||
return connection_.schema();
|
||||
}
|
||||
|
||||
query_result<record> query_select_finish::fetch_all()
|
||||
{
|
||||
return connection_.fetch(builder_.compile());
|
||||
query_compiler compiler(connection_.dialect());
|
||||
return connection_.fetch(compiler.compile(&data_));
|
||||
}
|
||||
|
||||
record query_select_finish::fetch_one()
|
||||
{
|
||||
return *connection_.fetch(builder_.compile()).begin().get();
|
||||
query_compiler compiler(connection_.dialect());
|
||||
return *connection_.fetch(compiler.compile(&data_)).begin().get();
|
||||
}
|
||||
|
||||
std::unique_ptr<query_result_impl> query_select_finish::fetch()
|
||||
{
|
||||
return connection_.fetch(builder_.compile().sql);
|
||||
query_compiler compiler(connection_.dialect());
|
||||
return connection_.fetch(compiler.compile(&data_).sql);
|
||||
}
|
||||
|
||||
statement query_select_finish::prepare()
|
||||
{
|
||||
return connection_.prepare(builder_.compile());
|
||||
query_compiler compiler(connection_.dialect());
|
||||
return connection_.prepare(compiler.compile(&data_));
|
||||
}
|
||||
|
||||
query_intermediate::query_intermediate(connection &db, query_builder &query)
|
||||
: basic_query_intermediate(db), builder_(query) {}
|
||||
query_intermediate::query_intermediate(connection &db, query_data &data)
|
||||
: basic_query_intermediate(db), data_(data) {}
|
||||
|
||||
query_offset_intermediate query_order_direction_intermediate::offset(size_t offset)
|
||||
{
|
||||
return {connection_, builder_};
|
||||
return {connection_, data_};
|
||||
}
|
||||
|
||||
query_limit_intermediate query_offset_intermediate::limit(size_t limit)
|
||||
{
|
||||
return {connection_, builder_};
|
||||
return {connection_, data_};
|
||||
}
|
||||
|
||||
query_limit_intermediate query_order_direction_intermediate::limit(size_t limit)
|
||||
{
|
||||
return {connection_, builder_};
|
||||
return {connection_, data_};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_group_by_intermediate::order_by(const std::string &name)
|
||||
{
|
||||
return {connection_, builder_.order_by(name)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.order_by(name)};
|
||||
}
|
||||
|
||||
query_order_direction_intermediate query_order_by_intermediate::asc()
|
||||
{
|
||||
return {connection_, builder_.asc()};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.asc()};
|
||||
}
|
||||
|
||||
query_order_direction_intermediate query_order_by_intermediate::desc()
|
||||
{
|
||||
return {connection_, builder_.desc()};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.desc()};
|
||||
}
|
||||
|
||||
query_group_by_intermediate query_from_intermediate::group_by(const std::string &name)
|
||||
{
|
||||
return {connection_, builder_.group_by(name)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.group_by(name)};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_from_intermediate::order_by(const std::string &name)
|
||||
{
|
||||
return {connection_, builder_.order_by(name)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.order_by(name)};
|
||||
}
|
||||
|
||||
query_group_by_intermediate query_where_intermediate::group_by(const std::string &name)
|
||||
{
|
||||
return {connection_, builder_.group_by(name)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.group_by(name)};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_where_intermediate::order_by(const std::string &name)
|
||||
{
|
||||
return {connection_, builder_.order_by(name)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.order_by(name)};
|
||||
}
|
||||
|
||||
query_join_intermediate query_on_intermediate::join(const std::string &join_table_name, const std::string &as)
|
||||
{
|
||||
return {connection_, builder_.join(join_table_name, join_type_t::INNER, as)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.join(join_table_name, join_type_t::INNER, as)};
|
||||
}
|
||||
|
||||
query_where_intermediate query_on_intermediate::where(const basic_condition &cond)
|
||||
{
|
||||
return {connection_, builder_.where(cond)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.where(cond)};
|
||||
}
|
||||
|
||||
query_group_by_intermediate query_on_intermediate::group_by(const std::string &name)
|
||||
{
|
||||
return {connection_, builder_.group_by(name)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.group_by(name)};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_on_intermediate::order_by(const std::string &name)
|
||||
{
|
||||
return {connection_, builder_.order_by(name)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.order_by(name)};
|
||||
}
|
||||
|
||||
query_on_intermediate query_join_intermediate::on(const std::string &column, const std::string &join_column)
|
||||
query_on_intermediate query_join_intermediate::on(const basic_condition &cond)
|
||||
{
|
||||
return {connection_, builder_.on(column, join_column)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.on(column, join_column)};
|
||||
}
|
||||
|
||||
query_join_intermediate query_from_intermediate::join(const std::string &join_table_name, const std::string &as)
|
||||
query_join_intermediate query_from_intermediate::join_left(const std::string &join_table_name, const std::string &as)
|
||||
{
|
||||
return {connection_, builder_.join(join_table_name, join_type_t::INNER, as)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.join(join_table_name, join_type_t::INNER, as)};
|
||||
}
|
||||
|
||||
query_where_intermediate query_from_intermediate::where(const basic_condition &cond)
|
||||
{
|
||||
return query_where_intermediate{connection_, builder_.where(cond)};
|
||||
return query_where_intermediate{connection_, data_};
|
||||
// return query_where_intermediate{connection_, builder_.where(cond)};
|
||||
}
|
||||
|
||||
query_select_intermediate::query_select_intermediate(connection &s, const std::vector<column>& columns)
|
||||
: query_start_intermediate(s)
|
||||
query_select_intermediate::query_select_intermediate(connection &db, const std::vector<column>& columns)
|
||||
: query_start_intermediate(db)
|
||||
{
|
||||
builder_.select(columns);
|
||||
data_.parts.push_back(std::make_unique<query_select_part>(columns));
|
||||
}
|
||||
|
||||
query_from_intermediate query_select_intermediate::from(const std::string &table, const std::string &as)
|
||||
{
|
||||
return {connection_, builder_.from(table, as)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.from(table, as)};
|
||||
}
|
||||
|
||||
query_insert_intermediate::query_insert_intermediate(connection &s)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.insert();
|
||||
data_.parts.push_back(std::make_unique<query_insert_part>());
|
||||
}
|
||||
|
||||
query_into_intermediate query_insert_intermediate::into(const std::string &table, std::initializer_list<column_info> column_names)
|
||||
query_into_intermediate query_insert_intermediate::into(const std::string &table, std::initializer_list<column> column_names)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_names)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.into(table, column_names)};
|
||||
}
|
||||
|
||||
size_t query_execute_finish::execute()
|
||||
{
|
||||
return connection_.execute(builder_.compile().sql);
|
||||
query_compiler compiler(connection_.dialect());
|
||||
return connection_.execute(compiler.compile(&data_).sql);
|
||||
}
|
||||
|
||||
statement query_execute_finish::prepare()
|
||||
{
|
||||
return connection_.prepare(builder_.compile());
|
||||
query_compiler compiler(connection_.dialect());
|
||||
return connection_.prepare(compiler.compile(&data_));
|
||||
}
|
||||
|
||||
query_execute_finish query_into_intermediate::values(std::initializer_list<any_type> values)
|
||||
{
|
||||
return {connection_, builder_.values(values)};
|
||||
return this->values(std::vector<any_type>(values));
|
||||
}
|
||||
|
||||
query_execute_finish query_into_intermediate::values(const std::vector<any_type> &values)
|
||||
{
|
||||
return {connection_, data_};
|
||||
}
|
||||
|
||||
query_create_intermediate::query_create_intermediate(connection &db)
|
||||
: query_start_intermediate(db) {
|
||||
builder_.create();
|
||||
data_.parts.push_back(std::make_unique<query_create_part>());
|
||||
}
|
||||
|
||||
query_execute_finish query_create_intermediate::table(const std::string &table_name, std::initializer_list<column> columns)
|
||||
query_execute_finish query_create_intermediate::table(const std::string &table_name, std::initializer_list<column_definition> columns)
|
||||
{
|
||||
return table(table_name, std::vector<column>{columns});
|
||||
return table(table_name, std::vector<column_definition>{columns});
|
||||
}
|
||||
|
||||
query_execute_finish query_create_intermediate::table(const std::string &table_name, const std::vector<column> &columns)
|
||||
query_execute_finish query_create_intermediate::table(const std::string &table_name, const std::vector<column_definition> &columns)
|
||||
{
|
||||
return {connection_, builder_.table(table_name, columns)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.table(table_name, columns)};
|
||||
}
|
||||
|
||||
query_drop_intermediate::query_drop_intermediate(connection &s)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.drop();
|
||||
data_.parts.push_back(std::make_unique<query_drop_part>());
|
||||
}
|
||||
|
||||
query_execute_finish query_drop_intermediate::table(const std::string &table)
|
||||
{
|
||||
return {connection_, builder_.table(table)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.table(table)};
|
||||
}
|
||||
|
||||
query_execute_finish query_execute_where_intermediate::limit(int limit)
|
||||
{
|
||||
return {connection_, builder_.limit(limit)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.limit(limit)};
|
||||
}
|
||||
|
||||
query_execute_where_intermediate query_set_intermediate::where(const basic_condition &cond)
|
||||
{
|
||||
return {connection_, builder_.where(cond)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.where(cond)};
|
||||
}
|
||||
|
||||
query_update_intermediate::query_update_intermediate(connection &s, const std::string& table_name)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.update(table_name);
|
||||
data_.parts.push_back(std::make_unique<query_update_part>(table_name));
|
||||
}
|
||||
|
||||
query_set_intermediate query_update_intermediate::set(std::initializer_list<key_value_pair> columns)
|
||||
{
|
||||
return {connection_, builder_.set(columns)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.set(columns)};
|
||||
}
|
||||
|
||||
query_execute_where_intermediate query_delete_from_intermediate::where(const basic_condition &cond)
|
||||
{
|
||||
return {connection_, builder_.where(cond)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.where(cond)};
|
||||
}
|
||||
|
||||
query_delete_intermediate::query_delete_intermediate(connection &s)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.remove();
|
||||
data_.parts.push_back(std::make_unique<query_delete_part>());
|
||||
}
|
||||
|
||||
query_delete_from_intermediate query_delete_intermediate::from(const std::string &table)
|
||||
{
|
||||
return {connection_, builder_.from(table)};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.from(table)};
|
||||
}
|
||||
|
||||
query_start_intermediate::query_start_intermediate(connection &s)
|
||||
: basic_query_intermediate(s)
|
||||
, builder_(s.dialect())
|
||||
query_start_intermediate::query_start_intermediate(connection &db)
|
||||
: basic_query_intermediate(db)
|
||||
{}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
#include "matador/sql/query_parts.hpp"
|
||||
#include "matador/sql/basic_condition.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
query_part::query_part(sql::dialect::token_t token)
|
||||
: token_(token) {}
|
||||
|
||||
query_select_part::query_select_part(std::vector<column> columns)
|
||||
: query_part(sql::dialect::token_t::SELECT)
|
||||
, columns_(std::move(columns)) {}
|
||||
|
||||
void query_select_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
const std::vector<column>& query_select_part::columns() const
|
||||
{
|
||||
return columns_;
|
||||
}
|
||||
|
||||
query_from_part::query_from_part(std::string table_name)
|
||||
: query_part(sql::dialect::token_t::FROM)
|
||||
, table_(std::move(table_name)) {}
|
||||
|
||||
query_from_part::query_from_part(std::string table_name, std::string as)
|
||||
: query_part(sql::dialect::token_t::FROM)
|
||||
, table_(std::move(table_name))
|
||||
, alias_(std::move(as)) {}
|
||||
|
||||
void query_from_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
void query_where_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_table_name_part::query_table_name_part(sql::dialect::token_t token, std::string table_name)
|
||||
: query_part(token)
|
||||
, table_name_(std::move(table_name)) {}
|
||||
|
||||
query_group_by_part::query_group_by_part(const std::string &table_name)
|
||||
: query_table_name_part(dialect::token_t::GROUP_BY, table_name)
|
||||
{}
|
||||
|
||||
void query_group_by_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_order_by_part::query_order_by_part(const std::string &table_name)
|
||||
: query_table_name_part(dialect::token_t::ORDER_BY, table_name)
|
||||
{}
|
||||
|
||||
void query_order_by_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_order_by_asc_part::query_order_by_asc_part()
|
||||
: query_part(dialect::token_t::ASC)
|
||||
{}
|
||||
|
||||
void query_order_by_asc_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_order_by_desc_part::query_order_by_desc_part()
|
||||
: query_part(dialect::token_t::DESC)
|
||||
{}
|
||||
|
||||
void query_order_by_desc_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_insert_part::query_insert_part()
|
||||
: query_part(dialect::token_t::INSERT) {}
|
||||
|
||||
void query_insert_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_values_part::query_values_part(std::initializer_list<any_type> values)
|
||||
: query_part(sql::dialect::token_t::VALUES)
|
||||
, values_(values) {}
|
||||
|
||||
void query_values_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_update_part::query_update_part(const std::string &table_name)
|
||||
: query_table_name_part(dialect::token_t::UPDATE, table_name) {}
|
||||
|
||||
void query_update_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_delete_part::query_delete_part()
|
||||
: query_part(sql::dialect::token_t::REMOVE) {}
|
||||
|
||||
void query_delete_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_create_part::query_create_part()
|
||||
: query_part(sql::dialect::token_t::CREATE) {}
|
||||
|
||||
void query_create_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_drop_part::query_drop_part()
|
||||
: query_part(sql::dialect::token_t::DROP) {}
|
||||
|
||||
void query_drop_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
record::record(std::initializer_list<column> columns)
|
||||
record::record(std::initializer_list<column_definition> columns)
|
||||
: columns_(columns)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
record::record(const std::vector<column> &columns)
|
||||
record::record(const std::vector<column_definition> &columns)
|
||||
: columns_(columns)
|
||||
{
|
||||
init();
|
||||
|
|
@ -41,7 +41,7 @@ record &record::operator=(const record &x)
|
|||
return *this;
|
||||
}
|
||||
|
||||
const std::vector<column> &record::columns() const
|
||||
const std::vector<column_definition> &record::columns() const
|
||||
{
|
||||
return columns_;
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ bool record::has_primary_key() const
|
|||
return pk_index_ > -1;
|
||||
}
|
||||
|
||||
const column &record::primary_key() const
|
||||
const column_definition &record::primary_key() const
|
||||
{
|
||||
if (!has_primary_key()) {
|
||||
throw std::logic_error("record has no primary key");
|
||||
|
|
@ -60,13 +60,13 @@ const column &record::primary_key() const
|
|||
return columns_[pk_index_];
|
||||
}
|
||||
|
||||
const column &record::at(const std::string &name) const
|
||||
const column_definition &record::at(const std::string &name) const
|
||||
{
|
||||
auto ref = columns_by_name_.at(name).first;
|
||||
return columns_by_name_.at(name).first;
|
||||
}
|
||||
|
||||
const column &record::at(size_t index) const
|
||||
const column_definition &record::at(size_t index) const
|
||||
{
|
||||
return columns_.at(index);
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ record::const_iterator record::find(const std::string &column_name) const {
|
|||
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
|
||||
}
|
||||
|
||||
void record::append(column col)
|
||||
void record::append(column_definition col)
|
||||
{
|
||||
auto &ref = columns_.emplace_back(std::move(col));
|
||||
add_to_map(ref, columns_.size()-1);
|
||||
|
|
@ -149,7 +149,7 @@ void record::init()
|
|||
}
|
||||
}
|
||||
|
||||
void record::add_to_map(column &col, size_t index)
|
||||
void record::add_to_map(column_definition &col, size_t index)
|
||||
{
|
||||
columns_by_name_.emplace(col.name(), column_index_pair {std::ref(col), index});
|
||||
if (utils::is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
|
||||
|
|
|
|||
|
|
@ -7,12 +7,17 @@ namespace matador::sql {
|
|||
|
||||
void table_info::create(connection &conn) const
|
||||
{
|
||||
conn.create().table(name, prototype.columns()).execute();
|
||||
conn.query().create().table(name, prototype.columns()).execute();
|
||||
}
|
||||
|
||||
void table_info::drop(connection &conn) const
|
||||
{
|
||||
conn.drop().table(name).execute();
|
||||
conn.query().drop().table(name).execute();
|
||||
}
|
||||
|
||||
std::string schema::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
const table_info& schema::attach(const std::type_index ti, const table_info& table)
|
||||
|
|
@ -71,4 +76,5 @@ bool schema::empty() const
|
|||
{
|
||||
return repository_.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ void session::drop_table(const std::string &table_name)
|
|||
throw std::logic_error("no database connection available");
|
||||
}
|
||||
|
||||
c->drop().table(table_name).execute();
|
||||
c->query().drop().table(table_name).execute();
|
||||
}
|
||||
|
||||
query_result<record> session::fetch(const query_context &q) const
|
||||
|
|
@ -41,7 +41,7 @@ query_result<record> session::fetch(const query_context &q) const
|
|||
// 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());
|
||||
const_cast<column_definition&>(col).type(rit->type());
|
||||
}
|
||||
}
|
||||
auto res = c->fetch(q.sql);
|
||||
|
|
|
|||
|
|
@ -14,16 +14,16 @@ TEST_CASE("Generate columns from object", "[column generator]") {
|
|||
|
||||
auto columns = column_generator::generate<matador::test::product>(repo);
|
||||
|
||||
const std::vector<column> expected_columns = {
|
||||
column{ "product_name", data_type_t::type_varchar, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||
column{ "supplier_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||
column{ "category_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||
column{ "quantity_per_unit", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||
column{ "unit_price", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column{ "units_in_stock", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column{ "units_in_order", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column{ "reorder_level", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column{ "discontinued", data_type_t::type_bool, null_attributes, null_option::NOT_NULL }
|
||||
const std::vector<column_definition> expected_columns = {
|
||||
column_definition{"product_name", data_type_t::type_varchar, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||
column_definition{"supplier_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||
column_definition{"category_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||
column_definition{"quantity_per_unit", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||
column_definition{"unit_price", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column_definition{"units_in_stock", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column_definition{"units_in_order", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column_definition{"reorder_level", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||
column_definition{"discontinued", data_type_t::type_bool, null_attributes, null_option::NOT_NULL }
|
||||
};
|
||||
REQUIRE(!columns.empty());
|
||||
REQUIRE(columns.size() == expected_columns.size());
|
||||
|
|
@ -40,10 +40,10 @@ TEST_CASE("Generate columns from object with nullable columns", "[column generat
|
|||
|
||||
auto columns = column_generator::generate<matador::test::optional>(repo);
|
||||
|
||||
const std::vector<column> expected_columns = {
|
||||
column{ "id", data_type_t::type_unsigned_long, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||
column{ "name", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||
column{ "age", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL }
|
||||
const std::vector<column_definition> expected_columns = {
|
||||
column_definition{"id", data_type_t::type_unsigned_long, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||
column_definition{"name", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||
column_definition{"age", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL }
|
||||
};
|
||||
REQUIRE(!columns.empty());
|
||||
REQUIRE(columns.size() == expected_columns.size());
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
|
||||
using namespace matador::sql;
|
||||
|
||||
TEST_CASE("Create empty column", "[column]") {
|
||||
column c("name");
|
||||
column_definition c("name");
|
||||
|
||||
REQUIRE(c.name() == "name");
|
||||
REQUIRE(c.index() == 0);
|
||||
|
|
@ -25,7 +25,7 @@ TEST_CASE("Create empty column", "[column]") {
|
|||
}
|
||||
|
||||
TEST_CASE("Copy and move column", "[column]") {
|
||||
column c("name");
|
||||
column_definition c("name");
|
||||
c.set(std::string{"george"}, 255);
|
||||
REQUIRE(c.name() == "name");
|
||||
REQUIRE(c.index() == 0);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <matador/sql/column.hpp>
|
||||
#include <matador/sql/column_definition.hpp>
|
||||
#include <matador/sql/condition.hpp>
|
||||
#include <matador/sql/dialect_builder.hpp>
|
||||
#include <matador/sql/query_builder.hpp>
|
||||
|
|
@ -164,7 +164,7 @@ TEST_CASE("Create, insert and select a blob column", "[query][blob]") {
|
|||
REQUIRE(q.table_name == "person");
|
||||
|
||||
q = query.insert().into("person", {
|
||||
{"", "id", ""}, {"", "name", ""}, {"", "data", ""}
|
||||
{ "id", "name", "data" }
|
||||
}).values({7UL, "george", blob{1, 'A', 3, 4}}).compile();
|
||||
|
||||
REQUIRE(q.sql == R"(INSERT INTO "person" ("id", "name", "data") VALUES (7, 'george', X'01410304'))");
|
||||
|
|
@ -176,7 +176,7 @@ TEST_CASE("Create, insert and select a blob column", "[query][blob]") {
|
|||
REQUIRE(q.table_name == "person");
|
||||
}
|
||||
|
||||
TEST_CASE("Select statement with join", "[query][join]") {
|
||||
TEST_CASE("Select statement with join_left", "[query][join_left]") {
|
||||
dialect d = dialect_builder::builder().create().build();
|
||||
query_builder query(d);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue