Ability to list all keys from kv store
[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 #include <atomic>
39
40 namespace config {
41
42 class KVStore {
43
44 public:
45     /**
46      * A guard struct for thread synchronization and transaction management.
47      */
48     typedef std::shared_ptr<void> Transaction;
49
50     /**
51      * @param path configuration database file path
52      */
53     KVStore(const std::string& path);
54     KVStore(const KVStore& store);
55     ~KVStore();
56
57     /**
58      * Clears all the stored data
59      */
60     void clear();
61
62     /**
63      * @return Is there any data stored
64      */
65     bool isEmpty();
66
67     /**
68      * @param key string regexp of the stored values
69      *
70      * @return Does this key exist in the database
71      */
72     bool exists(const std::string& key);
73
74     /**
75      * Removes values corresponding to the passed key.
76      * Many values may correspond to one key, so many values may
77      * need to be deleted
78      *
79      * @param key string regexp of the stored values
80      */
81     void remove(const std::string& key);
82
83     /**
84      * Stores a single value corresponding to the passed key
85      *
86      * @param key string key of the value
87      * @param value value corresponding to the key
88      */
89     template<typename T>
90     void set(const std::string& key, const T& value)
91     {
92         return setInternal(key, value);
93     }
94
95     /**
96      * Gets the value corresponding to the key.
97      * Uses stringstreams to parse.
98      *
99      * @param key string key of the value
100      * @tparam T = std::string desired type of the return value
101      * @return value corresponding to the key
102      */
103     template<typename T = std::string>
104     T get(const std::string& key)
105     {
106         return getInternal(key, static_cast<T*>(nullptr));
107     }
108
109     /**
110      * Returns all stored keys.
111      */
112     std::vector<std::string> getKeys();
113
114     KVStore::Transaction getTransaction();
115
116 private:
117     typedef std::lock_guard<std::mutex> Lock;
118
119     struct TransactionImpl;
120     std::weak_ptr<TransactionImpl> mTransactionImplPtr;
121     std::mutex getTransactionMutex;
122     std::mutex mConnMtx;
123
124     void setInternal(const std::string& key, const std::string& value);
125     void setInternal(const std::string& key, const std::initializer_list<std::string>& values);
126     void setInternal(const std::string& key, const std::vector<std::string>& values);
127     template<typename T>
128     void setInternal(const std::string& key, const T& value);
129     template<typename T>
130     void setInternal(const std::string& key, const std::vector<T>& values);
131
132     std::string getInternal(const std::string& key, std::string*);
133     std::vector<std::string> getInternal(const std::string& key, std::vector<std::string>*);
134     template<typename T>
135     T getInternal(const std::string& key, T*);
136     template<typename T>
137     std::vector<T> getInternal(const std::string& key, std::vector<T>*);
138
139     std::string mPath;
140     sqlite3::Connection mConn;
141     std::unique_ptr<sqlite3::Statement> mGetValueStmt;
142     std::unique_ptr<sqlite3::Statement> mGetKeyExistsStmt;
143     std::unique_ptr<sqlite3::Statement> mGetIsEmptyStmt;
144     std::unique_ptr<sqlite3::Statement> mGetValueListStmt;
145     std::unique_ptr<sqlite3::Statement> mSetValueStmt;
146     std::unique_ptr<sqlite3::Statement> mRemoveValuesStmt;
147     std::unique_ptr<sqlite3::Statement> mGetKeysStmt;
148
149     void setupDb();
150     void prepareStatements();
151     void createFunctions();
152 };
153
154 namespace {
155 template<typename T>
156 std::string toString(const T& value)
157 {
158     std::ostringstream oss;
159     oss << value;
160     return oss.str();
161 }
162
163 template<typename T>
164 T fromString(const std::string& strValue)
165 {
166     std::istringstream iss(strValue);
167     T value;
168     iss >> value;
169     return value;
170 }
171
172 } // namespace
173
174 template<typename T>
175 void KVStore::setInternal(const std::string& key, const T& value)
176 {
177     setInternal(key, toString(value));
178 }
179
180 template<typename T>
181 void KVStore::setInternal(const std::string& key, const std::vector<T>& values)
182 {
183     std::vector<std::string> strValues(values.size());
184
185     std::transform(values.begin(),
186                    values.end(),
187                    strValues.begin(),
188                    toString<T>);
189
190     setInternal(key, strValues);
191 }
192
193 template<typename T>
194 T KVStore::getInternal(const std::string& key, T*)
195 {
196     return fromString<T>(getInternal(key, static_cast<std::string*>(nullptr)));
197 }
198
199 template<typename T>
200 std::vector<T> KVStore::getInternal(const std::string& key, std::vector<T>*)
201 {
202     std::vector<std::string> strValues = getInternal(key, static_cast<std::vector<std::string>*>(nullptr));
203     std::vector<T> values(strValues.size());
204
205     std::transform(strValues.begin(),
206                    strValues.end(),
207                    values.begin(),
208                    fromString<T>);
209
210     return values;
211 }
212
213 /**
214  * Concatenates all parameters into one std::string.
215  * Uses '.' to connect the terms.
216  * @param args components of the string
217  * @tparam delim optional delimiter
218  * @tparam typename ... Args any type implementing str
219  * @return string created from he args
220  */
221 template<char delim = '.', typename Arg1, typename ... Args>
222 std::string key(const Arg1& a1, const Args& ... args)
223 {
224     std::string ret = toString(a1);
225     std::initializer_list<std::string> strings {toString(args)...};
226     for (const std::string& s : strings) {
227         ret += delim + s;
228     }
229
230     return ret;
231 }
232
233 /**
234  * Function added for key function completeness.
235  *
236  * @tparam delim = '.' parameter not used, added for consistency
237  * @return empty string
238  */
239 template<char delim = '.'>
240 std::string key()
241 {
242     return std::string();
243 }
244
245 } // namespace config
246
247 #endif // COMMON_CONFIG_KVSTORE_HPP
248
249