Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add has_many_to_many interface #165

Merged
merged 24 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a3aee6f
added observers parameter to object_store::attach
zussel May 30, 2024
dfbdbe0
moved abstract_type to class prototype_node
zussel May 30, 2024
7727e89
added foreign_attributes class handling object relation attributes
zussel May 30, 2024
cb9731d
replaced cascade_type parameter in all has_one, belongs_to and has_ma…
zussel May 30, 2024
c6b2d47
changed log output level to trace
zussel May 31, 2024
c48e404
some changes in demo projekt
zussel May 31, 2024
8ac0058
fixed demo project
zussel Jun 2, 2024
8dab89f
folded namespaces
zussel Jun 2, 2024
ab5b53f
moved initializing data into main.cpp
zussel Jun 2, 2024
5402e89
progress on demo project
zussel Jun 3, 2024
817d0c5
introduced has_many_to_many interface to separate many-to-many from o…
zussel Jun 6, 2024
2aee53e
has-many progress, restored id to has many interface
zussel Jun 9, 2024
bb02228
added on_has_many interface for has many relations without belongs to…
zussel Jun 11, 2024
a492503
relation resolver and demo project progress
zussel Jul 10, 2024
d1b95b7
Removed unused methode "serialize" from relation_resolver
zussel Jul 11, 2024
5d1ab8f
fixed relation resolver
zussel Jul 11, 2024
4d086d5
removed unused includes
zussel Jul 11, 2024
53c2522
removed comments
zussel Jul 11, 2024
f6e228e
create an explicit logger
zussel Jul 11, 2024
dae86be
demo progress
zussel Jul 11, 2024
2184333
fixed json orm test
zussel Jul 12, 2024
1a743d2
fixed sql query test
zussel Jul 13, 2024
df8de60
fixed connection create default values
zussel Jul 13, 2024
13d4451
updated postgres to 13 in appveyor
zussel Jul 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ platform:

services:
- mssql2017
- postgresql101
- postgresql13

image: Visual Studio 2019

Expand All @@ -29,7 +29,7 @@ skip_commits:
- .github/workflows/coverage.yml

init:
- SET PATH=C:\Program Files\PostgreSQL\10\bin\;%PATH%
- SET PATH=C:\Program Files\PostgreSQL\13\bin\;%PATH%
- psql --version

branches:
Expand Down
20 changes: 13 additions & 7 deletions examples/demo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,25 @@ ENDIF()

SET (DEMO_SOURCES
main.cpp
services/auth_service.cpp
services/auth_service.hpp
models/movie.hpp
models/person.hpp
models/credential.hpp
models/user.hpp
pages/movie_page.cpp
pages/movie_page.hpp
models/movie.hpp
models/person.hpp
services/movie_service.cpp
services/movie_service.hpp pages/main_page.cpp pages/main_page.hpp
pages/main_page.cpp
pages/main_page.hpp
pages/crud_page.hpp
pages/directors_page.cpp
pages/directors_page.hpp)
pages/directors_page.hpp
services/auth_service.cpp
services/auth_service.hpp
services/movie_service.cpp
services/movie_service.hpp
services/director_service.cpp
services/director_service.hpp
converter/object_to_json_table_converter.hpp
converter/object_to_json_table_converter.cpp)

ADD_EXECUTABLE(demo ${DEMO_SOURCES})

Expand Down
30 changes: 30 additions & 0 deletions examples/demo/converter/object_to_json_table_converter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "object_to_json_table_converter.hpp"

#include <matador/utils/string.hpp>

using namespace matador;

void object_to_json_table_converter::on_primary_key(const char * /*id*/, std::string &pk, size_t /*size*/)
{
result_.push_back(create_value_information(pk, "PRIMARY_KEY"));
}

void object_to_json_table_converter::on_attribute(const char * /*id*/, bool &to, const matador::field_attributes &)
{
result_.push_back(create_value_information(to, "BOOLEAN"));
}

void object_to_json_table_converter::on_attribute(const char * /*id*/, std::string &to, const matador::field_attributes &)
{
result_.push_back(create_value_information(to, "STRING"));
}

void object_to_json_table_converter::on_attribute(const char * /*id*/, matador::date &to, const matador::field_attributes &)
{
result_.push_back(create_value_information(to_string(to), "DATE"));
}

void object_to_json_table_converter::on_attribute(const char * /*id*/, matador::time &to, const matador::field_attributes &)
{
result_.push_back(create_value_information(to_string(to), "TIME"));
}
128 changes: 128 additions & 0 deletions examples/demo/converter/object_to_json_table_converter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#ifndef MATADOR_OBJECT_TO_JSON_TABLE_CONVERTER_HPP
#define MATADOR_OBJECT_TO_JSON_TABLE_CONVERTER_HPP

