Browse Source

* Refactored modifier implementation

refactoring
bergmann 4 years ago
parent
commit
ffb804d776
42 changed files with 1233 additions and 857 deletions
  1. +1
    -0
      include/cpphibernate.h
  2. +18
    -0
      include/cpphibernate/modifier.h
  3. +21
    -22
      include/cpphibernate/modifier/limit.h
  4. +50
    -0
      include/cpphibernate/modifier/limit.inl
  5. +12
    -21
      include/cpphibernate/modifier/modifier.h
  6. +25
    -0
      include/cpphibernate/modifier/modifier.inl
  7. +21
    -48
      include/cpphibernate/modifier/modifiers.h
  8. +63
    -0
      include/cpphibernate/modifier/modifiers.inl
  9. +21
    -22
      include/cpphibernate/modifier/offset.h
  10. +50
    -0
      include/cpphibernate/modifier/offset.inl
  11. +20
    -153
      include/cpphibernate/modifier/order_by.h
  12. +54
    -0
      include/cpphibernate/modifier/order_by.inl
  13. +38
    -0
      include/cpphibernate/modifier/order_by/ascending.h
  14. +49
    -0
      include/cpphibernate/modifier/order_by/ascending.inl
  15. +38
    -0
      include/cpphibernate/modifier/order_by/descending.h
  16. +47
    -0
      include/cpphibernate/modifier/order_by/descending.inl
  17. +22
    -0
      include/cpphibernate/modifier/order_by/order_direction.h
  18. +37
    -0
      include/cpphibernate/modifier/order_by/order_direction.inl
  19. +36
    -2
      include/cpphibernate/modifier/where.h
  20. +59
    -0
      include/cpphibernate/modifier/where.inl
  21. +0
    -7
      include/cpphibernate/modifier/where/clauses.h
  22. +0
    -60
      include/cpphibernate/modifier/where/clauses/and.h
  23. +0
    -31
      include/cpphibernate/modifier/where/clauses/clause.h
  24. +0
    -64
      include/cpphibernate/modifier/where/clauses/equal.h
  25. +0
    -60
      include/cpphibernate/modifier/where/clauses/not.h
  26. +0
    -60
      include/cpphibernate/modifier/where/clauses/or.h
  27. +59
    -0
      include/cpphibernate/modifier/where/conjunction.h
  28. +69
    -0
      include/cpphibernate/modifier/where/conjunction.inl
  29. +59
    -0
      include/cpphibernate/modifier/where/disjunction.h
  30. +69
    -0
      include/cpphibernate/modifier/where/disjunction.inl
  31. +38
    -0
      include/cpphibernate/modifier/where/equal.h
  32. +64
    -0
      include/cpphibernate/modifier/where/equal.inl
  33. +59
    -0
      include/cpphibernate/modifier/where/negation.h
  34. +67
    -0
      include/cpphibernate/modifier/where/negation.inl
  35. +0
    -60
      include/cpphibernate/modifier/where/where.h
  36. +22
    -0
      include/cpphibernate/modifier/where/where_clause.h
  37. +25
    -0
      include/cpphibernate/modifier/where/where_clause.inl
  38. +1
    -1
      include/cpphibernate/schema/attributes.inl
  39. +1
    -1
      include/cpphibernate/schema/fields.inl
  40. +1
    -1
      include/cpphibernate/schema/tables.inl
  41. +17
    -8
      test/cpphibernate/cpphibernate_tests.cpp
  42. +0
    -236
      test/test_schema.h

+ 1
- 0
include/cpphibernate.h View File

@@ -1,5 +1,6 @@
#pragma once

#include "cpphibernate/misc.h"
#include "cpphibernate/modifier.h"
#include "cpphibernate/schema.h"
#include "cpphibernate/types.h"

+ 18
- 0
include/cpphibernate/modifier.h View File

@@ -0,0 +1,18 @@
#pragma once

#include "modifier/modifier.h"
#include "modifier/modifiers.h"

#include "modifier/limit.h"
#include "modifier/offset.h"

#include "modifier/order_by.h"
#include "modifier/order_by/ascending.h"
#include "modifier/order_by/descending.h"

#include "modifier/where.h"
#include "modifier/where/where_clause.h"
#include "modifier/where/equal.h"
#include "modifier/where/negation.h"
#include "modifier/where/conjunction.h"
#include "modifier/where/disjunction.h"

+ 21
- 22
include/cpphibernate/modifier/limit.h View File

@@ -1,39 +1,38 @@
#pragma once

#include <cpphibernate/misc.h>
#include <cpphibernate/config.h>
#include <cpphibernate/modifier/modifier.h>

beg_namespace_cpphibernate_modifier
namespace cpphibernate
{

namespace __impl
{

/* limit_t */

template<typename T_value>
struct limit_t
: public modifier_t
{
using value_type = T_value;

value_type value;
};
/**
* @brief Helper class to build limit objects.
*/
template<typename X, typename = void>
struct limit_builder;

}

/* meta */

/**
* @brief Evaluates to true_t if the passed type is a limit modifier, false_t otherwise.
*/
template<typename T>
struct is_limit_modifier
: public mp::is_specialization_of<T, __impl::limit_t>
{ };
struct is_limit_modifier;

/* make */
/**
* @brief Is true if the passed type is a limit modifier, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_limit_modifier_v = is_limit_modifier<T>::value;

template<size_t T_value>
constexpr decltype(auto) limit = __impl::limit_t<hana::size_t<T_value>> { };
/**
* @brief Predicate to create new limit objects.
*/
constexpr decltype(auto) limit = mp::generic_predicate<__impl::limit_builder> { };

}
end_namespace_cpphibernate_modifier

#include "limit.inl"

+ 50
- 0
include/cpphibernate/modifier/limit.inl View File

@@ -0,0 +1,50 @@
#pragma once

#include "limit.h"

namespace cpphibernate
{

namespace __impl
{

/* limit_t */

template<typename T_value>
struct limit_t
: public mp::size_t<T_value::value>
, public tag_modifier
, public tag_equality_comparable<tag_modifier>
{ };

/* limit_builder */

template<typename X, typename>
struct limit_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&...)
{ static_assert(sizeof...(T_args) == -1, "Invalid parameters for limit(...)!"); }
};

template<typename T>
struct limit_builder<
mp::list<T>,
mp::enable_if_t<
mp::is_valid_v<decltype(T::value)>
&& mp::is_integral_v<mp::decay_t<decltype(T::value)>>>>
{
static constexpr decltype(auto) apply(T&&)
{ return limit_t<T> { }; }
};

}

