+++ /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 "tuple-helper.hpp"
-#include "type.hpp"
-
-#include <string>
-#include <tuple>
-#include <vector>
-
-namespace vist {
-namespace tsqb {
-namespace internal {
-
-template<typename... Columns>
-class ColumnPack final {
-public:
- using TableType = typename std::tuple_element<0, std::tuple<Columns...>>::type::TableType;
- using TupleType = std::tuple<Columns...>;
-
- explicit ColumnPack(Columns&& ...columns) : columns(columns...)
- {
- }
-
- template<typename Column>
- 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<std::string> getNames(void) const noexcept
- {
- std::vector<std::string> 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<TupleType>::value;
- }
-
-private:
- std::tuple<Columns...> columns;
-};
-
-} // namespace internal
-} // namespace tsqb
-} // namespace vist
#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 <vector>
+#include <algorithm>
#include <set>
-#include <string>
#include <sstream>
-#include <algorithm>
+#include <string>
+#include <tuple>
+#include <vector>
namespace vist {
namespace tsqb {
public:
using Self = Database<Tables...>;
- virtual ~Database() = default;
+ 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;
- 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<typename Cs>
std::set<std::string> getTableNames(Cs&& tuple) const noexcept;
template<typename Cs>
template<typename ColumnType>
std::string getColumnName(ColumnType&& type) const noexcept;
- template<typename Table>
- Self& join(condition::Join type = condition::Join::INNER);
-
- template<typename Expr>
- Self& on(Expr expr);
-
- operator std::string();
-
- std::string name;
std::vector<std::string> cache;
private:
- using TablePackType = internal::TablePack<Tables...>;
using ColumnNames = std::vector<std::string>;
using TableNames = std::set<std::string>;
- explicit Database(const std::string& name, TablePackType&& tablePack);
-
template<typename ...Ts>
friend Database<Ts...> make_database(const std::string& name, Ts&& ...tables);
- struct GetTableNames {
- const TablePackType& tablePack;
- std::set<std::string> names;
- GetTableNames(const TablePackType& tablePack) : tablePack(tablePack) {}
-
- template <typename T>
- 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<std::string> names;
-
- GetColumnNames(const TablePackType& tablePack) : tablePack(tablePack) {}
-
- template <typename T>
- 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...> tables;
};
template<typename ...Tables>
Database<Tables...> make_database(const std::string& name, Tables&& ...tables)
{
- auto tablePack = internal::TablePack<Tables...>(std::forward<Tables>(tables)...);
- return Database<Tables...>(name, std::move(tablePack));
+ return Database<Tables...>(name, std::forward<Tables>(tables)...);
}
-template<typename ...Tables>
-Database<Tables...>::Database(const std::string& name, TablePackType&& tablePack)
- : name(name), tablePack(std::move(tablePack)) {}
-
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->tablePack.getName(Table());
+ ss << this->getTableName(Table());
this->cache.emplace_back(ss.str());
return *this;
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());
template<typename Cs>
std::set<std::string> Database<Tables...>::getTableNames(Cs&& tuple) const noexcept
{
- GetTableNames closure(this->tablePack);
+ std::set<std::string> 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<Cs>(tuple), closure);
- return closure.names;
+ return names;
}
template<typename... Tables>
template<typename Cs>
std::vector<std::string> Database<Tables...>::getColumnNames(Cs&& tuple) const noexcept
{
- GetColumnNames closure(this->tablePack);
+ std::vector<std::string> 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<Cs>(tuple), closure);
- return closure.names;
+ return names;
}
template<typename... Tables>
-template<typename TableType>
-std::string Database<Tables...>::getTableName(TableType&& type) const noexcept
+template<typename Table>
+std::string Database<Tables...>::getTableName(Table&& table) const noexcept
{
- return this->tablePack.getName(std::forward<TableType>(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<typename... Tables>
template<typename ColumnType>
-std::string Database<Tables...>::getColumnName(ColumnType&& type) const noexcept
+std::string Database<Tables...>::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<typename... Tables>
+std::size_t Database<Tables...>::size() const noexcept
{
- auto column = make_column("anonymous", type);
- return this->tablePack.getColumnName(std::move(column));
+ using TupleType = std::tuple<Tables...>;
+ return std::tuple_size<TupleType>::value;
}
} // namespace tsqb
+++ /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 "tuple-helper.hpp"
-
-#include <set>
-#include <string>
-#include <tuple>
-#include <vector>
-
-namespace vist {
-namespace tsqb {
-namespace internal {
-
-template<typename... Tables>
-class TablePack final {
-public:
- using TupleType = std::tuple<Tables...>;
-
- explicit TablePack(Tables ...tables) : tables(tables...)
- {
- }
-
- template<typename TableType>
- 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<typename ColumnType>
- 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...> tables;
-};
-
-} // namespace internal
-} // namespace tsqb
-} // namespace vist