Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Commit

Permalink
Simplified internal table interface
Browse files Browse the repository at this point in the history
  • Loading branch information
trueqbit committed May 28, 2022
1 parent b034e38 commit b5e9b7c
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 154 deletions.
7 changes: 7 additions & 0 deletions dev/column.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ namespace sqlite_orm {
template<class T>
using is_column = polyfill::bool_constant<is_column_v<T>>;

template<class Elements, class F>
using col_index_sequence_with_field_type =
filter_tuple_sequence_t<Elements,
check_if_is_type<F>::template fn,
field_type_t,
filter_tuple_sequence_t<Elements, is_column>>;

template<class Elements, template<class...> class TraitFn>
using col_index_sequence_with = filter_tuple_sequence_t<Elements,
check_if_tuple_has<TraitFn>::template fn,
Expand Down
111 changes: 35 additions & 76 deletions dev/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,34 @@ namespace sqlite_orm {

template<class M, satisfies<is_setter, M> = true>
const member_field_type_t<M>* object_field_value(const object_type& object, M memberPointer) const {
using F = member_field_type_t<M>;
const F* res = nullptr;
this->for_each_column_with_field_type<F>(
call_as_template_base<column_field>([&res, &memberPointer, &object](const auto& column) {
if(compare_any(column.setter, memberPointer)) {
res = &polyfill::invoke(column.member_pointer, object);
}
}));
using field_type = member_field_type_t<M>;
const field_type* res = nullptr;
iterate_tuple(this->elements,
col_index_sequence_with_field_type<elements_type, field_type>{},
call_as_template_base<column_field>([&res, &memberPointer, &object](const auto& column) {
if(compare_any(column.setter, memberPointer)) {
res = &polyfill::invoke(column.member_pointer, object);
}
}));
return res;
}

const basic_generated_always::storage_type*
find_column_generated_storage_type(const std::string& name) const {
const basic_generated_always::storage_type* result = nullptr;
#if SQLITE_VERSION_NUMBER >= 3031000
this->for_each_column<constraints_type_t, check_if_tuple_has<is_generated_always>>([&result, &name](
auto& column) {
if(column.name != name) {
return;
}
using generated_op_index_sequence =
filter_tuple_sequence_t<std::remove_const_t<decltype(column.constraints)>, is_generated_always>;
constexpr size_t opIndex = first_index_sequence_value(generated_op_index_sequence{});
result = &get<opIndex>(column.constraints).storage;
});
iterate_tuple(this->elements,
col_index_sequence_with<elements_type, is_generated_always>{},
[&result, &name](auto& column) {
if(column.name != name) {
return;
}
using generated_op_index_sequence =
filter_tuple_sequence_t<std::remove_const_t<decltype(column.constraints)>,
is_generated_always>;
constexpr size_t opIndex = first_index_sequence_value(generated_op_index_sequence{});
result = &get<opIndex>(column.constraints).storage;
});
#endif
return result;
}
Expand Down Expand Up @@ -159,20 +162,16 @@ namespace sqlite_orm {

template<class L>
void for_each_primary_key_column(L&& lambda) const {
this->for_each_column_with<is_primary_key>(
call_as_template_base<column_field>([&lambda](const auto& column) {
lambda(column.member_pointer);
}));
iterate_tuple(this->elements,
col_index_sequence_with<elements_type, is_primary_key>{},
call_as_template_base<column_field>([&lambda](const auto& column) {
lambda(column.member_pointer);
}));
this->for_each_primary_key([this, &lambda](auto& primaryKey) {
this->for_each_column_in_primary_key(primaryKey, lambda);
iterate_tuple(primaryKey.columns, lambda);
});
}

template<class L, class... Args>
void for_each_column_in_primary_key(const primary_key_t<Args...>& primaryKey, L&& lambda) const {
iterate_tuple(primaryKey.columns, lambda);
}

template<class... Args>
std::vector<std::string> composite_key_columns_names(const primary_key_t<Args...>& primaryKey) const {
return create_from_tuple<std::vector<std::string>>(primaryKey.columns,
Expand All @@ -194,11 +193,13 @@ namespace sqlite_orm {
const std::string* find_column_name(M m) const {
const std::string* res = nullptr;
using field_type = member_field_type_t<M>;
this->for_each_column_with_field_type<field_type>([&res, m](auto& c) {
if(compare_any(c.member_pointer, m) || compare_any(c.setter, m)) {
res = &c.name;
}
});
iterate_tuple(this->elements,
col_index_sequence_with_field_type<elements_type, field_type>{},
[&res, m](auto& c) {
if(compare_any(c.member_pointer, m) || compare_any(c.setter, m)) {
res = &c.name;
}
});
return res;
}

Expand Down Expand Up @@ -253,55 +254,13 @@ namespace sqlite_orm {
iterate_tuple(this->elements, col_index_sequence{}, lambda);
}

/**
* Call passed lambda with columns filtered on `PredicateFn(TransformFn(column_t))`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<template<class...> class TransformFn, template<class...> class PredicateFn, class L>
void for_each_column(L&& lambda) const {
using col_index_sequence = filter_tuple_sequence_t<elements_type, is_column>;
using filtered_index_sequence =
filter_tuple_sequence_t<elements_type, PredicateFn, TransformFn, col_index_sequence>;
iterate_tuple(this->elements, filtered_index_sequence{}, lambda);
}

/**
* Call passed lambda with columns filtered on `PredicateFn(TransformFn(column_t))`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<template<class...> class TransformFn,
class PredicateFnCls,
class L,
satisfies<mpl::is_metafunction_class, PredicateFnCls> = true>
void for_each_column(L&& lambda) const {
return this->for_each_column<TransformFn, PredicateFnCls::template fn>(lambda);
}

/**
* Call passed lambda with columns having the specified field type `F`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<class F, class L>
void for_each_column_with_field_type(L&& lambda) const {
this->for_each_column<field_type_t, check_if_is_type<F>>(lambda);
}

/**
* Call passed lambda with columns having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<template<class...> class OpTraitFn, class L>
void for_each_column_with(L&& lambda) const {
this->for_each_column<constraints_type_t, check_if_tuple_has<OpTraitFn>>(lambda);
}

/**
* Call passed lambda with columns not having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column.
*/
template<template<class...> class OpTraitFn, class L>
void for_each_column_excluding(L&& lambda) const {
this->for_each_column<constraints_type_t, check_if_tuple_has_not<OpTraitFn>>(lambda);
iterate_tuple(this->elements, col_index_sequence_excluding<elements_type, OpTraitFn>{}, lambda);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion dev/values_to_tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace sqlite_orm {
(*this)(values, tuple, std::index_sequence<Idx...>{});
}
template<class Tpl, size_t... Idx>
void operator()(sqlite3_value** values, Tpl& tuple, std::index_sequence<Idx...>) const {}
void operator()(sqlite3_value** /*values*/, Tpl&, std::index_sequence<Idx...>) const {}
#endif
template<class T>
void extract(sqlite3_value* value, T& t) const {
Expand Down
120 changes: 43 additions & 77 deletions include/sqlite_orm/sqlite_orm.h
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,13 @@ namespace sqlite_orm {
template<class T>
using is_column = polyfill::bool_constant<is_column_v<T>>;

template<class Elements, class F>
using col_index_sequence_with_field_type =
filter_tuple_sequence_t<Elements,
check_if_is_type<F>::template fn,
field_type_t,
filter_tuple_sequence_t<Elements, is_column>>;

template<class Elements, template<class...> class TraitFn>
using col_index_sequence_with = filter_tuple_sequence_t<Elements,
check_if_tuple_has<TraitFn>::template fn,
Expand Down Expand Up @@ -10114,31 +10121,34 @@ namespace sqlite_orm {

template<class M, satisfies<is_setter, M> = true>
const member_field_type_t<M>* object_field_value(const object_type& object, M memberPointer) const {
using F = member_field_type_t<M>;
const F* res = nullptr;
this->for_each_column_with_field_type<F>(
call_as_template_base<column_field>([&res, &memberPointer, &object](const auto& column) {
if(compare_any(column.setter, memberPointer)) {
res = &polyfill::invoke(column.member_pointer, object);
}
}));
using field_type = member_field_type_t<M>;
const field_type* res = nullptr;
iterate_tuple(this->elements,
col_index_sequence_with_field_type<elements_type, field_type>{},
call_as_template_base<column_field>([&res, &memberPointer, &object](const auto& column) {
if(compare_any(column.setter, memberPointer)) {
res = &polyfill::invoke(column.member_pointer, object);
}
}));
return res;
}

const basic_generated_always::storage_type*
find_column_generated_storage_type(const std::string& name) const {
const basic_generated_always::storage_type* result = nullptr;
#if SQLITE_VERSION_NUMBER >= 3031000
this->for_each_column<constraints_type_t, check_if_tuple_has<is_generated_always>>([&result, &name](
auto& column) {
if(column.name != name) {
return;
}
using generated_op_index_sequence =
filter_tuple_sequence_t<std::remove_const_t<decltype(column.constraints)>, is_generated_always>;
constexpr size_t opIndex = first_index_sequence_value(generated_op_index_sequence{});
result = &get<opIndex>(column.constraints).storage;
});
iterate_tuple(this->elements,
col_index_sequence_with<elements_type, is_generated_always>{},
[&result, &name](auto& column) {
if(column.name != name) {
return;
}
using generated_op_index_sequence =
filter_tuple_sequence_t<std::remove_const_t<decltype(column.constraints)>,
is_generated_always>;
constexpr size_t opIndex = first_index_sequence_value(generated_op_index_sequence{});
result = &get<opIndex>(column.constraints).storage;
});
#endif
return result;
}
Expand Down Expand Up @@ -10193,20 +10203,16 @@ namespace sqlite_orm {

template<class L>
void for_each_primary_key_column(L&& lambda) const {
this->for_each_column_with<is_primary_key>(
call_as_template_base<column_field>([&lambda](const auto& column) {
lambda(column.member_pointer);
}));
iterate_tuple(this->elements,
col_index_sequence_with<elements_type, is_primary_key>{},
call_as_template_base<column_field>([&lambda](const auto& column) {
lambda(column.member_pointer);
}));
this->for_each_primary_key([this, &lambda](auto& primaryKey) {
this->for_each_column_in_primary_key(primaryKey, lambda);
iterate_tuple(primaryKey.columns, lambda);
});
}

template<class L, class... Args>
void for_each_column_in_primary_key(const primary_key_t<Args...>& primaryKey, L&& lambda) const {
iterate_tuple(primaryKey.columns, lambda);
}

template<class... Args>
std::vector<std::string> composite_key_columns_names(const primary_key_t<Args...>& primaryKey) const {
return create_from_tuple<std::vector<std::string>>(primaryKey.columns,
Expand All @@ -10228,11 +10234,13 @@ namespace sqlite_orm {
const std::string* find_column_name(M m) const {
const std::string* res = nullptr;
using field_type = member_field_type_t<M>;
this->for_each_column_with_field_type<field_type>([&res, m](auto& c) {
if(compare_any(c.member_pointer, m) || compare_any(c.setter, m)) {
res = &c.name;
}
});
iterate_tuple(this->elements,
col_index_sequence_with_field_type<elements_type, field_type>{},
[&res, m](auto& c) {
if(compare_any(c.member_pointer, m) || compare_any(c.setter, m)) {
res = &c.name;
}
});
return res;
}

Expand Down Expand Up @@ -10287,55 +10295,13 @@ namespace sqlite_orm {
iterate_tuple(this->elements, col_index_sequence{}, lambda);
}

/**
* Call passed lambda with columns filtered on `PredicateFn(TransformFn(column_t))`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<template<class...> class TransformFn, template<class...> class PredicateFn, class L>
void for_each_column(L&& lambda) const {
using col_index_sequence = filter_tuple_sequence_t<elements_type, is_column>;
using filtered_index_sequence =
filter_tuple_sequence_t<elements_type, PredicateFn, TransformFn, col_index_sequence>;
iterate_tuple(this->elements, filtered_index_sequence{}, lambda);
}

/**
* Call passed lambda with columns filtered on `PredicateFn(TransformFn(column_t))`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<template<class...> class TransformFn,
class PredicateFnCls,
class L,
satisfies<mpl::is_metafunction_class, PredicateFnCls> = true>
void for_each_column(L&& lambda) const {
return this->for_each_column<TransformFn, PredicateFnCls::template fn>(lambda);
}

/**
* Call passed lambda with columns having the specified field type `F`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<class F, class L>
void for_each_column_with_field_type(L&& lambda) const {
this->for_each_column<field_type_t, check_if_is_type<F>>(lambda);
}

/**
* Call passed lambda with columns having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column. Function signature: `void(auto& column)`
*/
template<template<class...> class OpTraitFn, class L>
void for_each_column_with(L&& lambda) const {
this->for_each_column<constraints_type_t, check_if_tuple_has<OpTraitFn>>(lambda);
}

/**
* Call passed lambda with columns not having the specified constraint trait `OpTrait`.
* @param lambda Lambda called for each column.
*/
template<template<class...> class OpTraitFn, class L>
void for_each_column_excluding(L&& lambda) const {
this->for_each_column<constraints_type_t, check_if_tuple_has_not<OpTraitFn>>(lambda);
iterate_tuple(this->elements, col_index_sequence_excluding<elements_type, OpTraitFn>{}, lambda);
}

/**
Expand Down Expand Up @@ -13722,7 +13688,7 @@ namespace sqlite_orm {
(*this)(values, tuple, std::index_sequence<Idx...>{});
}
template<class Tpl, size_t... Idx>
void operator()(sqlite3_value** values, Tpl& tuple, std::index_sequence<Idx...>) const {}
void operator()(sqlite3_value** /*values*/, Tpl&, std::index_sequence<Idx...>) const {}
#endif
template<class T>
void extract(sqlite3_value* value, T& t) const {
Expand Down

0 comments on commit b5e9b7c

Please sign in to comment.