/* is_limit_modifier */

template<typename T>
struct is_limit_modifier
: public mp::is_specialization_of<T, __impl::limit_t>
{ };

}

+ 12
- 21
include/cpphibernate/modifier/modifier.h View File

@@ -2,30 +2,21 @@

#include <cpphibernate/config.h>

beg_namespace_cpphibernate_modifier
namespace cpphibernate
{

namespace __impl
{

/* modifier_t */

struct modifier_t
{ };

}

/* meta */

/**
* @brief Evaluates to true_t if the passed type is a modifier, false_t otherwise.
*/
template<typename T>
struct is_modifier
: public mp::is_base_of<__impl::modifier_t, T>
{ };
struct is_modifier;

template<typename... T>
struct all_are_modifiers
: public mp::all_true<is_modifier<T>::value...>
{ };
/**
* @brief Is true if the passed type is a modifier, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_modifier_v = is_modifier<T>::value;

}
end_namespace_cpphibernate_modifier

#include "modifier.inl"

+ 25
- 0
include/cpphibernate/modifier/modifier.inl View File

@@ -0,0 +1,25 @@
#pragma once

#include "modifier.h"

namespace cpphibernate
{

namespace __impl
{

/* tag_modifier */

struct tag_modifier
{ };

}

/* is_modifier */

template<typename T>
struct is_modifier
: public mp::is_base_of<__impl::tag_modifier, T>
{ };

}

+ 21
- 48
include/cpphibernate/modifier/modifiers.h View File

@@ -1,65 +1,38 @@
#pragma once

#include <cpphibernate/misc.h>
#include <cpphibernate/config.h>
#include <cpphibernate/modifier/modifier.h>

beg_namespace_cpphibernate_modifier
{
namespace cpphibernate {
namespace schema {

namespace __impl
{

/* is_modifiers_impl */

/**
* @brief Helper type to build modifiers.
*/
template<typename T, typename = void>
struct is_modifiers_impl
: mp::c_false_t
{ };

template<typename... T>
struct is_modifiers_impl<hana::basic_tuple<T...>, mp::enable_if<all_are_modifiers<T...>>>
: mp::c_true_t
{ };
struct modifiers_builder;

}

/* meta */

/**
* @brief Evaluates to true_t if the passed type is a modifiers type.
*/
template<typename T>
struct is_modifiers
: public __impl::is_modifiers_impl<T>
{ };

/* operations */

namespace __impl
{

/* make_modifiers_impl */

template<typename T, typename = void>
struct make_modifiers_impl
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&...)
{ static_assert(sizeof...(T_args) == -1, "Invalid parameters for hibernate::schema::modifier::make(...)!"); }
};
struct is_modifiers;

template<typename... T>
struct make_modifiers_impl<
mp::list<T...>,
mp::enable_if_c<
all_are_modifiers<mp::decay_t<T>...>::value>>
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ return hana::make_basic_tuple(std::forward<T_args>(args)...); }
};
/**
* @brief Is true if the passed type is an modifiers type, false otherwise.
*/
template<typename T>
constexpr bool is_modifiers_v = is_modifiers<T>::value;

}
/**
* @brief Predicate to create an modifiers object from the passed modifiers.
*/
constexpr decltype(auto) make_modifiers = mp::generic_predicate<__impl::modifiers_builder> { };

constexpr decltype(auto) make_list = misc::make_generic_predicate<__impl::make_modifiers_impl> { };
} }

}
end_namespace_cpphibernate_modifier
#include "modifiers.inl"

+ 63
- 0
include/cpphibernate/modifier/modifiers.inl View File

@@ -0,0 +1,63 @@
#pragma once

#include "modifier.h"
#include "modifiers.h"

namespace cpphibernate {
namespace schema {

namespace __impl
{

/* modifiers_t */

template<typename... T_modifiers>
using modifiers_t = hana::basic_tuple<T_modifiers...>;

/* modifiers_builder */

template<typename T, typename>
struct modifiers_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&...)
{ static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_modifiers(...)!"); }
};

template<typename... T_args>
struct modifiers_builder<
mp::list<T_args...>,
mp::enable_if_t<
mp::is_true_v<is_modifier_v<mp::decay_t<T_args>>...>>>
{
static constexpr decltype(auto) apply(T_args&&... args)
{
using modifiers_type = modifiers_t<T_args...>;
return modifiers_type(std::forward<T_args>(args)...);
}
};

/* is_modifiers_impl */

template<typename T, typename = void>
struct is_modifiers_impl
: mp::false_t
{ };

template<typename... T>
struct is_modifiers_impl<
modifiers_t<T...>,
mp::enable_if_t<mp::is_true_v<is_modifier_v<mp::decay_t<T>>...>>>
: mp::true_t
{ };

}

/* is_modifiers */

template<typename T>
struct is_modifiers
: public __impl::is_modifiers_impl<T>
{ };

} }

+ 21
- 22
include/cpphibernate/modifier/offset.h View File

@@ -1,39 +1,38 @@
#pragma once

#include <cpphibernate/misc.h>
#include <cpphibernate/config.h>
#include <cpphibernate/modifier/modifier.h>

beg_namespace_cpphibernate_modifier
namespace cpphibernate
{

namespace __impl
{

/* offset_t */

template<typename T_value>
struct offset_t
: public modifier_t
{
using value_type = T_value;

value_type value;
};
/**
* @brief Helper class to build offset objects.
*/
template<typename X, typename = void>
struct offset_builder;

}

/* meta */

/**
* @brief Evaluates to true_t if the passed type is a offset modifier, false_t otherwise.
*/
template<typename T>
struct is_offset
: public mp::is_specialization_of<T, __impl::offset_t>
{ };
struct is_offset_modifier;

/* make */
/**
* @brief Is true if the passed type is a offset modifier, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_offset_modifier_v = is_offset_modifier<T>::value;

template<size_t T_value>
constexpr decltype(auto) offset = __impl::offset_t<hana::size_t<T_value>> { };
/**
* @brief Predicate to create new offset objects.
*/
constexpr decltype(auto) offset = mp::generic_predicate<__impl::offset_builder> { };

}
end_namespace_cpphibernate_modifier

#include "offset.inl"

+ 50
- 0
include/cpphibernate/modifier/offset.inl View File

@@ -0,0 +1,50 @@
#pragma once

#include "offset.h"

