From dde5ff2112771c7b12c19b7124b2a0b5a36695c6 Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Thu, 30 Jan 2020 13:13:32 +0900 Subject: [PATCH] c++17: Refactor database with generic lambda Signed-off-by: Sangwan Kwon --- src/vist/query-builder/column-pack.hpp | 77 ----------------- src/vist/query-builder/database.hpp | 152 +++++++++++++++++---------------- src/vist/query-builder/table-pack.hpp | 78 ----------------- src/vist/query-builder/tests/table.cpp | 11 --- 4 files changed, 77 insertions(+), 241 deletions(-) delete mode 100644 src/vist/query-builder/column-pack.hpp delete mode 100644 src/vist/query-builder/table-pack.hpp diff --git a/src/vist/query-builder/column-pack.hpp b/src/vist/query-builder/column-pack.hpp deleted file mode 100644 index 7c759f3..0000000 --- a/src/vist/query-builder/column-pack.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 "tuple-helper.hpp" -#include "type.hpp" - -#include -#include -#include - -namespace vist { -namespace tsqb { -namespace internal { - -template -class ColumnPack final { -public: - using TableType = typename std::tuple_element<0, std::tuple>::type::TableType; - using TupleType = std::tuple; - - explicit ColumnPack(Columns&& ...columns) : columns(columns...) - { - } - - template - std::string getName(const Column& column) const noexcept - { - std::string name; - auto predicate = [&name, &column](const auto& iter) { - if (type::cast_compare(column, iter.type)) - name = iter.name; - }; - - tuple_helper::for_each(this->columns, predicate); - - return name; - } - - std::vector getNames(void) const noexcept - { - std::vector names; - auto closure = [&names](const auto& iter) { - names.push_back(iter.name); - }; - - tuple_helper::for_each(this->columns, closure); - - return names; - } - - std::size_t size() const noexcept - { - return std::tuple_size::value; - } - -private: - std::tuple columns; -}; - -} // namespace internal -} // namespace tsqb -} // namespace vist diff --git a/src/vist/query-builder/database.hpp b/src/vist/query-builder/database.hpp index 9cfa109..b9dee5f 100644 --- a/src/vist/query-builder/database.hpp +++ b/src/vist/query-builder/database.hpp @@ -16,18 +16,19 @@ #pragma once -#include "crud.hpp" +#include "column.hpp" #include "condition.hpp" +#include "crud.hpp" #include "expression.hpp" -#include "table-pack.hpp" #include "tuple-helper.hpp" #include "util.hpp" -#include +#include #include -#include #include -#include +#include +#include +#include namespace vist { namespace tsqb { @@ -37,15 +38,22 @@ class Database : public Crud> { public: using Self = Database; - virtual ~Database() = default; + explicit Database(const std::string& name, Tables ...tables) : + name(name), tables(tables...) {} + + template + Self& join(condition::Join type = condition::Join::INNER); + + template + Self& on(Expr expr); + + std::size_t size() const noexcept; - Database(const Database&) = delete; - Database& operator=(const Database&) = delete; + operator std::string(); - Database(Database&&) = default; - Database& operator=(Database&&) = default; + std::string name; - // Functions for Crud +public: // CRTP(Curiously Recurring Template Pattern) for CRUD template std::set getTableNames(Cs&& tuple) const noexcept; template @@ -55,73 +63,24 @@ public: template std::string getColumnName(ColumnType&& type) const noexcept; - template - Self& join(condition::Join type = condition::Join::INNER); - - template - Self& on(Expr expr); - - operator std::string(); - - std::string name; std::vector cache; private: - using TablePackType = internal::TablePack; using ColumnNames = std::vector; using TableNames = std::set; - explicit Database(const std::string& name, TablePackType&& tablePack); - template friend Database make_database(const std::string& name, Ts&& ...tables); - struct GetTableNames { - const TablePackType& tablePack; - std::set names; - GetTableNames(const TablePackType& tablePack) : tablePack(tablePack) {} - - template - void operator()(T&& type) - { - auto column = make_column("anonymous", type); - using TableType = typename decltype(column)::Table; - auto name = this->tablePack.getName(TableType()); - if (!name.empty()) - names.emplace(name); - } - }; - - struct GetColumnNames { - const TablePackType& tablePack; - std::vector names; - - GetColumnNames(const TablePackType& tablePack) : tablePack(tablePack) {} - - template - void operator()(T&& type) - { - auto column = make_column("anonymous", type); - auto name = this->tablePack.getColumnName(std::move(column)); - if (!name.empty()) - names.emplace_back(name); - } - }; - - TablePackType tablePack; + std::tuple tables; }; template Database make_database(const std::string& name, Tables&& ...tables) { - auto tablePack = internal::TablePack(std::forward(tables)...); - return Database(name, std::move(tablePack)); + return Database(name, std::forward(tables)...); } -template -Database::Database(const std::string& name, TablePackType&& tablePack) - : name(name), tablePack(std::move(tablePack)) {} - template template Database& Database::join(condition::Join type) @@ -129,7 +88,7 @@ Database& Database::join(condition::Join type) std::stringstream ss; ss << condition::to_string(type) << " "; ss << "JOIN "; - ss << this->tablePack.getName(Table()); + ss << this->getTableName(Table()); this->cache.emplace_back(ss.str()); return *this; @@ -142,12 +101,12 @@ Database& Database::on(Expr expr) std::stringstream ss; ss << "ON "; - auto lname = this->tablePack.getColumnName(std::move(expr.l)); + auto lname = this->getColumnName(std::move(expr.l.type)); ss << lname << " "; ss << std::string(expr) << " "; - auto rname = this->tablePack.getColumnName(std::move(expr.r)); + auto rname = this->getColumnName(std::move(expr.r.type)); ss << rname; this->cache.emplace_back(ss.str()); @@ -169,35 +128,78 @@ template template std::set Database::getTableNames(Cs&& tuple) const noexcept { - GetTableNames closure(this->tablePack); + std::set names; + + auto closure = [this, &names](const auto& type) { + auto column = make_column("anonymous", type); + using TableType = typename decltype(column)::Table; + auto name = this->getTableName(TableType()); + if (!name.empty()) + names.emplace(name); + }; + tuple_helper::for_each(std::forward(tuple), closure); - return closure.names; + return names; } template template std::vector Database::getColumnNames(Cs&& tuple) const noexcept { - GetColumnNames closure(this->tablePack); + std::vector names; + auto closure = [this, &names](const auto& iter) { + auto name = this->getColumnName(iter); + if (!name.empty()) + names.emplace_back(name); + }; + tuple_helper::for_each(std::forward(tuple), closure); - return closure.names; + return names; } template -template -std::string Database::getTableName(TableType&& type) const noexcept +template +std::string Database::getTableName(Table&& table) const noexcept { - return this->tablePack.getName(std::forward(type)); + std::string name; + auto predicate = [&name, &table](const auto& iter) { + if (iter.compare(table)) + name = iter.name; + }; + + tuple_helper::for_each(this->tables, predicate); + + return name; } template template -std::string Database::getColumnName(ColumnType&& type) const noexcept +std::string Database::getColumnName(ColumnType&& column) const noexcept +{ + Column anonymous("anonymous", column); + using TableType = typename decltype(anonymous)::Table; + TableType table; + + std::string name; + auto predicate = [&name, &table, &column](const auto& iter) { + if (iter.compare(table)) { + auto cname = iter.getColumnName(column); + name = iter.name + "." + cname; + } + }; + + tuple_helper::for_each(this->tables, predicate); + + return name; +} + +template +std::size_t Database::size() const noexcept { - auto column = make_column("anonymous", type); - return this->tablePack.getColumnName(std::move(column)); + using TupleType = std::tuple; + return std::tuple_size::value; } } // namespace tsqb diff --git a/src/vist/query-builder/table-pack.hpp b/src/vist/query-builder/table-pack.hpp deleted file mode 100644 index d76b309..0000000 --- a/src/vist/query-builder/table-pack.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 "tuple-helper.hpp" - -#include -#include -#include -#include - -namespace vist { -namespace tsqb { -namespace internal { - -template -class TablePack final { -public: - using TupleType = std::tuple; - - explicit TablePack(Tables ...tables) : tables(tables...) - { - } - - template - std::string getName(TableType&& table) const noexcept - { - std::string name; - auto predicate = [&name, &table](const auto& iter) { - if (iter.compare(table)) - name = iter.name; - }; - - tuple_helper::for_each(this->tables, predicate); - - return name; - } - - template - std::string getColumnName(ColumnType&& column) const noexcept - { - using TableType = typename ColumnType::Table; - - std::string name; - TableType table; - auto predicate = [&name, &table, column](const auto& iter) { - if (iter.compare(table)) { - auto cname = iter.getColumnName(column.type); - name = iter.name + "." + cname; - } - }; - - tuple_helper::for_each(this->tables, predicate); - - return name; - } - -private: - std::tuple tables; -}; - -} // namespace internal -} // namespace tsqb -} // namespace vist diff --git a/src/vist/query-builder/tests/table.cpp b/src/vist/query-builder/tests/table.cpp index dda8ca9..038482a 100644 --- a/src/vist/query-builder/tests/table.cpp +++ b/src/vist/query-builder/tests/table.cpp @@ -17,11 +17,9 @@ #include #include -#include #include using namespace vist::tsqb; -using namespace vist::tsqb::internal; namespace { @@ -49,8 +47,6 @@ Table table2 { "table2", Column("column1", &Table2::column1), Column("column4", &Table2::column4), Column("column5", &Table2::column5) }; -TablePack tables { table1, table2 }; - } // anonymous namespace TEST(TableTests, size) @@ -85,10 +81,3 @@ TEST(TableTests, compare) { EXPECT_TRUE(table1.compare(Table1())); } - -TEST(TableTests, pack_get_column) -{ - EXPECT_EQ(tables.getColumnName(Column("anonymous", &Table1::column1)), "table1.column1"); - EXPECT_EQ(tables.getColumnName(Column("anonymous", &Table1::column2)), "table1.column2"); - EXPECT_EQ(tables.getColumnName(Column("anonymous", &Table1::column3)), "table1.column3"); -} -- 2.7.4