Compare commits
No commits in common. "d9f97124873f6cc0d7b38d1e0c6be0d3982bc623" and "54e6786ceb4b166178a32e00c5c6c27dff983260" have entirely different histories.
d9f9712487
...
54e6786ceb
|
|
@ -328,7 +328,7 @@ utils::result<object::object_ptr<Type>, utils::error> session::find(const Primar
|
||||||
"Failed to build query for type " + info.name() + "."));
|
"Failed to build query for type " + info.name() + "."));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto res = data->prepare(*this);
|
auto res = build_select_query(data.release()).prepare(*this);
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return utils::failure(res.err());
|
return utils::failure(res.err());
|
||||||
|
|
@ -357,7 +357,7 @@ utils::result<sql::query_result<Type>, utils::error> session::find(query::criter
|
||||||
"Failed to build query for type " + it->second.name() + "."));
|
"Failed to build query for type " + it->second.name() + "."));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = data->prepare(*this);
|
auto result = build_select_query(data.release()).prepare(*this);
|
||||||
if (!result.is_ok()) {
|
if (!result.is_ok()) {
|
||||||
return utils::failure(result.err());
|
return utils::failure(result.err());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#include "matador/query/basic_schema.hpp"
|
#include "matador/query/basic_schema.hpp"
|
||||||
#include "matador/query/intermediates/executable_query.hpp"
|
#include "matador/query/intermediates/executable_query.hpp"
|
||||||
#include "matador/query/query.hpp"
|
|
||||||
#include "matador/query/query_builder_exception.hpp"
|
|
||||||
|
|
||||||
namespace matador::query {
|
namespace matador::query {
|
||||||
class insert_query_builder {
|
class insert_query_builder {
|
||||||
|
|
@ -12,22 +10,25 @@ public:
|
||||||
explicit insert_query_builder(const basic_schema &schema);
|
explicit insert_query_builder(const basic_schema &schema);
|
||||||
|
|
||||||
template<class EntityType>
|
template<class EntityType>
|
||||||
utils::result<std::vector<executable_query>, query_build_error> build(const object::object_ptr<EntityType> &ptr) {
|
utils::result<executable_query, utils::error> build(const object::object_ptr<EntityType> &ptr) {
|
||||||
const auto it = schema_.find(typeid(EntityType));
|
|
||||||
if (it == schema_.end()) {
|
|
||||||
return utils::failure(query_build_error::UnknownType);
|
|
||||||
}
|
|
||||||
|
|
||||||
executable_query q = query::query::insert().into(it->second.table()).values(*ptr);
|
|
||||||
return utils::ok(std::vector{q});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class V >
|
template < class V >
|
||||||
static void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {}
|
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
|
||||||
static void on_revision(const char *id, uint64_t &/*rev*/);
|
push(id);
|
||||||
|
if (!is_root_entity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entity_query_data_.pk_column_name = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_revision(const char *id, uint64_t &/*rev*/);
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
static void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
||||||
|
{
|
||||||
|
push(id);
|
||||||
|
}
|
||||||
|
|
||||||
template<class Pointer>
|
template<class Pointer>
|
||||||
void on_belongs_to(const char *id, Pointer &obj, const utils::foreign_attributes &attr) {
|
void on_belongs_to(const char *id, Pointer &obj, const utils::foreign_attributes &attr) {
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ public:
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const select_query_data &query_data() const;
|
const select_query_data &query_data() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<class Pointer>
|
template<class Pointer>
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,7 @@ public:
|
||||||
* @return True if the object matches the type, false otherwise.
|
* @return True if the object matches the type, false otherwise.
|
||||||
*/
|
*/
|
||||||
template<typename MessageType>
|
template<typename MessageType>
|
||||||
[[nodiscard]] bool is() const {
|
[[nodiscard]] bool is() const { return type_ == std::type_index(typeid(MessageType)); }
|
||||||
return type_ == std::type_index(typeid(MessageType));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Accesses the stored object as a typed reference.
|
* @brief Accesses the stored object as a typed reference.
|
||||||
|
|
@ -107,14 +105,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename MessageType>
|
template<typename MessageType>
|
||||||
const MessageType& get() const {
|
const MessageType& get() const {
|
||||||
if (!is<MessageType>()) {
|
if (!is<MessageType>()) throw std::bad_cast();
|
||||||
throw std::bad_cast();
|
const void* p = raw_ptr();
|
||||||
}
|
if (!p) throw std::runtime_error("AnyMessage: empty pointer");
|
||||||
const void* ptr = raw_ptr();
|
return *static_cast<const MessageType*>(p);
|
||||||
if (!ptr) {
|
|
||||||
throw std::runtime_error("AnyMessage: empty pointer");
|
|
||||||
}
|
|
||||||
return *static_cast<const MessageType*>(ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -215,24 +209,26 @@ public:
|
||||||
* @return A subscription object to manage the handler's registration.
|
* @return A subscription object to manage the handler's registration.
|
||||||
*/
|
*/
|
||||||
template<typename MessageType>
|
template<typename MessageType>
|
||||||
subscription subscribe(std::function<void(const MessageType&)> handler, Filter<MessageType> filter = nullptr) {
|
subscription subscribe(std::function<void(const MessageType&)> handler,
|
||||||
|
Filter<MessageType> filter = nullptr)
|
||||||
|
{
|
||||||
auto id = next_id_.fetch_add(1, std::memory_order_relaxed);
|
auto id = next_id_.fetch_add(1, std::memory_order_relaxed);
|
||||||
std::unique_lock write_lock(mutex_);
|
std::unique_lock writeLock(mutex_);
|
||||||
|
|
||||||
auto &vec = handlers_[std::type_index(typeid(MessageType))];
|
auto &vec = handlers_[std::type_index(typeid(MessageType))];
|
||||||
Entry entry;
|
Entry e;
|
||||||
entry.id = id;
|
e.id = id;
|
||||||
entry.handler = [h = std::move(handler)](const void* p) {
|
e.handler = [h = std::move(handler)](const void* p) {
|
||||||
h(*static_cast<const MessageType*>(p));
|
h(*static_cast<const MessageType*>(p));
|
||||||
};
|
};
|
||||||
if (filter) {
|
if (filter) {
|
||||||
entry.filter = [f = std::move(filter)](const void* p) -> bool {
|
e.filter = [f = std::move(filter)](const void* p) -> bool {
|
||||||
return f(*static_cast<const MessageType*>(p));
|
return f(*static_cast<const MessageType*>(p));
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
entry.filter = nullptr;
|
e.filter = nullptr;
|
||||||
}
|
}
|
||||||
vec.emplace_back(std::move(entry));
|
vec.emplace_back(std::move(e));
|
||||||
return {this, std::type_index(typeid(MessageType)), id};
|
return {this, std::type_index(typeid(MessageType)), id};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,7 +245,8 @@ public:
|
||||||
template<typename MessageType, typename CallerClass>
|
template<typename MessageType, typename CallerClass>
|
||||||
subscription subscribe(CallerClass* instance,
|
subscription subscribe(CallerClass* instance,
|
||||||
MemberHandler<MessageType, CallerClass> memberFn,
|
MemberHandler<MessageType, CallerClass> memberFn,
|
||||||
Filter<MessageType> filter = nullptr) {
|
Filter<MessageType> filter = nullptr)
|
||||||
|
{
|
||||||
auto fn = [instance, memberFn](const MessageType& m) { (instance->*memberFn)(m); };
|
auto fn = [instance, memberFn](const MessageType& m) { (instance->*memberFn)(m); };
|
||||||
return subscribe<MessageType>(std::function<void(const MessageType&)>(fn), std::move(filter));
|
return subscribe<MessageType>(std::function<void(const MessageType&)>(fn), std::move(filter));
|
||||||
}
|
}
|
||||||
|
|
@ -260,28 +257,29 @@ public:
|
||||||
* @tparam MessageType The type of the message to subscribe to.
|
* @tparam MessageType The type of the message to subscribe to.
|
||||||
* @tparam CallerClass The class of the shared_ptr instance.
|
* @tparam CallerClass The class of the shared_ptr instance.
|
||||||
* @param instance A shared pointer to the instance.
|
* @param instance A shared pointer to the instance.
|
||||||
* @param member_func A pointer to the member function to execute.
|
* @param memberFn A pointer to the member function to execute.
|
||||||
* @param filter An optional filter function.
|
* @param filter An optional filter function.
|
||||||
* @return A subscription object to manage the handler's registration.
|
* @return A subscription object to manage the handler's registration.
|
||||||
*/
|
*/
|
||||||
template<typename MessageType, typename CallerClass>
|
template<typename MessageType, typename CallerClass>
|
||||||
subscription subscribe(std::shared_ptr<CallerClass> instance,
|
subscription subscribe(std::shared_ptr<CallerClass> instance,
|
||||||
MemberHandler<MessageType, CallerClass> member_func,
|
MemberHandler<MessageType, CallerClass> memberFn,
|
||||||
Filter<MessageType> filter = nullptr) {
|
Filter<MessageType> filter = nullptr)
|
||||||
std::weak_ptr<CallerClass> caller_ptr = instance;
|
{
|
||||||
auto handler = [caller_ptr, member_func](const MessageType& msg) {
|
std::weak_ptr<CallerClass> w = instance;
|
||||||
if (auto caller = caller_ptr.lock()) {
|
auto handler = [w, memberFn](const MessageType& m) {
|
||||||
(caller.get()->*member_func)(msg);
|
if (auto s = w.lock()) {
|
||||||
|
(s.get()->*memberFn)(m);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::function<bool(const MessageType&)> local_filter = nullptr;
|
std::function<bool(const MessageType&)> local_filter = nullptr;
|
||||||
if (filter) {
|
if (filter) {
|
||||||
local_filter = [caller_ptr, filter = std::move(filter)](const MessageType& msg) -> bool {
|
local_filter = [w, filter = std::move(filter)](const MessageType& m) -> bool {
|
||||||
if (caller_ptr.expired()) {
|
if (w.expired()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return filter(msg);
|
return filter(m);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return subscribe<MessageType>(std::move(handler), std::move(local_filter));
|
return subscribe<MessageType>(std::move(handler), std::move(local_filter));
|
||||||
|
|
@ -323,7 +321,7 @@ public:
|
||||||
void publish(const MessageType& msg) const {
|
void publish(const MessageType& msg) const {
|
||||||
std::vector<Entry> snapshot;
|
std::vector<Entry> snapshot;
|
||||||
{
|
{
|
||||||
std::shared_lock read_lock(mutex_);
|
std::shared_lock readLock(mutex_);
|
||||||
const auto it = handlers_.find(std::type_index(typeid(MessageType)));
|
const auto it = handlers_.find(std::type_index(typeid(MessageType)));
|
||||||
if (it == handlers_.end()) {
|
if (it == handlers_.end()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -331,9 +329,7 @@ public:
|
||||||
snapshot = it->second; // copy list to avoid holding lock during callbacks
|
snapshot = it->second; // copy list to avoid holding lock during callbacks
|
||||||
}
|
}
|
||||||
for (const auto &e : snapshot) {
|
for (const auto &e : snapshot) {
|
||||||
if (!e.filter || e.filter(&msg)) {
|
if (!e.filter || e.filter(&msg)) e.handler(&msg);
|
||||||
e.handler(&msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ add_library(matador-orm STATIC
|
||||||
../../include/matador/query/criteria_evaluator.hpp
|
../../include/matador/query/criteria_evaluator.hpp
|
||||||
../../include/matador/query/fk_value_extractor.hpp
|
../../include/matador/query/fk_value_extractor.hpp
|
||||||
../../include/matador/query/generator.hpp
|
../../include/matador/query/generator.hpp
|
||||||
../../include/matador/query/insert_query_builder.hpp
|
|
||||||
../../include/matador/query/intermediates/executable_query.hpp
|
../../include/matador/query/intermediates/executable_query.hpp
|
||||||
../../include/matador/query/intermediates/fetchable_query.hpp
|
../../include/matador/query/intermediates/fetchable_query.hpp
|
||||||
../../include/matador/query/intermediates/query_alter_intermediate.hpp
|
../../include/matador/query/intermediates/query_alter_intermediate.hpp
|
||||||
|
|
@ -116,7 +115,6 @@ add_library(matador-orm STATIC
|
||||||
query/criteria/not_criteria.cpp
|
query/criteria/not_criteria.cpp
|
||||||
query/criteria_evaluator.cpp
|
query/criteria_evaluator.cpp
|
||||||
query/generator.cpp
|
query/generator.cpp
|
||||||
query/insert_query_builder.cpp
|
|
||||||
query/intermediates/executable_query.cpp
|
query/intermediates/executable_query.cpp
|
||||||
query/intermediates/fetchable_query.cpp
|
query/intermediates/fetchable_query.cpp
|
||||||
query/intermediates/query_alter_intermediate.cpp
|
query/intermediates/query_alter_intermediate.cpp
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#include "matador/query/insert_query_builder.hpp"
|
|
||||||
|
|
||||||
namespace matador::query {
|
|
||||||
insert_query_builder::insert_query_builder(const basic_schema& schema)
|
|
||||||
: schema_(schema) {}
|
|
||||||
|
|
||||||
void insert_query_builder::on_revision(const char* /*id*/, uint64_t&) {}
|
|
||||||
} // namespace matador::query
|
|
||||||
|
|
@ -17,7 +17,6 @@ add_executable(OrmTests
|
||||||
query/ColumnGeneratorTest.cpp
|
query/ColumnGeneratorTest.cpp
|
||||||
query/CriteriaTests.cpp
|
query/CriteriaTests.cpp
|
||||||
query/GeneratorTests.cpp
|
query/GeneratorTests.cpp
|
||||||
query/InsertQueryBuilderTest.cpp
|
|
||||||
query/QueryBuilderTest.cpp
|
query/QueryBuilderTest.cpp
|
||||||
query/QueryFixture.cpp
|
query/QueryFixture.cpp
|
||||||
query/QueryFixture.hpp
|
query/QueryFixture.hpp
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
#include <catch2/catch_test_macros.hpp>
|
|
||||||
|
|
||||||
#include "matador/object/object_ptr.hpp"
|
|
||||||
|
|
||||||
#include "matador/sql/backend_provider.hpp"
|
|
||||||
#include "matador/sql/connection.hpp"
|
|
||||||
#include "matador/sql/interface/connection_impl.hpp"
|
|
||||||
|
|
||||||
#include "matador/query/schema.hpp"
|
|
||||||
|
|
||||||
#include "matador/query/insert_query_builder.hpp"
|
|
||||||
|
|
||||||
#include "../backend/test_backend_service.hpp"
|
|
||||||
|
|
||||||
#include "../../models/airplane.hpp"
|
|
||||||
#include "../../models/flight.hpp"
|
|
||||||
|
|
||||||
using namespace matador::object;
|
|
||||||
using namespace matador::sql;
|
|
||||||
using namespace matador::query;
|
|
||||||
using namespace matador::utils;
|
|
||||||
|
|
||||||
TEST_CASE("insert query builder test", "[query][insert_query_builder]") {
|
|
||||||
using namespace matador::test;
|
|
||||||
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
|
|
||||||
connection db("noop://noop.db");
|
|
||||||
|
|
||||||
schema scm;
|
|
||||||
auto result = scm.attach<airplane>("airplanes")
|
|
||||||
.and_then( [&scm] { return scm.attach<flight>("flights"); } );
|
|
||||||
REQUIRE(result);
|
|
||||||
|
|
||||||
insert_query_builder iqb(scm);
|
|
||||||
|
|
||||||
const auto a380 = object_ptr(std::make_shared<airplane>(1, "Boeing", "A380" ));
|
|
||||||
auto build_result = iqb.build<airplane>(a380);
|
|
||||||
REQUIRE(build_result.is_ok());
|
|
||||||
|
|
||||||
const auto& stmts = *build_result;
|
|
||||||
REQUIRE(stmts.size() == 1);
|
|
||||||
|
|
||||||
const auto sql = stmts.front().str(db);
|
|
||||||
REQUIRE(sql == R"(INSERT INTO "airplanes" ("id", "brand", "model") VALUES (1, 'Boeing', 'A380'))");
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue