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

Commit

Permalink
fixed and and or operators for expression
Browse files Browse the repository at this point in the history
  • Loading branch information
fnc12 committed May 21, 2021
1 parent ab77f3f commit 70b84fa
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 153 deletions.
40 changes: 30 additions & 10 deletions dev/conditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#include "collate_argument.h"
#include "constraints.h"
#include "optional_container.h"
#include "negatable.h"
#include "tags.h"
#include "expression.h"

namespace sqlite_orm {

Expand Down Expand Up @@ -59,11 +60,6 @@ namespace sqlite_orm {
template<class T>
struct is_offset<offset_t<T>> : std::true_type {};

/**
* Inherit from this class if target class can be chained with other conditions with '&&' and '||' operators
*/
struct condition_t {};

/**
* Collated something
*/
Expand Down Expand Up @@ -148,6 +144,11 @@ namespace sqlite_orm {
using super::super;
};

template<class L, class R>
and_condition_t<L, R> make_and_condition(L left, R right) {
return {std::move(left), std::move(right)};
}

struct or_condition_string {
operator std::string() const {
return "OR";
Expand All @@ -164,6 +165,11 @@ namespace sqlite_orm {
using super::super;
};

template<class L, class R>
or_condition_t<L, R> make_or_condition(L left, R right) {
return {std::move(left), std::move(right)};
}

struct is_equal_string {
operator std::string() const {
return "=";
Expand Down Expand Up @@ -1106,16 +1112,30 @@ namespace sqlite_orm {
class R,
typename = typename std::enable_if<std::is_base_of<internal::condition_t, L>::value ||
std::is_base_of<internal::condition_t, R>::value>::type>
internal::and_condition_t<L, R> operator&&(L l, R r) {
return {std::move(l), std::move(r)};
auto operator&&(L l, R r) {
using internal::get_from_expression;
return internal::make_and_condition(std::move(get_from_expression(l)), std::move(get_from_expression(r)));
}

template<class L, class R>
auto and_(L l, R r) {
using internal::get_from_expression;
return internal::make_and_condition(std::move(get_from_expression(l)), std::move(get_from_expression(r)));
}

template<class L,
class R,
typename = typename std::enable_if<std::is_base_of<internal::condition_t, L>::value ||
std::is_base_of<internal::condition_t, R>::value>::type>
internal::or_condition_t<L, R> operator||(L l, R r) {
return {std::move(l), std::move(r)};
auto operator||(L l, R r) {
using internal::get_from_expression;
return internal::make_or_condition(std::move(get_from_expression(l)), std::move(get_from_expression(r)));
}

template<class L, class R>
auto or_(L l, R r) {
using internal::get_from_expression;
return internal::make_or_condition(std::move(get_from_expression(l)), std::move(get_from_expression(r)));
}

template<class T>
Expand Down
75 changes: 75 additions & 0 deletions dev/expression.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "operators.h"

namespace sqlite_orm {

namespace internal {

template<class L, class R>
struct and_condition_t;

template<class L, class R>
struct or_condition_t;

/**
* Is not an operator but a result of c(...) function. Has operator= overloaded which returns assign_t
*/
template<class T>
struct expression_t : condition_t {
T value;

expression_t(T value_) : value(std::move(value_)) {}

template<class R>
assign_t<T, R> operator=(R r) const {
return {this->value, std::move(r)};
}

assign_t<T, std::nullptr_t> operator=(std::nullptr_t) const {
return {this->value, nullptr};
}
#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED
assign_t<T, std::nullopt_t> operator=(std::nullopt_t) const {
return {this->value, std::nullopt};
}
#endif
template<class... Args>
in_t<T, Args...> in(Args... args) const {
return {this->value, std::make_tuple(std::forward<Args>(args)...), false};
}

template<class... Args>
in_t<T, Args...> not_in(Args... args) const {
return {this->value, std::make_tuple(std::forward<Args>(args)...), true};
}

template<class R>
and_condition_t<T, R> and_(R right) const {
return {this->value, std::move(right)};
}

template<class R>
or_condition_t<T, R> or_(R right) const {
return {this->value, std::move(right)};
}
};

template<class T>
T get_from_expression(T value) {
return std::move(value);
}

template<class T>
T get_from_expression(expression_t<T> expression) {
return std::move(expression.value);
}
}

/**
* Public interface for syntax sugar for columns. Example: `where(c(&User::id) == 5)` or
* `storage.update(set(c(&User::name) = "Dua Lipa"));
*/
template<class T>
internal::expression_t<T> c(T value) {
return {std::move(value)};
}
}
7 changes: 0 additions & 7 deletions dev/negatable.h

This file was deleted.

44 changes: 1 addition & 43 deletions dev/operators.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED
#include <optional> // std::nullopt
#endif // SQLITE_ORM_OPTIONAL_SUPPORTED
#include "negatable.h"
#include "tags.h"

namespace sqlite_orm {

Expand Down Expand Up @@ -191,48 +191,6 @@ namespace sqlite_orm {
template<class L, class... Args>
struct in_t;

/**
* Is not an operator but a result of c(...) function. Has operator= overloaded which returns assign_t
*/
template<class T>
struct expression_t {
T value;

expression_t(T value_) : value(std::move(value_)) {}

template<class R>
assign_t<T, R> operator=(R r) const {
return {this->value, std::move(r)};
}

assign_t<T, std::nullptr_t> operator=(std::nullptr_t) const {
return {this->value, nullptr};
}
#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED
assign_t<T, std::nullopt_t> operator=(std::nullopt_t) const {
return {this->value, std::nullopt};
}
#endif
template<class... Args>
in_t<T, Args...> in(Args... args) const {
return {this->value, std::make_tuple(std::forward<Args>(args)...), false};
}

template<class... Args>
in_t<T, Args...> not_in(Args... args) const {
return {this->value, std::make_tuple(std::forward<Args>(args)...), true};
}
};

}

/**
* Public interface for syntax sugar for columns. Example: `where(c(&User::id) == 5)` or
* `storage.update(set(c(&User::name) = "Dua Lipa"));
*/
template<class T>
internal::expression_t<T> c(T value) {
return {std::move(value)};
}

/**
Expand Down
2 changes: 1 addition & 1 deletion dev/storage_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace sqlite_orm {
int res = sqlite3_exec(
db,
sql.c_str(),
[](void* data, int argc, char** argv, char* * /*columnName*/) -> int {
[](void* data, int argc, char** argv, char** /*columnName*/) -> int {
auto& tableNames_ = *(data_t*)data;
for(int i = 0; i < argc; i++) {
if(argv[i]) {
Expand Down
2 changes: 1 addition & 1 deletion dev/storage_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace sqlite_orm {
auto rc = sqlite3_exec(
db,
query.c_str(),
[](void* data, int argc, char** argv, char* * /*azColName*/) -> int {
[](void* data, int argc, char** argv, char** /*azColName*/) -> int {
auto& res = *(bool*)data;
if(argc) {
res = !!std::atoi(argv[0]);
Expand Down
12 changes: 12 additions & 0 deletions dev/tags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

namespace sqlite_orm {
namespace internal {
struct negatable_t {};

/**
* Inherit from this class if target class can be chained with other conditions with '&&' and '||' operators
*/
struct condition_t {};
}
}
Loading

0 comments on commit 70b84fa

Please sign in to comment.