From 08426fdaf9a551719e761c7754709f987d6f0d22 Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Mon, 1 Jul 2019 07:24:21 +0900 Subject: [PATCH] Apply CRTP idiom to database Signed-off-by: Sangwan Kwon --- tsqb/include/crud.hxx | 13 ++++- tsqb/include/database.hxx | 132 ++++++++-------------------------------------- tsqb/include/table.hxx | 14 ++++- 3 files changed, 46 insertions(+), 113 deletions(-) diff --git a/tsqb/include/crud.hxx b/tsqb/include/crud.hxx index 099719a..fe67524 100644 --- a/tsqb/include/crud.hxx +++ b/tsqb/include/crud.hxx @@ -104,6 +104,8 @@ Table& Crud::selectInternal(ColumnTuple&& ct, bool distinct) static_cast(this)->cache.clear(); auto columnNames = static_cast(this)->getColumnNames(std::move(ct)); + auto tableNames = static_cast(this)->getTableNames(std::move(ct)); + std::stringstream ss; ss << "SELECT "; @@ -118,7 +120,16 @@ Table& Crud
::selectInternal(ColumnTuple&& ct, bool distinct) ss << ", "; } - ss << " FROM " << static_cast(this)->name; + ss << " FROM "; + + i = 0; + for (const auto& t : tableNames) { + ss << t; + + if (i++ < tableNames.size() - 1) + ss << ", "; + } + static_cast(this)->cache.emplace_back(ss.str()); return *(static_cast(this)); diff --git a/tsqb/include/database.hxx b/tsqb/include/database.hxx index 27c26e9..89a6f03 100644 --- a/tsqb/include/database.hxx +++ b/tsqb/include/database.hxx @@ -21,31 +21,33 @@ #pragma once +#include "crud.hxx" +#include "condition.hxx" +#include "expression.hxx" +#include "table-pack.hxx" +#include "tuple-helper.hxx" +#include "util.hxx" + #include #include #include #include #include -#include "table-pack.hxx" -#include "tuple-helper.hxx" -#include "condition.hxx" -#include "expression.hxx" -#include "util.hxx" - namespace tsqb { template -class Database { +class Database : public Crud> { public: using Self = Database; - // TODO(Sangwan): Use Crud class - template - Self& select(ColumnTypes&&... cts); - - template - Self& where(Expr expr); + // Functions for Crud + template + std::set getTableNames(Cs&& tuple) const noexcept; + template + std::vector getColumnNames(Cs&& tuple) const noexcept; + template + std::string getColumnName(ColumnType&& type) const noexcept; template Self& join(condition::Join type = condition::Join::INNER); @@ -56,6 +58,7 @@ public: operator std::string(); std::string name; + std::vector cache; private: using TablePackType = internal::TablePack; @@ -67,12 +70,6 @@ private: template friend Database make_database(const std::string& name, Ts&& ...tables); - template - std::set getTableNames(Cs&& tuple); - - template - std::vector getColumnNames(Cs&& tuple); - struct GetTableNames { TablePackType tablePack; std::set names; @@ -105,17 +102,7 @@ private: } }; - template - std::string processWhere(condition::And& expr); - - template - std::string processWhere(condition::Or& expr); - - template - std::string processWhere(Expr expr); - TablePackType tablePack; - std::vector cache; }; template @@ -130,54 +117,6 @@ Database::Database(const std::string& name, TablePackType&& tablePack : name(name), tablePack(std::move(tablePack)) {} template -template -Database& Database::select(ColumnTypes&&... cts) -{ - this->cache.clear(); - - auto columnTuple = std::make_tuple(std::forward(cts)...); - auto columnNames = this->getColumnNames(std::move(columnTuple)); - auto tableNames = this->getTableNames(std::move(columnTuple)); - - std::stringstream ss; - ss << "SELECT "; - - int i = 0; - for (const auto& c : columnNames) { - ss << c; - - if (i++ < columnNames.size() - 1) - ss << ", "; - } - - ss << " FROM "; - - i = 0; - for (const auto& t : tableNames) { - ss << t; - - if (i++ < tableNames.size() - 1) - ss << ", "; - } - - cache.emplace_back(ss.str()); - - return *this; -} - -template -template -Database& Database::where(Expr expr) -{ - std::stringstream ss; - ss << "WHERE " << this->processWhere(expr); - - this->cache.emplace_back(ss.str()); - - return *this; -} - -template template Database& Database::join(condition::Join type) { @@ -222,7 +161,7 @@ Database::operator std::string() template template -std::set Database::getTableNames(Cs&& tuple) +std::set Database::getTableNames(Cs&& tuple) const noexcept { GetTableNames closure(this->tablePack); tuple_helper::for_each(std::forward(tuple), closure); @@ -232,7 +171,7 @@ std::set Database::getTableNames(Cs&& tuple) template template -std::vector Database::getColumnNames(Cs&& tuple) +std::vector Database::getColumnNames(Cs&& tuple) const noexcept { GetColumnNames closure(this->tablePack); tuple_helper::for_each(std::forward(tuple), closure); @@ -241,38 +180,11 @@ std::vector Database::getColumnNames(Cs&& tuple) } template -template -std::string Database::processWhere(condition::And& expr) -{ - std::stringstream ss; - ss << this->processWhere(expr.l) << " "; - ss << static_cast(expr) << " "; - ss << this->processWhere(expr.r); - - return ss.str(); -} - -template -template -std::string Database::processWhere(condition::Or& expr) -{ - std::stringstream ss; - ss << this->processWhere(expr.l) << " "; - ss << static_cast(expr) << " "; - ss << this->processWhere(expr.r); - - return ss.str(); -} - -template -template -std::string Database::processWhere(Expr expr) +template +std::string Database::getColumnName(ColumnType&& type) const noexcept { - std::stringstream ss; - ss << this->tablePack.getColumnName(expr.l); - ss << " " << std::string(expr) << " ?"; - - return ss.str(); + auto column = make_column("anonymous", type); + return this->tablePack.getColumnName(std::move(column)); } } // namespace tsqb diff --git a/tsqb/include/table.hxx b/tsqb/include/table.hxx index 439002b..1d6df59 100644 --- a/tsqb/include/table.hxx +++ b/tsqb/include/table.hxx @@ -40,11 +40,14 @@ public: using ColumnPackType = internal::ColumnPack; using TableType = typename ColumnPackType::TableType; + // Functions for Crud + template + std::vector getColumnNames(Cs&& tuple) const noexcept; + template + std::set getTableNames(Cs&& tuple) const noexcept; template std::string getColumnName(ColumnType&& type) const noexcept; - template - std::vector getColumnNames(Cs&& tuple) const noexcept; std::vector getColumnNames(void) const noexcept; template @@ -94,6 +97,13 @@ Table::Table(const std::string& name, ColumnPackType&& columnPack) template template +std::set Table::getTableNames(Cs&& tuple) const noexcept +{ + return {this->name}; +} + +template +template std::vector Table::getColumnNames(Cs&& tuple) const noexcept { GetColumnNames closure(this->columnPack); -- 2.7.4