namespace cpphibernate
{

namespace __impl
{

/* offset_t */

template<typename T_value>
struct offset_t
: public mp::size_t<T_value::value>
, public tag_modifier
, public tag_equality_comparable<tag_modifier>
{ };

/* offset_builder */

template<typename X, typename>
struct offset_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&...)
{ static_assert(sizeof...(T_args) == -1, "Invalid parameters for offset(...)!"); }
};

template<typename T>
struct offset_builder<
mp::list<T>,
mp::enable_if_t<
mp::is_valid_v<decltype(T::value)>
&& mp::is_integral_v<mp::decay_t<decltype(T::value)>>>>
{
static constexpr decltype(auto) apply(T&&)
{ return offset_t<T> { }; }
};

}

/* is_offset_modifier */

template<typename T>
struct is_offset_modifier
: public mp::is_specialization_of<T, __impl::offset_t>
{ };

}

+ 20
- 153
include/cpphibernate/modifier/order_by.h View File

@@ -1,171 +1,38 @@
#pragma once

#include <cpphibernate/misc.h>
#include <cpphibernate/config.h>
#include <cpphibernate/modifier/modifier.h>

beg_namespace_cpphibernate_modifier
namespace cpphibernate
{

namespace __impl
{

/* order_direction_tag_t */

struct order_direction_tag_t
{ };

/* order_direction_t */

template<typename T_field>
struct order_direction_t
: public order_direction_tag_t
{
using field_type = T_field;
using wrapped_field_type = hana::type<mp::decay_t<field_type>>;

wrapped_field_type wrapped_field;
};
/**
* @brief Helper class to build order_by objects.
*/
template<typename X, typename = void>
struct order_by_builder;

}

/* meta */

/**
* @brief Evaluates to true_t if the passed type is a offset modifier, false_t otherwise.
*/
template<typename T>
struct is_order_direction
: public mp::is_base_of<__impl::order_direction_tag_t, T>
{ };

template<typename... T>
struct all_are_order_directions
: public mp::all_true<is_order_direction<T>::value...>
{ };

namespace __impl
{

/* order_ascending_t */

template<typename T_field>
struct order_ascending_t
: public order_direction_t<T_field>
{ };

/* order_descending_t */

template<typename T_field>
struct order_descending_t
: public order_direction_t<T_field>
{ };

/* order_by_t */

template<typename... T_fields>
struct order_by_t
: public modifier_t
{
using fields_type = hana::basic_tuple<T_fields...>;

fields_type fields;
};

}

/* meta */
struct is_order_by_modifier;

/**
* @brief Is true if the passed type is a offset modifier, false otherwise.
*/
template<typename T>
struct is_order_by
: public mp::is_specialization_of<T, __impl::order_by_t>
{ };
constexpr decltype(auto) is_order_by_modifier_v = is_order_by_modifier<T>::value;

template<typename T>
struct is_ascending
: public mp::is_specialization_of<T, __impl::order_ascending_t>
{ };

template<typename T>
struct is_descending
: public mp::is_specialization_of<T, __impl::order_descending_t>
{ };

namespace __impl
{

/* ascending_builder */

template<typename X, typename = void>
struct ascending_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::ascending(...)!"); }
};

template<typename T_field>
struct ascending_builder<
mp::list<T_field>,
mp::enable_if<schema::is_field<mp::decay_t<T_field>>>>
{
static constexpr decltype(auto) apply(T_field&&)
{
using field_type = mp::decay_t<T_field>;
using ascending_type = order_ascending_t<field_type>;
return ascending_type { };
}
};

/* descending_builder */

template<typename X, typename = void>
struct descending_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::descending(...)!"); }
};

template<typename T_field>
struct descending_builder<
mp::list<T_field>,
mp::enable_if<schema::is_field<mp::decay_t<T_field>>>>
{
static constexpr decltype(auto) apply(T_field&&)
{
using field_type = mp::decay_t<T_field>;
using descending_type = order_descending_t<field_type>;
return descending_type { };
}
};

/* order_by_builder */

template<typename X, typename = void>
struct order_by_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::order_by(...)!"); }
};

template<typename... T_order_directions>
struct order_by_builder<
mp::list<T_order_directions...>,
mp::enable_if<all_are_order_directions<mp::decay_t<T_order_directions>...>>>
{
static constexpr decltype(auto) apply(T_order_directions&&...)
{
using order_by_type = order_by_t<mp::decay_t<T_order_directions>...>;
return order_by_type { };
}
};

}

/* make */

constexpr decltype(auto) ascending = misc::make_generic_predicate<__impl::ascending_builder> { };
constexpr decltype(auto) descending = misc::make_generic_predicate<__impl::descending_builder> { };
constexpr decltype(auto) order_by = misc::make_generic_predicate<__impl::order_by_builder> { };
/**
* @brief Predicate to create new offset objects.
*/
constexpr decltype(auto) order_by = mp::generic_predicate<__impl::order_by_builder> { };

}
end_namespace_cpphibernate_modifier

#include "order_by.inl"

+ 54
- 0
include/cpphibernate/modifier/order_by.inl View File

@@ -0,0 +1,54 @@
#pragma once

#include "order_by.h"
#include "order_by/order_direction.h"

namespace cpphibernate
{

namespace __impl
{

/* order_by_t */

template<typename... T_order_directions>
struct order_by_t
: public tag_modifier
{
using order_directions_type = hana::basic_tuple<T_order_directions...>;

order_directions_type order_directions;
};

/* order_by_builder */

template<typename X, typename>
struct order_by_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&...)
{ static_assert(sizeof...(T_args) == -1, "Invalid parameters for order_by(...)!"); }
};

template<typename... T_order_directions>
struct order_by_builder<
mp::list<T_order_directions...>,
mp::enable_if_t<mp::is_true_v<is_order_direction_v<mp::decay_t<T_order_directions>>...>>>
{
static constexpr decltype(auto) apply(T_order_directions&&...)
{
using order_by_type = order_by_t<mp::decay_t<T_order_directions>...>;
return order_by_type { };
}
};

}

/* is_order_by_modifier */

template<typename T>
struct is_order_by_modifier
: public mp::is_specialization_of<T, __impl::order_by_t>
{ };

}

+ 38
- 0
include/cpphibernate/modifier/order_by/ascending.h View File

@@ -0,0 +1,38 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

namespace __impl
{

/**
* @brief Helper class to build ascending objects.
*/
template<typename X, typename = void>
struct ascending_builder;

}

/**
* @brief Evaluates to true_t if the passed type is a ascending order, false_t otherwise.
*/
template<typename T>
struct is_ascending;

