this->admins.erase(name);
}
- std::string query = schema::AdminTable.remove().where(expr(&Admin::name) == name);
+ std::string query = schema::AdminTable.remove().where(Admin::Name == name);
database::Statement stmt(*database, query);
stmt.bind(1, name);
if (!stmt.exec())
DEBUG(VIST) << "Activate admin: " << admin;
/// Admin::Activated
std::string query = schema::AdminTable.update(Admin::Activated)
- .where(expr(&Admin::name) == admin);
+ .where(Admin::Name == admin);
database::Statement stmt(*this->database, query);
stmt.bind(1, static_cast<int>(state));
stmt.bind(2, admin);
THROW(ErrCode::LogicError) << "Not exist policy: " << policy;
std::string query = schema::PolicyManagedTable.update(PolicyManaged::Value)
- .where(expr(&PolicyManaged::admin) == admin &&
- expr(&PolicyManaged::policy) == policy);
+ .where(PolicyManaged::Admin == admin &&
+ PolicyManaged::Policy == policy);
database::Statement stmt(*this->database, query);
stmt.bind(1, value.dump());
stmt.bind(2, admin);
#pragma once
#include "query-builder/column.hpp"
-#include "query-builder/condition.hpp"
#include "query-builder/database.hpp"
#include "query-builder/expression.hpp"
#include "query-builder/macro.hpp"
#pragma once
+#include "expression.hpp"
+
#include <string>
#include <tuple>
std::string name;
Type type;
+
+ template<typename Value>
+ Equal<Column<Object, Field>, Value> operator==(Value value) const;
+ template<typename Value>
+ Greater<Column<Object, Field>, Value> operator>(Value value) const;
+ template<typename Value>
+ Lesser<Column<Object, Field>, Value> operator<(Value value) const;
};
+template<typename Object, typename Field>
+template<typename Value>
+Equal<Column<Object, Field>, Value> Column<Object, Field>::operator==(Value value) const
+{
+ return {*this, value};
+}
+
+template<typename Object, typename Field>
+template<typename Value>
+Greater<Column<Object, Field>, Value> Column<Object, Field>::operator>(Value value) const
+{
+ return {*this, value};
+}
+
+template<typename Object, typename Field>
+template<typename Value>
+Lesser<Column<Object, Field>, Value> Column<Object, Field>::operator<(Value value) const
+{
+ return {*this, value};
+}
+
} // namespace tsqb
} // namespace vist
+++ /dev/null
-/*
- * Copyright (c) 2017-present Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-#pragma once
-
-#include "type.hpp"
-
-namespace vist {
-namespace tsqb {
-namespace condition {
-
-struct Base {};
-
-template<typename L, typename R>
-struct And : public Base {
- L l;
- R r;
-
- And(L l, R r) : l(l), r(r) {}
- operator std::string() const
- {
- return "AND";
- }
-};
-
-template<typename L, typename R>
-struct Or : public Base {
- L l;
- R r;
-
- Or(L l, R r) : l(l), r(r) {}
- operator std::string() const
- {
- return "OR";
- }
-};
-
-template<typename L, typename R>
-struct Binary : public Base {
- L l;
- R r;
-
- Binary(L l, R r) : l(l), r(r)
- {
- using FieldType = typename L::FieldType;
- type::assert_compare(FieldType(), r);
- }
-};
-
-template<typename L>
-struct Binary<L, const char*> : public Base {
- L l;
- std::string r;
-
- Binary(L l, const char* r) : l(l), r(r)
- {
- using FieldType = typename L::FieldType;
- type::assert_compare(FieldType(), std::string());
- }
-};
-
-enum class Join : int {
- INNER,
- CROSS,
- LEFT_OUTER,
- RIGHT_OUTER,
- FULL_OUTER
-};
-
-inline std::string to_string(Join type)
-{
- switch (type) {
- case Join::CROSS: return "CROSS";
- case Join::LEFT_OUTER: return "LEFT OUTER";
- case Join::RIGHT_OUTER: return "RIGHT OUTER";
- case Join::FULL_OUTER: return "FULL OUTER";
- case Join::INNER:
- default:
- return "INNER";
- }
-}
-
-} // namespace condition
-} // namespace tsqb
-} // namespace vist
private:
template<typename L, typename R>
- std::string processWhere(condition::And<L,R>& expr);
+ std::string processWhere(And<L,R>& expr);
template<typename L, typename R>
- std::string processWhere(condition::Or<L,R>& expr);
+ std::string processWhere(Or<L,R>& expr);
template<typename Expr>
std::string processWhere(Expr expr);
template<typename T>
template<typename L, typename R>
-std::string Crud<T>::processWhere(condition::And<L,R>& expr)
+std::string Crud<T>::processWhere(And<L,R>& expr)
{
std::stringstream ss;
ss << this->processWhere(expr.l) << " ";
template<typename T>
template<typename L, typename R>
-std::string Crud<T>::processWhere(condition::Or<L,R>& expr)
+std::string Crud<T>::processWhere(Or<L,R>& expr)
{
std::stringstream ss;
ss << this->processWhere(expr.l) << " ";
#pragma once
#include "column.hpp"
-#include "condition.hpp"
#include "crud.hpp"
#include "expression.hpp"
#include "util.hpp"
explicit Database(const std::string& name, Tables ...tables) :
name(name), tables(tables...) {}
- template<typename Table>
- Self& join(condition::Join type = condition::Join::INNER);
-
- template<typename Expr>
- Self& on(Expr expr);
-
std::size_t size() const noexcept;
operator std::string();
};
template<typename... Tables>
-template<typename Table>
-Database<Tables...>& Database<Tables...>::join(condition::Join type)
-{
- std::stringstream ss;
- ss << condition::to_string(type) << " ";
- ss << "JOIN ";
- ss << this->getTableName(Table());
-
- this->cache.emplace_back(ss.str());
- return *this;
-}
-
-template<typename... Tables>
-template<typename Expr>
-Database<Tables...>& Database<Tables...>::on(Expr expr)
-{
- std::stringstream ss;
- ss << "ON ";
-
- auto lname = this->getColumnName(std::move(expr.l.type));
- ss << lname << " ";
-
- ss << std::string(expr) << " ";
-
- auto rname = this->getColumnName(std::move(expr.r.type));
- ss << rname;
-
- this->cache.emplace_back(ss.str());
- return *this;
-}
-
-template<typename... Tables>
Database<Tables...>::operator std::string()
{
std::stringstream ss;
#include "column.hpp"
#include "type.hpp"
-#include "condition.hpp"
+#include <string>
#include <type_traits>
namespace vist {
namespace tsqb {
-template<typename Type>
-struct Expression {
- Type value;
-};
+struct Expression {};
-template<typename O, typename F>
-Expression<Column<O, F>> expr(F O::*field)
-{
- Column<O, F> anonymous = {"anonymous", field};
- return {anonymous};
-}
+template<typename T>
+using is_expression = typename std::is_base_of<Expression, T>;
template<typename L, typename R>
-struct Lesser : public condition::Binary<L, R> {
- using condition::Binary<L, R>::Binary;
+struct Binary : public Expression {
+ L l;
+ R r;
- operator std::string() const
+ /// L is Column and R is Value
+ Binary(L l, R r) : l(l), r(r)
{
- return "<";
+ /// preventing logical expressions like &&, || and ==
+ if constexpr(!is_expression<L>::value) {
+ using FieldType = typename L::FieldType;
+ type::assert_compare(FieldType(), r);
+ }
}
};
-template<typename L, typename R>
-Lesser<L, R> operator<(Expression<L> expr, R r)
-{
- return {expr.value, r};
-}
+template<typename L>
+struct Binary<L, const char*> : public Expression {
+ L l;
+ std::string r;
+
+ Binary(L l, const char* r) : l(l), r(r)
+ {
+ using FieldType = typename L::FieldType;
+ type::assert_compare(FieldType(), std::string());
+ }
+};
template<typename L, typename R>
-struct Equal : public condition::Binary<L, R>
-{
- using condition::Binary<L, R>::Binary;
+struct Greater : public Binary<L, R> {
+ using Binary<L, R>::Binary;
operator std::string() const
{
- return "=";
+ return ">";
}
};
template<typename L, typename R>
-Equal<L, R> operator==(Expression<L> expr, R r)
-{
- return {expr.value, r};
-}
+struct Lesser : public Binary<L, R> {
+ using Binary<L, R>::Binary;
-namespace join {
+ operator std::string() const
+ {
+ return "<";
+ }
+};
template<typename L, typename R>
-struct Equal
-{
- L l;
- R r;
+struct Equal : public Binary<L, R> {
+ using Binary<L, R>::Binary;
operator std::string() const
{
}
};
-} // namespace join
-
-template<typename L, typename R>
-join::Equal<L, R> operator==(Expression<L> l, Expression<R> r)
-{
- return {l.value, r.value};
-}
-
template<typename L, typename R>
-struct Greater : public condition::Binary<L, R>
-{
- using condition::Binary<L, R>::Binary;
+struct And : public Binary<L, R> {
+ using Binary<L, R>::Binary;
operator std::string() const
{
- return ">";
+ return "AND";
}
};
template<typename L, typename R>
-Greater<L, R> operator>(Expression<L> expr, R r)
-{
- return {expr.value, r};
-}
-
-template<bool B, typename T = void>
-using enable_if_t = typename std::enable_if<B, T>::type;
+struct Or : public Binary<L, R> {
+ using Binary<L, R>::Binary;
-template<typename T>
-using is_condition = typename std::is_base_of<condition::Base, T>;
+ operator std::string() const
+ {
+ return "OR";
+ }
+};
template<typename L,
typename R,
- typename = typename tsqb::enable_if_t<is_condition<L>::value
- && tsqb::is_condition<R>::value>>
-condition::And<L, R> operator&&(const L& l, const R& r)
+ typename = typename std::enable_if_t<is_expression<L>::value &&
+ is_expression<R>::value>>
+And<L, R> operator&&(const L& l, const R& r)
{
return {l, r};
}
template<typename L,
typename R,
- typename = typename tsqb::enable_if_t<is_condition<L>::value
- && tsqb::is_condition<R>::value>>
-condition::Or<L, R> operator||(const L& l, const R& r)
+ typename = typename std::enable_if_t<is_expression<L>::value &&
+ is_expression<R>::value>>
+Or<L, R> operator||(const L& l, const R& r)
{
return {l, r};
}
--- /dev/null
+/*
+ * Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include <gtest/gtest.h>
+
+#include "schema.hpp"
+
+using namespace vist::tsqb;
+using namespace vist::test;
+
+TEST(QueryBuilderExpressionTests, equal)
+{
+ std::string dump = (Table1::Column1 == 3);
+ EXPECT_EQ(dump, "=");
+}
+
+TEST(QueryBuilderExpressionTests, greater)
+{
+ std::string dump = (Table1::Column1 > 3);
+ EXPECT_EQ(dump, ">");
+}
+
+TEST(QueryBuilderExpressionTests, lesser)
+{
+ std::string dump = (Table1::Column1 < 3);
+ EXPECT_EQ(dump, "<");
+}
TEST(QueryBuilderTsqbTests, SELECT_WHERE)
{
std::string select1 = AdminTable.select(Admin::Uid, Admin::Key)
- .where(expr(&Admin::id) > 3);
- std::string select2 = admin.selectAll().where(expr(&Admin::uid) > 3);
- std::string select3 = admin.selectAll().where(expr(&Admin::uid) > 3 &&
- expr(&Admin::pkg) == "dpm");
- std::string select4 = admin.selectAll().where(expr(&Admin::uid) > 3 ||
- expr(&Admin::pkg) == "dpm");
+ .where(Admin::Id > 3);
+ std::string select2 = admin.selectAll().where(Admin::Uid > 3);
+ std::string select3 = admin.selectAll().where(Admin::Uid > 3 &&
+ Admin::Pkg == "dpm");
+ std::string select4 = admin.selectAll().where(Admin::Uid > 3 ||
+ Admin::Pkg == "dpm");
EXPECT_EQ(select1, "SELECT uid, key FROM admin WHERE id > ?");
EXPECT_EQ(select2, "SELECT * FROM admin WHERE uid > ?");
{
int uid = 0, id = 1;
std::string update1 = admin.update(Admin::Id, Admin::Pkg, Admin::Uid, Admin::Key);
- std::string update2 = admin.update(Admin::Key).where(expr(&Admin::uid) == uid &&
- expr(&Admin::id) == id);
+ std::string update2 = admin.update(Admin::Key).where((Admin::Uid == uid) &&
+ (Admin::Id == id));
std::string update3 = admin.update(Admin::Key, Admin::Pkg)
- .where(expr(&Admin::uid) == 0 && expr(&Admin::id) == 1);
+ .where((Admin::Uid == 0) && (Admin::Id == 1));
EXPECT_EQ(update1, "UPDATE admin SET id = ?, pkg = ?, uid = ?, key = ?");
EXPECT_EQ(update2, "UPDATE admin SET key = ? WHERE uid = ? AND id = ?");
TEST(QueryBuilderTsqbTests, DELETE)
{
std::string delete1 = admin.remove();
- std::string delete2 = admin.remove().where(expr(&Admin::pkg) == "dpm" &&
- expr(&Admin::uid) == 3);
+ std::string delete2 = admin.remove().where((Admin::Pkg == "dpm") &&
+ (Admin::Uid == 3));
EXPECT_EQ(delete1, "DELETE FROM admin");
EXPECT_EQ(delete2, "DELETE FROM admin WHERE pkg = ? AND uid = ?");
/*
* Below cause complie error since expression types are dismatch.
- std::string type_unsafe1 = admin.selectAll().where(expr(&Admin::uid) > "dpm");
- std::string type_unsafe2 = admin.selectAll().where(expr(&Admin::uid) == "dpm");
- std::string type_unsafe3 = admin.selectAll().where(expr(&Admin::pkg) == 3);
+ std::string type_unsafe1 = admin.selectAll().where(Admin::Uid > "dpm");
+ std::string type_unsafe2 = admin.selectAll().where(Admin::Uid == "dpm");
+ std::string type_unsafe3 = admin.selectAll().where(Admin::Pkg == 3);
int pkg = 3;
- std::string type_unsafe4 = admin.selectAll().where(expr(&Admin::pkg) < pkg);
- std::string type_unsafe5 = admin.remove().where(expr(&Admin::pkg) == "dpm" &&
- expr(&Admin::uid) == "dpm");
+ std::string type_unsafe4 = admin.selectAll().where(Admin::Pkg) < pkg);
+ std::string type_unsafe5 = admin.remove().where(Admin::Pkg) == "dpm" &&
+ Admin::Uid) == "dpm");
*/
}
ManagedPolicy::Id, ManagedPolicy::Value);
std::string multiSelect2 = db.select(Admin::Uid, Admin::Key,
ManagedPolicy::Id, ManagedPolicy::Value)
- .where(expr(&Admin::uid) > 0 && expr(&ManagedPolicy::id) == 3);
+ .where((Admin::Uid > 0) && (ManagedPolicy::Id == 3));
EXPECT_EQ(multiSelect1, "SELECT admin.uid, admin.key, managed_policy.id, "
"managed_policy.value FROM admin, managed_policy");
.join<ManagedPolicy>(condition::Join::CROSS);
std::string join3 = db.select(ManagedPolicy::Value)
.join<PolicyDefinition>()
- .on(expr(&ManagedPolicy::pid) == expr(&PolicyDefinition::id))
+ .on(ManagedPolicy::Pid) == PolicyDefinition::Id))
.join<Admin>()
- .on(expr(&ManagedPolicy::aid) == expr(&Admin::id))
- .where(expr(&ManagedPolicy::pid) == 99);
+ .on(ManagedPolicy::Aid) == Admin::Id))
+ .where(ManagedPolicy::Pid) == 99);
EXPECT_EQ(join1, "SELECT admin.uid, admin.key FROM admin "
"LEFT OUTER JOIN policy_definition");