#include "matador/sql/connection.hpp" #include "matador/sql/connection_pool.hpp" #include "matador/query/criteria.hpp" #include "matador/query/query.hpp" #include "matador/query/table_column.hpp" #include "matador/query/meta_table_macro.hpp" #include "matador/query/schema.hpp" #include "matador/object/object_ptr.hpp" #include "matador/object/repository.hpp" #include "matador/utils/access.hpp" #include "matador/utils/default_type_traits.hpp" #include "matador/utils/enum_mapper.hpp" #include struct author { unsigned int id{}; std::string first_name; std::string last_name; std::string date_of_birth; unsigned short year_of_birth{}; bool distinguished{false}; template void process(Operator &op) { namespace field = matador::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 int id{}; matador::object::object_ptr book_author; std::string title; unsigned short published_in{}; template void process(Operator &op) { namespace field = matador::access; field::primary_key(op, "id", id); field::attribute(op, "title", title, 511); field::belongs_to(op, "author_id", book_author, matador::utils::CascadeNoneFetchLazy); field::attribute(op, "published_in", published_in); } }; struct payload { unsigned int id{}; template void process(Operator &op) { namespace field = matador::access; field::primary_key(op, "id", id); } }; struct job { enum class job_state { Pending, Running, Succeeded, Failed, Canceled }; enum class job_mode { Foreground, Background }; unsigned int id{}; matador::object::object_ptr data; std::string type; std::string description; job_state state; job_mode mode; template void process(Operator &op) { namespace field = matador::access; field::primary_key(op, "id", id); field::belongs_to(op, "payload", data, matador::utils::CascadeNoneFetchLazy); field::attribute(op, "type", type, 511); field::attribute(op, "description", description, 511); field::attribute(op, "state", state); field::attribute(op, "mode", mode); } }; static const matador::utils::enum_mapper job_state_enum({ {job::job_state::Pending, "Pending"}, {job::job_state::Running, "Running"}, {job::job_state::Succeeded, "Succeeded"}, {job::job_state::Failed, "Failed"}, {job::job_state::Canceled, "Canceled"} }); static const matador::utils::enum_mapper job_mode_enum({ {job::job_mode::Foreground, "Foreground"}, {job::job_mode::Background, "Background"} }); template<> struct matador::utils::data_type_traits { static basic_type type(const std::size_t size) { return data_type_traits::type(size); } static void read_value(attribute_reader &reader, const char *id, const size_t index, job::job_state &value) { std::string enum_string; reader.read_value(id, index, enum_string, 64); if (const auto enum_opt = job_state_enum.to_enum(enum_string)) { value = enum_opt.value(); } } static void write_value(attribute_writer &binder, const size_t index, const job::job_state &value) { binder.write_value(index, job_state_enum.to_string(value)); } }; template<> struct matador::utils::data_type_traits { static basic_type type(const std::size_t size) { return data_type_traits::type(size); } static void read_value(attribute_reader &reader, const char *id, const size_t index, job::job_mode &value) { std::string enum_string; reader.read_value(id, index, enum_string, 64); if (const auto enum_opt = job_mode_enum.to_enum(enum_string)) { value = enum_opt.value(); } } static void bind_value(attribute_writer &binder, const size_t index, const job::job_mode &value) { binder.write_value(index, job_mode_enum.to_string(value)); } }; META_TABLE(authors, AUTHOR, id, first_name, last_name, date_of_birth, year_of_birth, distinguished) META_TABLE(books, BOOK, id, author_id, title, published_in) META_TABLE(job, JOB, id, payload, type, description, state, mode) META_TABLE(payload, PAYLOAD, id) META_TABLE(temporary_table, TEMPORARY_TABLE, id); META_TABLE(customer, CUSTOMER, id, name, email, address) META_TABLE(product, PRODUCT, id, title, description, price, category) META_TABLE(category, CATEGORY, id, title, description) META_TABLE(cart, CART, id, items, owner) int main() { using namespace matador::sql; using namespace matador::object; using namespace matador::utils; using namespace matador::query; using namespace matador::query::meta; const std::string env_var{"MATADOR_BACKENDS_PATH"}; connection_pool pool("postgres://test:test123!@127.0.0.1:5432/matador", 4); schema s(""); auto result = s.attach("authors").and_then([&s] { return s.attach("books"); }); const auto c = pool.acquire(); result = s.create(*c); if (!result) { std::cout << "error: " << result.err() << std::endl; return 0; } author mc; mc.id = 1; mc.first_name = "Michael"; mc.last_name = "Crichton"; mc.date_of_birth = "19.8.1954"; mc.year_of_birth = 1954; mc.distinguished = true; auto insert_authors_sql = query::insert() .into(AUTHOR) .values(mc) .execute(*c); if (!insert_authors_sql) { std::cout << "error: " << insert_authors_sql.err() << std::endl; std::ignore = s.drop(*c); return 0; } auto authors_result = query::select(AUTHOR) .from(AUTHOR) .fetch_all(*c); if (!authors_result) { std::cout << "error: " << authors_result.err() << std::endl; std::ignore = s.drop(*c); return 0; } for (const auto &row: *authors_result) { std::cout << "Author " << row.at(AUTHOR.first_name.canonical_name()) << "\n"; } // // auto update_authors_sql = c.query( s ) // .update( qh::authors ) // .set( {{qh::authors.first_name, "Stephen"}, // {qh::authors.last_name, "King"}} ) // .where( qh::authors.last_name == "Crichton" ) // .execute(); // // std::cout << "SQL: " << update_authors_sql << "\n"; // // auto authors = c.query( s ) // .select( qh::authors.columns ) // .from( qh::authors ) // .fetch_all(); // // for (const auto& a: authors) { std::cout << "Author " << a.first_name << "\n"; } // // c.query( s ) // .insert() // .into( qh::books ) // .values( {2, "It", mc.id, 1980} ) // .execute(); // // c.query( s ) // .insert() // .into( qh::books ) // .values( {3, "Misery", mc.id, 1984} ) // .execute(); // // auto select_books_sql = query::select( BOOK, {AUTHOR.last_name} ) auto select_books_sql = query::select({BOOK.id, BOOK.title, BOOK.author_id, BOOK.published_in, AUTHOR.last_name}) .from(BOOK) .join_left(AUTHOR) .on(BOOK.author_id == AUTHOR.id) .where(BOOK.published_in < 2008 && AUTHOR.last_name == "King") .group_by({BOOK.id, AUTHOR.last_name}) .order_by(BOOK.title).asc() .limit(5) .offset(2) .fetch_all(*c); if (!select_books_sql) { std::cout << "error: " << select_books_sql.err() << std::endl; std::ignore = s.drop(*c); return 0; } for (const auto &r: *select_books_sql) { std::cout << "R: " << r.at(BOOK.title.canonical_name()) << ", " << r.at(AUTHOR.last_name.canonical_name()) << "\n"; } result = s.drop(*c); if (!result) { std::cout << "error: " << result.err() << std::endl; return 0; } // // 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 // // OFFSET 2 LIMIT 5 // // c.query( s ).drop().table( qh::books ).execute(); // // auto drop_authors_sql = c.query( s ) // .drop() // .table( qh::authors ) // .execute(); // // std::cout << "SQL: " << drop_authors_sql << "\n"; // auto res = query::select({PAYLOAD.id}) .from(PAYLOAD) .join_left(JOB) .on(JOB.payload == PAYLOAD.id) .where( in(PAYLOAD.id, query::select({JOB.state}) .from(JOB) .where(JOB.state == job::job_state::Running).compile(c->dialect()) ) && in(PAYLOAD.id, query::select({TEMPORARY_TABLE.id}) .from(TEMPORARY_TABLE).compile(c->dialect()) ) ).compile(c->dialect()); // // .fetch_value(); std::cout << "SQL: " << res.sql << "\n"; return 0; }