/**
* @brief Is true if the passed type is a ascending order, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_ascending_v = is_ascending<T>::value;

/**
* @brief Predicate to create new ascending order objects.
*/
constexpr decltype(auto) ascending = mp::generic_predicate<__impl::ascending_builder> { };

}

#include "ascending.inl"

+ 49
- 0
include/cpphibernate/modifier/order_by/ascending.inl View File

@@ -0,0 +1,49 @@
#pragma once

#include <cpphibernate/schema/field.h>

#include "ascending.h"
#include "order_direction.h"

namespace cpphibernate
{

namespace __impl
{

/* ascending_t */

template<typename T_field>
struct ascending_t
: public order_direction_t<T_field>
{ };

/* ascending_builder */

template<typename X, typename>
struct ascending_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::ascending(...)!"); }
};

template<typename T_field>
struct ascending_builder<
mp::list<T_field>,
mp::enable_if_t<schema::is_field_v<mp::decay_t<T_field>>>>
{
static constexpr decltype(auto) apply(T_field&&)
{ return ascending_t<T_field> { }; }
};

}

/* is_ascending */

template<typename T>
struct is_ascending
: public mp::is_specialization_of<T, __impl::ascending_t>
{ };

}

+ 38
- 0
include/cpphibernate/modifier/order_by/descending.h View File

@@ -0,0 +1,38 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

namespace __impl
{

/**
* @brief Helper class to build descending objects.
*/
template<typename X, typename = void>
struct descending_builder;

}

/**
* @brief Evaluates to true_t if the passed type is a descending order, false_t otherwise.
*/
template<typename T>
struct is_descending;

/**
* @brief Is true if the passed type is a descending order, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_descending_v = is_descending<T>::value;

/**
* @brief Predicate to create new descending order objects.
*/
constexpr decltype(auto) descending = mp::generic_predicate<__impl::descending_builder> { };

}

#include "descending.inl"

+ 47
- 0
include/cpphibernate/modifier/order_by/descending.inl View File

@@ -0,0 +1,47 @@
#pragma once

#include "descending.h"
#include "order_direction.h"

namespace cpphibernate
{

namespace __impl
{

/* descending_t */

template<typename T_field>
struct descending_t
: public order_direction_t<T_field>
{ };

/* descending_builder */

template<typename X, typename>
struct descending_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::descending(...)!"); }
};

template<typename T_field>
struct descending_builder<
mp::list<T_field>,
mp::enable_if_t<schema::is_field_v<mp::decay_t<T_field>>>>
{
static constexpr decltype(auto) apply(T_field&&)
{ return descending_t<T_field> { }; }
};

}

/* is_descending */

template<typename T>
struct is_descending
: public mp::is_specialization_of<T, __impl::descending_t>
{ };

}

+ 22
- 0
include/cpphibernate/modifier/order_by/order_direction.h View File

@@ -0,0 +1,22 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

/**
* @brief Evaluates to true_t if the passed type is a order_direction, false_t otherwise.
*/
template<typename T>
struct is_order_direction;

/**
* @brief Is true if the passed type is a order_direction, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_order_direction_v = is_order_direction<T>::value;

}

#include "order_direction.inl"

+ 37
- 0
include/cpphibernate/modifier/order_by/order_direction.inl View File

@@ -0,0 +1,37 @@
#pragma once

#include "order_direction.h"

namespace cpphibernate
{

namespace __impl
{

/* tag_order_direction */

struct tag_order_direction
{ };

/* order_direction_t */

template<typename T_field>
struct order_direction_t
: public tag_order_direction
{
using field_type = T_field;
using wrapped_field_type = hana::type<mp::decay_t<field_type>>;

wrapped_field_type wrapped_field;
};

}

/* is_order_direction */

template<typename T>
struct is_order_direction
: public mp::is_base_of<__impl::tag_order_direction, T>
{ };

}

+ 36
- 2
include/cpphibernate/modifier/where.h View File

@@ -1,4 +1,38 @@
#pragma once

#include <cpphibernate/modifier/where/clauses.h>
#include <cpphibernate/modifier/where/where.h>
#include <cpphibernate/config.h>

namespace cpphibernate
{

namespace __impl
{

/**
* @brief Helper class to build where objects.
*/
template<typename X, typename = void>
struct where_builder;

}

/**
* @brief Evaluates to true_t if the passed type is a where modifier, false_t otherwise.
*/
template<typename T>
struct is_where_modifier;

/**
* @brief Is true if the passed type is a where modifier, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_where_modifier_v = is_where_modifier<T>::value;

/**
* @brief Predicate to create new where objects.
*/
constexpr decltype(auto) where = mp::generic_predicate<__impl::where_builder> { };

}

#include "where.inl"

+ 59
- 0
include/cpphibernate/modifier/where.inl View File

@@ -0,0 +1,59 @@
#pragma once

#include "where.h"
#include "where/where_clause.h"

namespace cpphibernate
{

namespace __impl
{

/* where_t */

template<typename T_where_clause>
struct where_t
: public tag_modifier
{
using clause_type = T_where_clause;

clause_type clause;

constexpr where_t(clause_type&& p_clause)
: clause(p_clause)
{ }
};

/* where_builder */

template<typename X, typename>
struct where_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&...)
{ static_assert(sizeof...(T_args) == -1, "Invalid parameters for where(...)!"); }
};

template<typename T_where_clause>
struct where_builder<
mp::list<T_where_clause>,
mp::enable_if_t<mp::is_true_v<is_where_clause_v<mp::decay_t<T_where_clause>>>>>
{
static constexpr decltype(auto) apply(T_where_clause&& clause)
{
using clause_type = T_where_clause;
using where_type = where_t<clause_type>;
return where_type(std::forward<clause_type>(clause));
}
};

}

/* is_where_modifier */

template<typename T>
struct is_where_modifier
: public mp::is_specialization_of<T, __impl::where_t>
{ };

}

+ 0
- 7
include/cpphibernate/modifier/where/clauses.h View File

@@ -1,7 +0,0 @@
#pragma once

#include <cpphibernate/modifier/where/clauses/and.h>
#include <cpphibernate/modifier/where/clauses/clause.h>
#include <cpphibernate/modifier/where/clauses/equal.h>
#include <cpphibernate/modifier/where/clauses/not.h>
#include <cpphibernate/modifier/where/clauses/or.h>

+ 0
- 60
include/cpphibernate/modifier/where/clauses/and.h View File

@@ -1,60 +0,0 @@
#pragma once

#include <cpphibernate/config.h>
#include <cpphibernate/modifier/where/clauses/clause.h>

