b01c5dad346bad589bb8fa66d4be7b33615f237a
[archive/platform/core/system/libConfig.git] / src / config / kvstore.hpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Jan Olszak <j.olszak@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19 /**
20  * @file
21  * @author Jan Olszak (j.olszak@samsung.com)
22  * @brief  Declaration of a class for key-value storage in a sqlite3 database
23  */
24
25 #ifndef COMMON_CONFIG_KVSTORE_HPP
26 #define COMMON_CONFIG_KVSTORE_HPP
27
28 #include "config/sqlite3/connection.hpp"
29 #include "config/sqlite3/statement.hpp"
30
31 #include <algorithm>
32 #include <initializer_list>
33 #include <memory>
34 #include <mutex>
35 #include <sstream>
36 #include <string>
37 #include <vector>
38
39 namespace config {
40
41 class KVStore {
42
43 public:
44
45     /**
46      * @param path configuration database file path
47      */
48     KVStore(const std::string& path);
49     ~KVStore();
50
51     /**
52      * Clears all the stored data
53      */
54     void clear();
55
56     /**
57      * @return Number of all stored values
58      */
59     unsigned int size();
60
61     /**
62      * @param key string regexp of the stored values
63      *
64      * @return Number of values corresponding to the passed key
65      */
66     unsigned int count(const std::string& key);
67
68     /**
69      * Removes values corresponding to the passed key.
70      * Many values may correspond to one key, so many values may
71      * need to be deleted
72      *
73      * @param key string regexp of the stored values
74      */
75     void remove(const std::string& key);
76
77     /**
78      * Stores a single value corresponding to the passed key
79      *
80      * @param key string key of the value
81      * @param value value corresponding to the key
82      */
83     template<typename T>
84     void set(const std::string& key, const T& value)
85     {
86         return setInternal(key, value);
87     }
88
89     /**
90      * Gets the value corresponding to the key.
91      * Uses stringstreams to parse.
92      *
93      * @param key string key of the value
94      * @tparam T = std::string desired type of the return value
95      * @return value corresponding to the key
96      */
97     template<typename T = std::string>
98     T get(const std::string& key)
99     {
100         return getInternal(key, static_cast<T*>(nullptr));
101     }
102
103
104 private:
105     typedef std::lock_guard<std::mutex> Lock;
106
107     void setInternal(const std::string& key, const std::string& value);
108     void setInternal(const std::string& key, const std::initializer_list<std::string>& values);
109     void setInternal(const std::string& key, const std::vector<std::string>& values);
110     template<typename T>
111     void setInternal(const std::string& key, const T& value);
112     template<typename T>
113     void setInternal(const std::string& key, const std::vector<T>& values);
114
115     std::string getInternal(const std::string& key, std::string*);
116     std::vector<std::string> getInternal(const std::string& key, std::vector<std::string>*);
117     template<typename T>
118     T getInternal(const std::string& key, T*);
119     template<typename T>
120     std::vector<T> getInternal(const std::string& key, std::vector<T>*);
121
122     std::mutex mConnMtx;
123
124     sqlite3::Connection mConn;
125     std::unique_ptr<sqlite3::Statement> mGetValueStmt;
126     std::unique_ptr<sqlite3::Statement> mGetValueCountStmt;
127     std::unique_ptr<sqlite3::Statement> mGetSizeStmt;
128     std::unique_ptr<sqlite3::Statement> mGetValueListStmt;
129     std::unique_ptr<sqlite3::Statement> mSetValueStmt;
130     std::unique_ptr<sqlite3::Statement> mRemoveValuesStmt;
131
132     void setupDb();
133     void prepareStatements();
134
135     void removeInternal(const std::string& key);
136     unsigned int countInternal(const std::string& key);
137
138 };
139
140 namespace {
141 template<typename T>
142 std::string toString(const T& value)
143 {
144     std::ostringstream oss;
145     oss << value;
146     return oss.str();
147 }
148
149 template<typename T>
150 T fromString(const std::string& strValue)
151 {
152     std::istringstream iss(strValue);
153     T value;
154     iss >> value;
155     return value;
156 }
157
158 } // namespace
159
160 template<typename T>
161 void KVStore::setInternal(const std::string& key, const T& value)
162 {
163     setInternal(key, toString(value));
164 }
165
166 template<typename T>
167 void KVStore::setInternal(const std::string& key, const std::vector<T>& values)
168 {
169     std::vector<std::string> strValues(values.size());
170
171     std::transform(values.begin(),
172                    values.end(),
173                    strValues.begin(),
174                    toString<T>);
175
176     setInternal(key, strValues);
177 }
178
179 template<typename T>
180 T KVStore::getInternal(const std::string& key, T*)
181 {
182     return fromString<T>(getInternal(key, static_cast<std::string*>(nullptr)));
183 }
184
185 template<typename T>
186 std::vector<T> KVStore::getInternal(const std::string& key, std::vector<T>*)
187 {
188     std::vector<std::string> strValues = getInternal(key, static_cast<std::vector<std::string>*>(nullptr));
189     std::vector<T> values(strValues.size());
190
191     std::transform(strValues.begin(),
192                    strValues.end(),
193                    values.begin(),
194                    fromString<T>);
195
196     return values;
197 }
198
199 /**
200  * Concatenates all parameters into one std::string.
201  * Uses '.' to connect the terms.
202  * @param args components of the string
203  * @tparam delim optional delimiter
204  * @tparam typename ... Args any type implementing str
205  * @return string created from he args
206  */
207 template<char delim = '.', typename Arg1, typename ... Args>
208 std::string key(const Arg1& a1, const Args& ... args)
209 {
210     std::string ret = toString(a1);
211     std::initializer_list<std::string> strings {toString(args)...};
212     for (const std::string& s : strings) {
213         ret += delim + s;
214     }
215
216     return ret;
217 }
218
219 /**
220  * Function added for key function completeness.
221  *
222  * @tparam delim = '.' parameter not used, added for consistency
223  * @return empty string
224  */
225 template<char delim = '.'>
226 std::string key()
227 {
228     return std::string();
229 }
230
231 } // namespace config
232
233 #endif // COMMON_CONFIG_KVSTORE_HPP
234
235