#include "matador/object/object_ptr.hpp"
#include "matador/object/object_view.hpp"
#include "matador/object/object_json_attribute_extractor.hpp"

#include <matador/json/json.hpp>

class object_to_json_table_converter
{
public:
template<typename Type>
matador::json to_json_table(const matador::object_ptr<Type> &obj)
{
result_ = matador::json::object();
matador::access::process(*this, *obj);
return result_;
}

template< typename T >
matador::json to_json_table(const matador::object_view<T> &objects)
{
auto result = matador::json::array();

for (const auto &obj : objects) {
result_ = matador::json::array();
matador::access::process(*this, *obj.get());
result.push_back(result_);
}

return result;
}

template<typename Type>
[[nodiscard]] matador::json create_value_information(const Type &value, const std::string &type_name) const {
return {
{ "type", type_name },
{ "value", value }
};
}

template< class V >
void on_primary_key(const char * /*id*/, V &pk, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
{
result_.push_back(create_value_information(pk, "PRIMARY_KEY"));
}
void on_primary_key(const char *id, std::string &pk, size_t /*size*/);

void on_revision(const char * /*id*/, unsigned long long &rev)
{
result_.push_back(create_value_information(rev, "INTEGER"));
}

template < class V >
void on_attribute(const char * /*id*/, V &val, const matador::field_attributes &/*attr*/ = matador::null_attributes, typename std::enable_if<std::is_integral<V>::value && !std::is_same<V, bool>::value>::type* = 0)
{
result_.push_back(create_value_information(val, "INTEGER"));
}

template < class V >
void on_attribute(const char * /*id*/, V &val, const matador::field_attributes &/*attr*/ = matador::null_attributes, typename std::enable_if<std::is_floating_point<V>::value && !std::is_same<V, bool>::value>::type* = 0)
{
result_.push_back(create_value_information(val, "REAL"));
}

void on_attribute(const char *id, bool &to, const matador::field_attributes &/*attr*/ = matador::null_attributes);
void on_attribute(const char *id, std::string &to, const matador::field_attributes &/*attr*/ = matador::null_attributes);
void on_attribute(const char *id, matador::date &to, const matador::field_attributes &/*attr*/ = matador::null_attributes);
void on_attribute(const char *id, matador::time &to, const matador::field_attributes &/*attr*/ = matador::null_attributes);

template<class V>
void on_belongs_to(const char * /*id*/, matador::object_ptr<V> &x, const matador::foreign_attributes &/*attr*/ = matador::default_foreign_attributes)
{
if (!x.empty()) {
result_.push_back(create_value_information(extractor_.extract(x, { "id", "name"}), "ENTITY"));
}
}
template<class V>
void on_has_one(const char * /*id*/, matador::object_ptr<V> &x, const matador::foreign_attributes &/*attr*/ = matador::default_foreign_attributes)
{
if (!x.empty()) {
result_.push_back(create_value_information(extractor_.extract(x, { "id", "name"}), "ENTITY"));
}
}

template < class V, template <class ...> class Container >
void on_has_many(const char *id, matador::container<V, Container> &x, const char * /*join_column*/, const matador::foreign_attributes &/*attr*/ = matador::default_foreign_attributes)
{
handle_has_many(id, x);
}

template < class V, template <class ...> class Container >
void on_has_many(const char *id, matador::container<V, Container> &x, const matador::foreign_attributes &/*attr*/ = matador::default_foreign_attributes)
{
handle_has_many(id, x);
}

template < class V, template <class ...> class Container >
void on_has_many_to_many(const char *id, matador::container<V, Container> &x, const char *, const char *, const matador::foreign_attributes &/*attr*/ = matador::default_foreign_attributes)
{
handle_has_many(id, x);
}

template < class V, template <class ...> class Container >
void on_has_many_to_many(const char *id, matador::container<V, Container> &x, const matador::foreign_attributes &/*attr*/ = matador::default_foreign_attributes)
{
handle_has_many(id, x);
}

private:
template < class V, template <class ...> class Container >
void handle_has_many(const char *id, matador::container<V, Container> &x)
{
auto array = matador::json::array();
for (const auto &obj : x) {
array.push_back(create_value_information(extractor_.extract(obj, { "id", "name"}), "ENTITY"));
}
result_.push_back(create_value_information(array, "COLLECTION"));
}

private:
matador::object_json_attribute_extractor extractor_;
matador::json result_;
};


#endif //MATADOR_OBJECT_TO_JSON_TABLE_CONVERTER_HPP
46 changes: 41 additions & 5 deletions examples/demo/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "services/director_service.hpp"
#include "services/movie_service.hpp"

#include "pages/directors_page.hpp"
#include "pages/movie_page.hpp"
#include "pages/main_page.hpp"
Expand All @@ -12,32 +14,40 @@
#include "matador/orm/session.hpp"

#include "matador/http/http_server.hpp"
#include "matador/http/request.hpp"
#include "matador/http/static_file_service.hpp"

#include "matador/utils/os.hpp"

using namespace matador;

void initialize(matador::session &s);

int main(int /*argc*/, char* /*argv*/[])
{
try {
// setup application logging
matador::add_log_sink(matador::create_file_sink("log/server.log"));
matador::add_log_sink(matador::create_stdout_sink());

const std::string dbname = "moviedb.sqlite";
const auto initialized = os::exists(dbname);

// setup database
matador::persistence p("sqlite://moviedb.sqlite");
matador::persistence p("sqlite://" + dbname);
p.enable_log();

p.attach<person>("person");
p.attach<movie>("movie");

p.create();

// load entities
session s(p);
s.load();
p.create();

if (!initialized) {
initialize(s);
} else {
s.load();
}

// initialize network stack
net::init();
Expand All @@ -54,7 +64,9 @@ int main(int /*argc*/, char* /*argv*/[])
main_page mainpage(server, p);
movie_page moviepage(server, p);
directors_page directorpage(server, p);

movie_service mservice(server, p);
director_service dservice(server, p);

// start server
server.run();
Expand All @@ -66,3 +78,27 @@ int main(int /*argc*/, char* /*argv*/[])
}
return 0;
}

void initialize(matador::session &s) {
auto log = matador::create_logger("Initialize");
object_ptr<person> steven;
transaction tr = s.begin();
try {
steven = s.insert(new person("Steven Spielberg", date(18, 12, 1946)));
s.insert(new person("George Lucas", date(14, 5, 1944)));
tr.commit();
} catch (std::exception &ex) {
log.error("Couldn't commit transaction: %s", ex.what());
tr.rollback();
}

tr = s.begin();
try {
s.insert(new movie("Jaws", 1974, steven));
s.insert(new movie("Raiders of the lost Arc", 1984, steven));
tr.commit();
} catch (std::exception &ex) {
log.error("Couldn't commit transaction: %s", ex.what());
tr.rollback();
}
}
5 changes: 3 additions & 2 deletions examples/demo/models/credential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ struct credential
template < class Operator >
void process(Operator &op)
{
matador::access::attribute(op, "username", username, 255);
matador::access::attribute(op, "password", password, 255);
namespace field = matador::access;
field::attribute(op, "username", username, 255);
field::attribute(op, "password", password, 255);
}
};