beg_namespace_cpphibernate_modifier
{

namespace __impl
{

/* where_clause_and_t */

template<typename... T_clauses>
struct where_clause_and_t
: public where_clause_t
{
using clauses_type = hana::tuple<T_clauses...>;

clauses_type clauses;

constexpr where_clause_and_t(T_clauses&&... p_clauses)
: clauses(std::forward<T_clauses>(p_clauses)...)
{ }
};

/* where_clause_and_builder */

template<typename X, typename = void>
struct where_clause_and_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::and(...)!"); }
};

template<typename... T_clauses>
struct where_clause_and_builder<
mp::list<T_clauses...>,
mp::enable_if<all_are_where_clauses<mp::decay_t<T_clauses>...>>>
{
static constexpr decltype(auto) apply(T_clauses&&... clauses)
{ return where_clause_and_t<T_clauses...>(std::forward<T_clauses>(clauses)...); }
};

}

/* meta */

template<typename T>
struct is_where_clause_and
: public mp::is_specialization_of<T, __impl::where_clause_and_t>
{ };

/* make */

constexpr decltype(auto) and_ = misc::make_generic_predicate<__impl::where_clause_and_builder> { };

}
end_namespace_cpphibernate_modifier

+ 0
- 31
include/cpphibernate/modifier/where/clauses/clause.h View File

@@ -1,31 +0,0 @@
#pragma once

#include <cpphibernate/config.h>

beg_namespace_cpphibernate_modifier
{

namespace __impl
{

/* where_clause_t */

struct where_clause_t
{ };

}

/* meta */

template<typename T>
struct is_where_clause
: public mp::is_base_of<__impl::where_clause_t, T>
{ };

template<typename... T>
struct all_are_where_clauses
: public mp::all_true<is_where_clause<T>::value...>
{ };

}
end_namespace_cpphibernate_modifier

+ 0
- 64
include/cpphibernate/modifier/where/clauses/equal.h View File

@@ -1,64 +0,0 @@
#pragma once

#include <cpphibernate/config.h>
#include <cpphibernate/schema/field.h>
#include <cpphibernate/modifier/where/clauses/clause.h>

beg_namespace_cpphibernate_modifier
{

namespace __impl
{

/* where_clause_equal_t */

template<typename T_field, typename T_value>
struct where_clause_equal_t
: public where_clause_t
{
using field_type = T_field;
using value_type = T_value;

field_type field;
value_type value;

constexpr where_clause_equal_t(T_field&& p_field, T_value&& p_value)
: field(std::forward<T_field>(p_field))
, value(std::forward<T_value>(p_value))
{ }
};

/* where_clause_equal_builder */

template<typename X, typename = void>
struct where_clause_equal_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::equal(...)!"); }
};

template<typename T_field, typename T_value>
struct where_clause_equal_builder<
mp::list<T_field, T_value>,
mp::enable_if<schema::is_field<mp::decay_t<T_field>>>>
{
static constexpr decltype(auto) apply(T_field&& field, T_value&& value)
{ return where_clause_equal_t<T_field, T_value>(std::forward<T_field>(field), std::forward<T_value>(value)); }
};

}

/* meta */

template<typename T>
struct is_where_clause_equal
: public mp::is_specialization_of<T, __impl::where_clause_equal_t>
{ };

/* make */

constexpr decltype(auto) equal = misc::make_generic_predicate<__impl::where_clause_equal_builder> { };

}
end_namespace_cpphibernate_modifier

+ 0
- 60
include/cpphibernate/modifier/where/clauses/not.h View File

@@ -1,60 +0,0 @@
#pragma once

#include <cpphibernate/config.h>
#include <cpphibernate/modifier/where/clauses/clause.h>

beg_namespace_cpphibernate_modifier
{

namespace __impl
{

/* where_clause_not_t */

template<typename T_clause>
struct where_clause_not_t
: public where_clause_t
{
using clause_type = T_clause;

clause_type clause;

constexpr where_clause_not_t(T_clause&& p_clause)
: clause(std::forward<T_clause>(p_clause))
{ }
};

/* where_clause_not_builder */

template<typename X, typename = void>
struct where_clause_not_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::not(...)!"); }
};

template<typename T_clause>
struct where_clause_not_builder<
mp::list<T_clause>,
mp::enable_if<is_where_clause<mp::decay_t<T_clause>>>>
{
static constexpr decltype(auto) apply(T_clause&& clause)
{ return where_clause_not_t<T_clause>(std::forward<T_clause>(clause)); }
};

}

/* meta */

template<typename T>
struct is_where_clause_not
: public mp::is_specialization_of<T, __impl::where_clause_not_t>
{ };

/* make */

constexpr decltype(auto) not_ = misc::make_generic_predicate<__impl::where_clause_not_builder> { };

}
end_namespace_cpphibernate_modifier

+ 0
- 60
include/cpphibernate/modifier/where/clauses/or.h View File

@@ -1,60 +0,0 @@
#pragma once

#include <cpphibernate/config.h>
#include <cpphibernate/modifier/where/clauses/clause.h>

beg_namespace_cpphibernate_modifier
{

namespace __impl
{

/* where_clause_or_t */

template<typename... T_clauses>
struct where_clause_or_t
: public where_clause_t
{
using clauses_type = hana::tuple<T_clauses...>;

clauses_type clauses;

constexpr where_clause_or_t(T_clauses&&... p_clauses)
: clauses(std::forward<T_clauses>(p_clauses)...)
{ }
};

/* where_clause_or_builder */

template<typename X, typename = void>
struct where_clause_or_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::or(...)!"); }
};

template<typename... T_clauses>
struct where_clause_or_builder<
mp::list<T_clauses...>,
mp::enable_if<all_are_where_clauses<mp::decay_t<T_clauses>...>>>
{
static constexpr decltype(auto) apply(T_clauses&&... clauses)
{ return where_clause_or_t<T_clauses...>(std::forward<T_clauses>(clauses)...); }
};

}

/* meta */

template<typename T>
struct is_where_clause_or
: public mp::is_specialization_of<T, __impl::where_clause_or_t>
{ };

/* make */

constexpr decltype(auto) or_ = misc::make_generic_predicate<__impl::where_clause_or_builder> { };

}
end_namespace_cpphibernate_modifier

+ 59
- 0
include/cpphibernate/modifier/where/conjunction.h View File

@@ -0,0 +1,59 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

namespace __impl
{

/**
* @brief Helper class to build conjunction objects.
*/
template<typename X, typename = void>
struct conjunction_builder;

}



/**
* @brief Evaluates to true_t if the passed type is a conjunction clause, false_t otherwise.
*/
template<typename T>
struct is_conjunction;

