From da71fd107e417deb4abeac40f749a254869ab859 Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Thu, 30 Jan 2020 14:23:23 +0900 Subject: [PATCH] Refactor CRTP functions Signed-off-by: Sangwan Kwon --- src/vist/query-builder/crud.hpp | 29 +++++----- src/vist/query-builder/database.hpp | 27 +++++---- src/vist/query-builder/table.hpp | 19 ++++--- src/vist/query-builder/tests/database.cpp | 91 +++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 39 deletions(-) create mode 100644 src/vist/query-builder/tests/database.cpp diff --git a/src/vist/query-builder/crud.hpp b/src/vist/query-builder/crud.hpp index ded5080..a53f64d 100644 --- a/src/vist/query-builder/crud.hpp +++ b/src/vist/query-builder/crud.hpp @@ -52,8 +52,8 @@ public: T& where(Expr expr); private: - template - T& selectInternal(ColumnTuple&& ct, bool distinct = false); + template + T& selectInternal(bool distinct, ColumnTypes&& ...cts); template std::string processWhere(condition::And& expr); @@ -69,16 +69,14 @@ template template T& Crud::select(ColumnTypes&&... cts) { - auto columnTuple = std::make_tuple(std::forward(cts)...); - - return this->selectInternal(std::move(columnTuple)); + return this->selectInternal(false, std::forward(cts)...); } template template T& Crud::select(Distinct distinct) { - return this->selectInternal(std::move(distinct.value), true); + return this->selectInternal(true, std::move(distinct.value)); } template @@ -110,13 +108,15 @@ T& Crud::selectAll(void) } template -template -T& Crud::selectInternal(ColumnTuple&& ct, bool distinct) +template +T& Crud::selectInternal(bool distinct, ColumnTypes&& ...cts) { static_cast(this)->cache.clear(); - auto columnNames = static_cast(this)->getColumnNames(std::move(ct)); - auto tableNames = static_cast(this)->getTableNames(std::move(ct)); + auto columnNames = static_cast(this)->getColumnNames(std::forward(cts)...); + + auto tuple = std::tuple(cts...); + auto tableNames = static_cast(this)->getTableNames(std::move(tuple)); std::stringstream ss; ss << "SELECT "; @@ -153,8 +153,7 @@ T& Crud::update(ColumnTypes&&... cts) { static_cast(this)->cache.clear(); - auto columnTuple = std::make_tuple(std::forward(cts)...); - auto columnNames = static_cast(this)->getColumnNames(std::move(columnTuple)); + auto columnNames = static_cast(this)->getColumnNames(std::forward(cts)...); std::stringstream ss; ss << "UPDATE " << static_cast(this)->name << " "; @@ -179,8 +178,7 @@ T& Crud::insert(ColumnTypes&&... cts) { static_cast(this)->cache.clear(); - auto columnTuple = std::make_tuple(std::forward(cts)...); - auto columnNames = static_cast(this)->getColumnNames(std::move(columnTuple)); + auto columnNames = static_cast(this)->getColumnNames(std::forward(cts)...); std::stringstream ss; ss << "INSERT INTO " << static_cast(this)->name << " ("; @@ -213,8 +211,7 @@ T& Crud::remove(ColumnTypes&&... cts) { static_cast(this)->cache.clear(); - auto columnTuple = std::make_tuple(std::forward(cts)...); - auto columnNames = static_cast(this)->getColumnNames(std::move(columnTuple)); + auto columnNames = static_cast(this)->getColumnNames(std::forward(cts)...); std::stringstream ss; ss << "DELETE FROM " << static_cast(this)->name; diff --git a/src/vist/query-builder/database.hpp b/src/vist/query-builder/database.hpp index b9dee5f..a614130 100644 --- a/src/vist/query-builder/database.hpp +++ b/src/vist/query-builder/database.hpp @@ -54,10 +54,10 @@ public: std::string name; public: // CRTP(Curiously Recurring Template Pattern) for CRUD - template - std::set getTableNames(Cs&& tuple) const noexcept; - template - std::vector getColumnNames(Cs&& tuple) const noexcept; + template + std::vector getTableNames(Cs&& ...columns) const noexcept; + template + std::vector getColumnNames(Cs&& ...columns) const noexcept; template std::string getTableName(TableType&& type) const noexcept; template @@ -66,9 +66,6 @@ public: // CRTP(Curiously Recurring Template Pattern) for CRUD std::vector cache; private: - using ColumnNames = std::vector; - using TableNames = std::set; - template friend Database make_database(const std::string& name, Ts&& ...tables); @@ -125,8 +122,8 @@ Database::operator std::string() } template -template -std::set Database::getTableNames(Cs&& tuple) const noexcept +template +std::vector Database::getTableNames(Cs&& ...columns) const noexcept { std::set names; @@ -138,14 +135,15 @@ std::set Database::getTableNames(Cs&& tuple) const noexc names.emplace(name); }; - tuple_helper::for_each(std::forward(tuple), closure); + auto tuple = std::tuple(columns...); + tuple_helper::for_each(tuple, closure); - return names; + return std::vector(names.begin(), names.end()); } template -template -std::vector Database::getColumnNames(Cs&& tuple) const noexcept +template +std::vector Database::getColumnNames(Cs&& ...columns) const noexcept { std::vector names; auto closure = [this, &names](const auto& iter) { @@ -154,7 +152,8 @@ std::vector Database::getColumnNames(Cs&& tuple) const n names.emplace_back(name); }; - tuple_helper::for_each(std::forward(tuple), closure); + auto tuple = std::tuple(columns...); + tuple_helper::for_each(tuple, closure); return names; } diff --git a/src/vist/query-builder/table.hpp b/src/vist/query-builder/table.hpp index 3ec559d..ed2e27f 100644 --- a/src/vist/query-builder/table.hpp +++ b/src/vist/query-builder/table.hpp @@ -52,12 +52,12 @@ public: const std::string name; public: // CRTP(Curiously Recurring Template Pattern) for CRUD - template - std::set getTableNames(Cs&& tuple) const noexcept; + template + std::vector getTableNames(Cs&& ...coulmns) const noexcept; template std::string getTableName(That&& type) const noexcept; - template - std::vector getColumnNames(Cs&& tuple) const noexcept; + template + std::vector getColumnNames(Cs&& ...columns) const noexcept; template std::string getColumnName(const Column& column) const noexcept; @@ -83,15 +83,15 @@ std::string Table::getName() const noexcept } template -template -std::set Table::getTableNames(Cs&&) const noexcept +template +std::vector Table::getTableNames(Cs&& ...) const noexcept { return {this->name}; } template -template -std::vector Table::getColumnNames(Cs&& tuple) const noexcept +template +std::vector Table::getColumnNames(Cs&& ...columns) const noexcept { std::vector names; auto closure = [this, &names](auto type) { @@ -100,7 +100,8 @@ std::vector Table::getColumnNames(Cs&& tuple) const noe names.emplace_back(name); }; - tuple_helper::for_each(std::forward(tuple), closure); + auto tuple = std::tuple(columns...); + tuple_helper::for_each(tuple, closure); return names; } diff --git a/src/vist/query-builder/tests/database.cpp b/src/vist/query-builder/tests/database.cpp new file mode 100644 index 0000000..5e23ddb --- /dev/null +++ b/src/vist/query-builder/tests/database.cpp @@ -0,0 +1,91 @@ +/* + * 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 + +#include +#include +#include + +using namespace vist::tsqb; + +namespace { + +struct Table1 { + int column1; + std::string column2; + bool column3; +}; + +struct Table2 { + int column1; + std::string column2; + bool column3; + float column4; + double column5; +}; + +Table table1 { "table1", Column("column1", &Table1::column1), + Column("column2", &Table1::column2), + Column("column3", &Table1::column3) }; + +Table table2 { "table2", Column("column1", &Table2::column1), + Column("column2", &Table2::column2), + Column("column3", &Table2::column3), + Column("column4", &Table2::column4), + Column("column5", &Table2::column5) }; + +Database database { "database", table1, table2 }; + +} // anonymous namespace + +TEST(DatabaseTests, size) +{ + EXPECT_EQ(database.size(), 2); +} + +TEST(DatabaseTests, get_name) +{ + EXPECT_EQ(database.name, "database"); + + EXPECT_EQ(database.getTableName(Table1()), "table1"); + EXPECT_EQ(database.getTableName(Table2()), "table2"); + + EXPECT_EQ(database.getColumnName(&Table1::column1), "table1.column1"); + EXPECT_EQ(database.getColumnName(&Table1::column2), "table1.column2"); + EXPECT_EQ(database.getColumnName(&Table1::column3), "table1.column3"); + + EXPECT_EQ(database.getColumnName(&Table2::column1), "table2.column1"); + EXPECT_EQ(database.getColumnName(&Table2::column2), "table2.column2"); + EXPECT_EQ(database.getColumnName(&Table2::column3), "table2.column3"); + EXPECT_EQ(database.getColumnName(&Table2::column4), "table2.column4"); + EXPECT_EQ(database.getColumnName(&Table2::column5), "table2.column5"); +} + +TEST(DatabaseTests, get_names) +{ + auto columns = database.getColumnNames(&Table1::column1, &Table2::column3); + auto tables = database.getTableNames(&Table1::column1, &Table2::column1, &Table2::column1); + if (columns.size() == 2 && tables.size() == 2) { + EXPECT_EQ(columns[0], "table1.column1"); + EXPECT_EQ(columns[1], "table2.column3"); + + EXPECT_EQ(tables[0], "table1"); + EXPECT_EQ(tables[1], "table2"); + } else { + EXPECT_TRUE(false); + } +} -- 2.7.4