80c1b817c24c421538fba52e2e0e9f45c7f2dffa
[platform/core/security/vist.git] / src / vist / query-builder / crud.hpp
1 /*
2  *  Copyright (c) 2017-present Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16
17 #pragma once
18
19 #include "column.hpp"
20 #include "expression.hpp"
21
22 #include <string>
23 #include <sstream>
24
25 namespace vist {
26 namespace tsqb {
27
28 template<typename T>
29 class Crud {
30 public:
31         template<typename... ColumnTypes>
32         T& select(ColumnTypes&&... cts);
33
34         template<typename TableType>
35         T& selectAll(void);
36
37         T& selectAll(void);
38
39         template<typename... ColumnTypes>
40         T& update(ColumnTypes&&... cts);
41
42         template<typename... ColumnTypes>
43         T& insert(ColumnTypes&&... cts);
44
45         template<typename... ColumnTypes>
46         T& remove(ColumnTypes&&... cts);
47
48         template<typename Expr>
49         T& where(Expr expr);
50
51 private:
52         template<typename L, typename R>
53         std::string processWhere(And<L,R>& expr);
54
55         template<typename L, typename R>
56         std::string processWhere(Or<L,R>& expr);
57
58         template<typename Expr>
59         std::string processWhere(Expr expr);
60 };
61
62 template<typename T>
63 template<typename... ColumnTypes>
64 T& Crud<T>::select(ColumnTypes&&... cts)
65 {
66         static_cast<T*>(this)->cache.clear();
67
68         auto columnNames = static_cast<T*>(this)->getColumnNames(std::forward<ColumnTypes>(cts)...);
69         auto tableNames = static_cast<T*>(this)->getTableNames(std::forward<ColumnTypes>(cts)...);
70
71         std::stringstream ss;
72         ss << "SELECT ";
73
74         std::size_t i = 0;
75         for (const auto& c : columnNames) {
76                 ss << c;
77
78                 if (i++ < columnNames.size() - 1)
79                         ss << ", ";
80         }
81
82         ss << " FROM ";
83
84         i = 0;
85         for (const auto& t : tableNames) {
86                 ss << t;
87
88                 if (i++ < tableNames.size() - 1)
89                         ss << ", ";
90         }
91
92         static_cast<T*>(this)->cache.emplace_back(ss.str());
93
94         return *(static_cast<T*>(this));
95 }
96
97 template<typename T>
98 T& Crud<T>::selectAll(void)
99 {
100         static_cast<T*>(this)->cache.clear();
101
102         std::stringstream ss;
103         ss << "SELECT * FROM " << static_cast<T*>(this)->name;
104
105         static_cast<T*>(this)->cache.emplace_back(ss.str());
106
107         return *(static_cast<T*>(this));
108 }
109
110 template<typename T>
111 template<typename TableType>
112 T& Crud<T>::selectAll(void)
113 {
114         static_cast<T*>(this)->cache.clear();
115
116         std::stringstream ss;
117         auto tableName = static_cast<T*>(this)->getTableName(TableType());
118         ss << "SELECT * FROM " << tableName;
119
120         static_cast<T*>(this)->cache.emplace_back(ss.str());
121
122         return *(static_cast<T*>(this));
123 }
124
125 template<typename T>
126 template<typename... ColumnTypes>
127 T& Crud<T>::update(ColumnTypes&&... cts)
128 {
129         static_cast<T*>(this)->cache.clear();
130
131         auto columnNames = static_cast<T*>(this)->getColumnNames(std::forward<ColumnTypes>(cts)...);
132
133         std::stringstream ss;
134         ss << "UPDATE " << static_cast<T*>(this)->name << " ";
135         ss << "SET ";
136
137         unsigned int i = 0;
138         for (const auto& c : columnNames) {
139                 ss << c << " = ?";
140
141                 if (i++ < columnNames.size() - 1)
142                         ss << ", ";
143         }
144
145         static_cast<T*>(this)->cache.emplace_back(ss.str());
146
147         return *(static_cast<T*>(this));
148 }
149
150 template<typename T>
151 template<typename... ColumnTypes>
152 T& Crud<T>::insert(ColumnTypes&&... cts)
153 {
154         static_cast<T*>(this)->cache.clear();
155
156         auto columnNames = static_cast<T*>(this)->getColumnNames(std::forward<ColumnTypes>(cts)...);
157
158         std::stringstream ss;
159         ss << "INSERT INTO " << static_cast<T*>(this)->name << " (";
160
161         const int columnCount = columnNames.size();
162         for (int i = 0; i < columnCount; i++) {
163                 ss << columnNames[i];
164                 if (i < columnCount - 1)
165                         ss << ", ";
166         }
167
168         ss << ") VALUES (";
169
170         for (int i = 0; i < columnCount; i++) {
171                 ss << "?";
172                 if (i < columnCount - 1)
173                         ss << ", ";
174         }
175
176         ss << ")";
177
178         static_cast<T*>(this)->cache.emplace_back(ss.str());
179
180         return *(static_cast<T*>(this));
181 }
182
183 template<typename T>
184 template<typename... ColumnTypes>
185 T& Crud<T>::remove(ColumnTypes&&... cts)
186 {
187         static_cast<T*>(this)->cache.clear();
188
189         auto columnNames = static_cast<T*>(this)->getColumnNames(std::forward<ColumnTypes>(cts)...);
190
191         std::stringstream ss;
192         ss << "DELETE FROM " << static_cast<T*>(this)->name;
193
194         static_cast<T*>(this)->cache.emplace_back(ss.str());
195
196         return *(static_cast<T*>(this));
197 }
198
199 template<typename T>
200 template<typename Expr>
201 T& Crud<T>::where(Expr expr)
202 {
203         std::stringstream ss;
204         ss << "WHERE " << this->processWhere(expr);
205
206         static_cast<T*>(this)->cache.emplace_back(ss.str());
207
208         return *(static_cast<T*>(this));
209 }
210
211 template<typename T>
212 template<typename L, typename R>
213 std::string Crud<T>::processWhere(And<L,R>& expr)
214 {
215         std::stringstream ss;
216         ss << this->processWhere(expr.l) << " ";
217         ss << static_cast<std::string>(expr) << " ";
218         ss << this->processWhere(expr.r);
219
220         return ss.str();
221 }
222
223 template<typename T>
224 template<typename L, typename R>
225 std::string Crud<T>::processWhere(Or<L,R>& expr)
226 {
227         std::stringstream ss;
228         ss << this->processWhere(expr.l) << " ";
229         ss << static_cast<std::string>(expr) << " ";
230         ss << this->processWhere(expr.r);
231
232         return ss.str();
233 }
234
235 template<typename T>
236 template<typename Expr>
237 std::string Crud<T>::processWhere(Expr expr)
238 {
239         std::stringstream ss;
240         ss << static_cast<T*>(this)->getColumnName(expr.l);
241         ss << " " << std::string(expr) << " ?";
242
243         return ss.str();
244 }
245
246 } // namespace tsqb
247 } // namespace vist