/**
* @brief Is true if the passed type is a conjunction clause, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_conjunction_v = is_conjunction<T>::value;

/**
* @brief Predicate to create new conjunction clause objects.
*/
constexpr decltype(auto) conjunction = mp::generic_predicate<__impl::conjunction_builder> { };



/**
* @brief Evaluates to true_t if the passed type is a conjunction clause, false_t otherwise.
*/
template<typename T>
struct is_and;

/**
* @brief Is true if the passed type is a conjunction clause, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_and_v = is_and<T>::value;

/**
* @brief Predicate to create new conjunction clause objects.
*/
constexpr decltype(auto) and_ = mp::generic_predicate<__impl::conjunction_builder> { };

}

#include "conjunction.inl"

+ 69
- 0
include/cpphibernate/modifier/where/conjunction.inl View File

@@ -0,0 +1,69 @@
#pragma once

#include <cpphibernate/schema/field.h>

#include "conjunction.h"

namespace cpphibernate
{

namespace __impl
{

/* where_clause_conjunction_t */

template<typename... T_clauses>
struct where_clause_conjunction_t
: public tag_where_clause
{
using clauses_type = hana::basic_tuple<T_clauses...>;

clauses_type clauses;

constexpr where_clause_conjunction_t(
T_clauses&&... p_clauses)
: clauses(std::forward<T_clauses>(p_clauses)...)
{ }
};

/* conjunction_builder */

template<typename X, typename>
struct conjunction_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::conjunction(...)!"); }
};

template<typename... T_clauses>
struct conjunction_builder<
mp::list<T_clauses...>,
mp::enable_if_t<
mp::is_true_v<is_where_clause_v<mp::decay_t<T_clauses>>...>
&& sizeof...(T_clauses) >= 2>>
{
static constexpr decltype(auto) apply(T_clauses&&... clauses)
{
using clause_type = where_clause_conjunction_t<T_clauses...>;
return clause_type(std::forward<T_clauses>(clauses)...);
}
};

}

/* is_conjunction */

template<typename T>
struct is_conjunction
: public mp::is_specialization_of<T, __impl::where_clause_conjunction_t>
{ };

/* is_and */

template<typename T>
struct is_and
: public mp::is_specialization_of<T, __impl::where_clause_conjunction_t>
{ };

}

+ 59
- 0
include/cpphibernate/modifier/where/disjunction.h View File

@@ -0,0 +1,59 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

namespace __impl
{

/**
* @brief Helper class to build disjunction objects.
*/
template<typename X, typename = void>
struct disjunction_builder;

}



/**
* @brief Evaluates to true_t if the passed type is a disjunction clause, false_t otherwise.
*/
template<typename T>
struct is_disjunction;

/**
* @brief Is true if the passed type is a disjunction clause, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_disjunction_v = is_disjunction<T>::value;

/**
* @brief Predicate to create new disjunction clause objects.
*/
constexpr decltype(auto) disjunction = mp::generic_predicate<__impl::disjunction_builder> { };



/**
* @brief Evaluates to true_t if the passed type is a disjunction clause, false_t otherwise.
*/
template<typename T>
struct is_or;

/**
* @brief Is true if the passed type is a disjunction clause, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_or_v = is_or<T>::value;

/**
* @brief Predicate to create new disjunction clause objects.
*/
constexpr decltype(auto) or_ = mp::generic_predicate<__impl::disjunction_builder> { };

}

#include "disjunction.inl"

+ 69
- 0
include/cpphibernate/modifier/where/disjunction.inl View File

@@ -0,0 +1,69 @@
#pragma once

#include <cpphibernate/schema/field.h>

#include "disjunction.h"

namespace cpphibernate
{

namespace __impl
{

/* where_clause_disjunction_t */

template<typename... T_clauses>
struct where_clause_disjunction_t
: public tag_where_clause
{
using clauses_type = hana::basic_tuple<T_clauses...>;

clauses_type clauses;

constexpr where_clause_disjunction_t(
T_clauses&&... p_clauses)
: clauses(std::forward<T_clauses>(p_clauses)...)
{ }
};

/* disjunction_builder */

template<typename X, typename>
struct disjunction_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::disjunction(...)!"); }
};

template<typename... T_clauses>
struct disjunction_builder<
mp::list<T_clauses...>,
mp::enable_if_t<
mp::is_true_v<is_where_clause_v<mp::decay_t<T_clauses>>...>
&& sizeof...(T_clauses) >= 2>>
{
static constexpr decltype(auto) apply(T_clauses&&... clauses)
{
using clause_type = where_clause_disjunction_t<T_clauses...>;
return clause_type(std::forward<T_clauses>(clauses)...);
}
};

}

/* is_disjunction */

template<typename T>
struct is_disjunction
: public mp::is_specialization_of<T, __impl::where_clause_disjunction_t>
{ };

/* is_or */

template<typename T>
struct is_or
: public mp::is_specialization_of<T, __impl::where_clause_disjunction_t>
{ };

}

+ 38
- 0
include/cpphibernate/modifier/where/equal.h View File

@@ -0,0 +1,38 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

namespace __impl
{

/**
* @brief Helper class to build equal objects.
*/
template<typename X, typename = void>
struct equal_builder;

}

/**
* @brief Evaluates to true_t if the passed type is a equal order, false_t otherwise.
*/
template<typename T>
struct is_equal;

/**
* @brief Is true if the passed type is a equal order, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_equal_v = is_equal<T>::value;

/**
* @brief Predicate to create new equal order objects.
*/
constexpr decltype(auto) equal = mp::generic_predicate<__impl::equal_builder> { };

}

#include "equal.inl"

+ 64
- 0
include/cpphibernate/modifier/where/equal.inl View File

@@ -0,0 +1,64 @@
#pragma once

#include <cpphibernate/schema/field.h>

#include "equal.h"

namespace cpphibernate
{

namespace __impl
{

/* where_clause_equal_t */

template<typename T_field, typename T_value>
struct where_clause_equal_t
: public tag_where_clause
{
using field_type = T_field;
using value_type = T_value;

field_type field;
value_type value;

constexpr where_clause_equal_t(
field_type&& p_field,
value_type&& p_value)
: field(std::forward<field_type>(p_field))
, value(std::forward<value_type>(p_value))
{ }
};

/* equal_builder */

template<typename X, typename>
struct equal_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::equal(...)!"); }
};

template<typename T_field, typename T_value>
struct equal_builder<
mp::list<T_field, T_value>,
mp::enable_if_t<schema::is_field_v<mp::decay_t<T_field>>>>
{
static constexpr decltype(auto) apply(T_field&& field, T_value&& value)
{
using clause_type = where_clause_equal_t<T_field, T_value>;
return clause_type(std::forward<T_field>(field), std::forward<T_value>(value));
}
};

}