Expand Down
13 changes: 7 additions & 6 deletions examples/demo/models/movie.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct movie
: title(std::move(t)), year(y), director(dir)
{}

unsigned long id;
unsigned long id{};
std::string title;
matador::container<e_genre> genres;
unsigned short year {};
Expand All @@ -36,12 +36,13 @@ struct movie
template < class Operator >
void process(Operator &op)
{
matador::access::primary_key(op, "id", id);
matador::access::attribute(op, "title", title, 255);
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "title", title, 255);
//serializer.serialize("genres", genres, "movie_id", "genre", matador::cascade_type::ALL);
matador::access::attribute(op, "year", year);
matador::access::has_many(op, "actors", actors, "movie_id", "actor_id", matador::cascade_type::NONE);
matador::access::has_one(op, "director", director, matador::cascade_type::NONE);
field::attribute(op, "year", year);
field::has_many_to_many(op, "actors", actors, "movie_id", "actor_id", matador::cascade_type::NONE);
field::has_one(op, "director", director, matador::cascade_type::NONE);
}
};
#endif //MATADOR_MOVIE_HPP
9 changes: 5 additions & 4 deletions examples/demo/models/person.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

struct person
{
unsigned long id;
unsigned long id{};
std::string name;
matador::date birthday;

Expand All @@ -20,9 +20,10 @@ struct person
template < class Operator >
void process(Operator &op)
{
matador::access::primary_key(op, "id", id);
matador::access::attribute(op, "name", name, 255);
matador::access::attribute(op, "birthday", birthday);
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "name", name, 255);
field::attribute(op, "birthday", birthday);
}
};

Expand Down
11 changes: 6 additions & 5 deletions examples/demo/models/user.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ struct user
template < class Operator >
void process(Operator &op)
{
matador::access::primary_key(op, "id", id);
matador::access::attribute(op, "username", username, 255);
matador::access::attribute(op, "password", password, 255);
matador::access::attribute(op, "first_name", first_name, 255);
matador::access::attribute(op, "last_name", last_name, 255);
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "username", username, 255);
field::attribute(op, "password", password, 255);
field::attribute(op, "first_name", first_name, 255);
field::attribute(op, "last_name", last_name, 255);
}
};

Expand Down
Loading
Loading