2 * Copyright (c) 2017-present Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
21 #include "expression.hpp"
34 template<typename... Tables>
35 class Database : public Crud<Database<Tables...>> {
37 using Self = Database<Tables...>;
39 explicit Database(const std::string& name, Tables ...tables) :
40 name(name), tables(tables...) {}
42 std::size_t size() const noexcept;
44 operator std::string();
48 public: // CRTP(Curiously Recurring Template Pattern) for CRUD
49 template<typename... Cs>
50 std::vector<std::string> getTableNames(Cs&& ...columns) const noexcept;
51 template<typename Table>
52 std::string getTableName(Table&& table) const noexcept;
53 template<typename... Cs>
54 std::vector<std::string> getColumnNames(Cs&& ...columns) const noexcept;
55 template<typename Column>
56 std::string getColumnName(Column&& column) const noexcept;
58 std::vector<std::string> cache;
61 std::tuple<Tables...> tables;
64 template<typename... Tables>
65 Database<Tables...>::operator std::string()
68 for (const auto& c : cache)
72 return util::rtrim(ss.str());
75 template<typename... Tables>
76 template<typename... Cs>
77 std::vector<std::string> Database<Tables...>::getTableNames(Cs&& ...columns) const noexcept
79 std::set<std::string> names;
81 auto predicate = [this, &names](const auto& column) {
82 using ColumnType = std::remove_reference_t<decltype(column)>;
83 using TableType = typename ColumnType::Table;
84 auto name = this->getTableName(TableType());
89 auto closure = [&predicate](const auto&... iter) {
90 (predicate(iter), ...);
93 std::apply(closure, std::tuple(columns...));
95 return std::vector<std::string>(names.begin(), names.end());
98 template<typename... Tables>
99 template<typename... Cs>
100 std::vector<std::string> Database<Tables...>::getColumnNames(Cs&& ...columns) const noexcept
102 std::vector<std::string> names;
103 auto predicate = [this, &names](const auto& column) {
104 auto name = this->getColumnName(column);
106 names.emplace_back(name);
109 auto closure = [&predicate](const auto&... iter) {
110 (predicate(iter), ...);
113 std::apply(closure, std::tuple(columns...));
118 template<typename... Tables>
119 template<typename Table>
120 std::string Database<Tables...>::getTableName(Table&& table) const noexcept
123 auto predicate = [&name, &table](const auto& type) {
124 if (type.compare(table))
128 auto closure = [&predicate](const auto&... iter) {
129 (predicate(iter), ...);
132 std::apply(closure, this->tables);
137 template<typename... Tables>
138 template<typename Column>
139 std::string Database<Tables...>::getColumnName(Column&& column) const noexcept
141 using ColumnType = std::remove_reference_t<decltype(column)>;
142 using TableType = typename ColumnType::Table;
146 auto predicate = [&name, &table, &column](const auto& iter) {
147 if (iter.compare(table)) {
148 auto cname = iter.getColumnName(column);
149 name = iter.name + "." + cname;
153 auto closure = [&predicate](const auto&... iter) {
154 (predicate(iter), ...);
157 std::apply(closure, this->tables);
162 template<typename... Tables>
163 std::size_t Database<Tables...>::size() const noexcept
165 using TupleType = std::tuple<Tables...>;
166 return std::tuple_size<TupleType>::value;