/* is_equal */

template<typename T>
struct is_equal
: public mp::is_specialization_of<T, __impl::where_clause_equal_t>
{ };

}

+ 59
- 0
include/cpphibernate/modifier/where/negation.h View File

@@ -0,0 +1,59 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

namespace __impl
{

/**
* @brief Helper class to build negation objects.
*/
template<typename X, typename = void>
struct negation_builder;

}



/**
* @brief Evaluates to true_t if the passed type is a negation clause, false_t otherwise.
*/
template<typename T>
struct is_negation;

/**
* @brief Is true if the passed type is a negation clause, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_negation_v = is_negation<T>::value;

/**
* @brief Predicate to create new negation clause objects.
*/
constexpr decltype(auto) negation = mp::generic_predicate<__impl::negation_builder> { };



/**
* @brief Evaluates to true_t if the passed type is a negation clause, false_t otherwise.
*/
template<typename T>
struct is_not;

/**
* @brief Is true if the passed type is a negation clause, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_not_v = is_not<T>::value;

/**
* @brief Predicate to create new negation clause objects.
*/
constexpr decltype(auto) not_ = mp::generic_predicate<__impl::negation_builder> { };

}

#include "negation.inl"

+ 67
- 0
include/cpphibernate/modifier/where/negation.inl View File

@@ -0,0 +1,67 @@
#pragma once

#include <cpphibernate/schema/field.h>

#include "negation.h"

namespace cpphibernate
{

namespace __impl
{

/* where_clause_negation_t */

template<typename T_clause>
struct where_clause_negation_t
: public tag_where_clause
{
using clause_type = T_clause;

clause_type clause;

constexpr where_clause_negation_t(
clause_type&& p_clause)
: clause(std::forward<clause_type>(p_clause))
{ }
};

/* negation_builder */

template<typename X, typename>
struct negation_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::negation(...)!"); }
};

template<typename T_clause>
struct negation_builder<
mp::list<T_clause>,
mp::enable_if_t<is_where_clause_v<mp::decay_t<T_clause>>>>
{
static constexpr decltype(auto) apply(T_clause&& clause)
{
using clause_type = where_clause_negation_t<T_clause>;
return clause_type(std::forward<T_clause>(clause));
}
};

}

/* is_negation */

template<typename T>
struct is_negation
: public mp::is_specialization_of<T, __impl::where_clause_negation_t>
{ };

/* is_not */

template<typename T>
struct is_not
: public mp::is_specialization_of<T, __impl::where_clause_negation_t>
{ };

}

+ 0
- 60
include/cpphibernate/modifier/where/where.h View File

@@ -1,60 +0,0 @@
#pragma once

#include <cpphibernate/misc.h>
#include <cpphibernate/config.h>
#include <cpphibernate/modifier/modifier.h>
#include <cpphibernate/modifier/where/clauses/clause.h>

beg_namespace_cpphibernate_modifier
{

namespace __impl
{

/* where_t */

template<typename T_clause>
struct where_t
: public modifier_t
{
using clause_type = T_clause;

clause_type clause;

constexpr where_t(T_clause&& p_clause)
: clause(std::forward<T_clause>(p_clause))
{ }
};

/* where_builder */

template<typename X, typename = void>
struct where_builder
{
template<typename... T_args>
static constexpr decltype(auto) apply(T_args&&... args)
{ static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::modifier::where(...)!"); }
};

template<typename T_clause>
struct where_builder<mp::list<T_clause>, mp::enable_if<is_where_clause<T_clause>>>
{
static constexpr decltype(auto) apply(T_clause&& clause)
{ return where_t<T_clause>(std::forward<T_clause>(clause)); }
};

}

/* meta */

template<typename T>
struct is_where
: public mp::is_specialization_of<T, __impl::where_t>
{ };

/* make */

constexpr decltype(auto) where = misc::make_generic_predicate<__impl::where_builder> { };

}
end_namespace_cpphibernate_modifier

+ 22
- 0
include/cpphibernate/modifier/where/where_clause.h View File

@@ -0,0 +1,22 @@
#pragma once

#include <cpphibernate/config.h>

namespace cpphibernate
{

/**
* @brief Evaluates to true_t if the passed type is a where_clause, false_t otherwise.
*/
template<typename T>
struct is_where_clause;

/**
* @brief Is true if the passed type is a where_clause, false otherwise.
*/
template<typename T>
constexpr decltype(auto) is_where_clause_v = is_where_clause<T>::value;

}

#include "where_clause.inl"

+ 25
- 0
include/cpphibernate/modifier/where/where_clause.inl View File

@@ -0,0 +1,25 @@
#pragma once

#include "where_clause.h"

namespace cpphibernate
{

namespace __impl
{

/* tag_where_clause */

struct tag_where_clause
{ };

}

/* is_where_clause */

template<typename T>
struct is_where_clause
: public mp::is_base_of<__impl::tag_where_clause, T>
{ };

}

+ 1
- 1
include/cpphibernate/schema/attributes.inl View File

@@ -11,7 +11,7 @@ namespace schema {
/* attributes_t */

template<typename... T_attributes>
using attributes_t = hana::basic_tuple<T_attributes...>;
using attributes_t = hana::tuple<T_attributes...>;

/* attributes_builder */



+ 1
- 1
include/cpphibernate/schema/fields.inl View File

@@ -11,7 +11,7 @@ namespace schema {
/* fields_t */

template<typename... T_fields>
using fields_t = hana::basic_tuple<T_fields...>;
using fields_t = hana::tuple<T_fields...>;

/* fields_builder */



+ 1
- 1
include/cpphibernate/schema/tables.inl View File

@@ -11,7 +11,7 @@ namespace schema {
/* tables_t */

template<typename... T_tables>
using tables_t = hana::basic_tuple<T_tables...>;
using tables_t = hana::tuple<T_tables...>;

/* tables_builder */



+ 17
- 8
test/cpphibernate/cpphibernate_tests.cpp View File

@@ -4,17 +4,26 @@

#include "test_schema.h"

constexpr decltype(auto) x = ::cpphibernate::mp::make_getter(
[](std::string&) {
return int { };
});

using namespace ::testing;
using namespace ::cpphibernate;
using namespace ::cpphibernate::schema;

TEST(cpphibernate, getHelloWorld)
using namespace hana::literals;

constexpr decltype(auto) tmp_table = test_schema.tables[0_c];
constexpr decltype(auto) tmp_field = tmp_table.fields[0_c];
constexpr decltype(auto) mod = make_modifiers(
limit(5_c),
offset(3_c),
order_by(
ascending(tmp_field),
descending(tmp_field)),
where(
or_(
negation(equal(tmp_field, 1)),
negation(equal(tmp_field, 1)))));

TEST(cpphibernate_tests, dummy)
{
(void)x;
// std::cout << test_schema << std::endl;
(void)mod;
}

+ 0
- 236
test/test_schema.h View File

@@ -1,236 +0,0 @@
#pragma once

#include <cpphibernate.h>
#include <cpputils/misc/enum.h>

enum class test_enum
{
test0,
test1,
test2,
test3,

first = test0,
last = test3,
};

DEFINE_ENUM_TO_STRING_MAP(
test_enum,
{ test_enum::test0, "test0" },
{ test_enum::test1, "test1" },
{ test_enum::test2, "test2" },
{ test_enum::test3, "test3" }
);

DEFINE_STRING_TO_ENUM_MAP(
test_enum,
invariant_string_less,
{ "test0", test_enum::test0 },
{ "test1", test_enum::test1 },
{ "test2", test_enum::test2 },
{ "test3", test_enum::test3 }
);

struct test1
{
::cpphibernate::uuid id;
std::string str_data;
::cpphibernate::string<64> str64_data;

utl::nullable<uint32_t> u32_nullable;
std::unique_ptr<uint32_t> u32_ptr_u;
std::shared_ptr<uint32_t> u32_ptr_s;
};

struct test2
{
::cpphibernate::uuid id;
uint8_t u8_data;
int8_t i8_data;
uint16_t u16_data;
int16_t i16_data;
};

struct test3
{
::cpphibernate::uuid id;
uint32_t u32_data;
int32_t i32_data;
uint64_t u64_data;
int64_t i64_data;
};

struct base
{
::cpphibernate::uuid id;
std::string name;

virtual ~base() = default;
};

struct derived1
: public base
{
::cpphibernate::uuid derived1_id;
test1 test1_data;
test_enum enum_data;
};

struct derived2
: public base
{
::cpphibernate::uuid derived2_id;
utl::nullable<test2> test2_nullable;
std::unique_ptr<test2> test2_ptr_u;
std::shared_ptr<test2> test2_ptr_s;
};

struct derived3
: public derived2
{
::cpphibernate::uuid derived3_id;
std::list<test3> test3_list;
std::vector<test3> test3_vector;
};

struct dummy_id
{
int data;

inline dummy_id(int p_data = 0)
: data(p_data)
{ }
};

struct dummy_owner
{
::cpphibernate::uuid id;
std::vector<dummy_id> dummies;
};

struct double_usage_item
{
unsigned int id { 0 };
int data { 0 };

double_usage_item(int p_data = 0)
: data(p_data)
{ }
};

struct double_usage
{
int id { 0 };
std::unique_ptr<double_usage_item> single_item;
std::vector<double_usage_item> multiple_items;
};

struct double_usage_wrapper
{
int id { 0 };
std::unique_ptr<double_usage> double_usage;
};

constexpr decltype(auto) test_schema = cpphibernate_make_schema(
test,
cpphibernate_make_table_name(
tbl_test1,
test1,
1,
cpphibernate_make_id (&test1::id),
cpphibernate_make_field (test1, str_data),
cpphibernate_make_field (test1, str64_data),
cpphibernate_make_field (test1, u32_nullable),
cpphibernate_make_field (test1, u32_ptr_u),
cpphibernate_make_field (test1, u32_ptr_s)
),
cpphibernate_make_table_name(
tbl_test2,
test2,
2,
cpphibernate_make_id (&test2::id),
cpphibernate_make_field (test2, u8_data),
cpphibernate_make_field (test2, i8_data),
cpphibernate_make_field (test2, u16_data),
cpphibernate_make_field (test2, i16_data)
),
cpphibernate_make_table_name(
tbl_test3,
test3,
3,
cpphibernate_make_id (&test3::id),
cpphibernate_make_field (test3, u32_data),
cpphibernate_make_field (test3, i32_data),
cpphibernate_make_field (test3, u64_data),
cpphibernate_make_field (test3, i64_data)
),

cpphibernate_make_table_name(
tbl_base,
base,
10,
cpphibernate_make_id (&base::id),
cpphibernate_make_field (base, name)
),
cpphibernate_make_table_name(
tbl_derived1,
derived1,
11,
cpphibernate_make_id (&derived1::derived1_id),
cpphibernate_make_field (derived1, test1_data),
cpphibernate_make_field (derived1, enum_data)
),
cpphibernate_make_table_name(
tbl_derived2,
derived2,
12,
cpphibernate_make_id (&derived2::derived2_id),
cpphibernate_make_field (derived2, test2_nullable),
cpphibernate_make_field (derived2, test2_ptr_u),
cpphibernate_make_field (derived2, test2_ptr_s)
),
cpphibernate_make_table_name(
tbl_derived3,
derived3,
13,
cpphibernate_make_id (&derived3::derived3_id),
cpphibernate_make_field (derived3, test3_list),
cpphibernate_make_field (derived3, test3_vector)
),
cpphibernate_make_table_name(
tbl_dummy_id,
dummy_id,
14,
cpphibernate_make_temp_id (dummy_id, ::cpphibernate::uuid),
cpphibernate_make_field (dummy_id, data)
),
cpphibernate_make_table_name(
tbl_dummy_owner,
dummy_owner,
15,
cpphibernate_make_id (&dummy_owner::id),
cpphibernate_make_field (dummy_owner, dummies)
),
cpphibernate_make_table_name(
tbl_double_usage_item,
double_usage_item,
16,
cpphibernate_make_id (&double_usage_item::id),
cpphibernate_make_field (double_usage_item, data)
),
cpphibernate_make_table_name(
tbl_double_usage,
double_usage,
17,
cpphibernate_make_id (&double_usage::id),
cpphibernate_make_field (double_usage, single_item),
cpphibernate_make_field (double_usage, multiple_items)
),
cpphibernate_make_table_name(
tbl_double_usage_wrapper,
double_usage_wrapper,
18,
cpphibernate_make_id (&double_usage_wrapper::id),
cpphibernate_make_field (double_usage_wrapper, double_usage)
)
);

Loading…
Cancel
Save