Fork Vasum on GitHub Official Vasum Wiki on Tizen.org
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
from-kvstore-visitor-base.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Contact: Pawel Kubik (p.kubik@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 
25 #ifndef CARGO_SQLITE_FROM_KVSTORE_VISITOR_BASE_HPP
26 #define CARGO_SQLITE_FROM_KVSTORE_VISITOR_BASE_HPP
27 
28 #include "cargo-sqlite/kvstore.hpp"
30 #include "cargo/exception.hpp"
31 #include "cargo/is-visitable.hpp"
32 #include "cargo/is-like-tuple.hpp"
33 #include "cargo/is-streamable.hpp"
34 #include "cargo/is-union.hpp"
35 #include "cargo/visit-fields.hpp"
36 #include <map>
37 
38 
39 namespace cargo {
40 
50 template<typename RecursiveVisitor>
52 public:
54 
55  template<typename T>
56  void visit(const std::string& name, T& value)
57  {
58  static_cast<RecursiveVisitor*>(this)->visitImpl(key(mKeyPrefix, name), value);
59  }
60 
61 protected:
63  std::string mKeyPrefix;
64 
65  template<typename T>
66  void visitImpl(const std::string& name, T& value)
67  {
68  getInternal(name, value);
69  }
70 
71  FromKVStoreVisitorBase(KVStore& store, const std::string& prefix)
72  : mStore(store),
73  mKeyPrefix(prefix)
74  {
75  }
76 
78  const std::string& prefix)
79  : mStore(visitor.mStore),
80  mKeyPrefix(prefix)
81  {
82  }
83 
84 private:
85  template<typename T, typename std::enable_if<isStreamableIn<T>::value, int>::type = 0>
86  void getInternal(const std::string& name, T& value)
87  {
88  value = fromString<T>(mStore.get(name));
89  }
90 
91  template<typename T, typename std::enable_if<isVisitable<T>::value, int>::type = 0>
92  void getInternal(const std::string& name, T& value)
93  {
94  RecursiveVisitor visitor(*this, name);
95  value.accept(visitor);
96  }
97 
98  template<typename T,
99  typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
100  void getInternal(const std::string& name, T& value)
101  {
102  auto rawValue = static_cast<typename std::underlying_type<T>::type>(value);
103  static_cast<RecursiveVisitor*>(this)->visitImpl(name, rawValue);
104  value = static_cast<T>(rawValue);
105  }
106 
107  template<typename T>
108  void getInternal(const std::string& name, std::vector<T>& values)
109  {
110  size_t storedSize = 0;
111  getInternal(name, storedSize);
112 
113  if (storedSize == 0) {
114  return;
115  }
116 
117  values.resize(storedSize);
118  for (size_t i = 0; i < storedSize; ++i) {
119  const std::string k = key(name, std::to_string(i));
120  if (!mStore.prefixExists(k)) {
121  throw InternalIntegrityException("Corrupted list serialization.");
122  }
123  static_cast<RecursiveVisitor*>(this)->visitImpl(k, values[i]);
124  }
125  }
126 
127  template<typename T, size_t N>
128  void getInternal(const std::string& name, std::array<T, N>& values)
129  {
130  size_t storedSize = 0;
131  getInternal(name, storedSize);
132 
133  if (storedSize != values.size()) {
134  throw ContainerSizeException("Size of stored array doesn't match provided one.");
135  }
136 
137  for (size_t i = 0; i < storedSize; ++i) {
138  const std::string k = key(name, std::to_string(i));
139  if (!mStore.prefixExists(k)) {
140  throw InternalIntegrityException("Corrupted list serialization.");
141  }
142  static_cast<RecursiveVisitor*>(this)->visitImpl(k, values[i]);
143  }
144  }
145 
146  template<typename V>
147  void getInternal(const std::string& name, std::map<std::string, V>& values)
148  {
149  size_t storedSize = 0;
150  getInternal(name, storedSize);
151 
152  for (size_t i = 0; i < storedSize; ++i) {
153  std::string mapKey, k = key(name, i);
154  if (!mStore.prefixExists(k)) {
155  throw InternalIntegrityException("Corrupted map serialization.");
156  }
157  static_cast<RecursiveVisitor*>(this)->visitImpl(k, mapKey);
158  static_cast<RecursiveVisitor*>(this)->visitImpl(k + ".val", values[mapKey]);
159  }
160  }
161 
162  template<typename T, typename std::enable_if<isLikeTuple<T>::value, int>::type = 0>
163  void getInternal(const std::string& name, T& values)
164  {
165  size_t storedSize = 0;
166  getInternal(name, storedSize);
167 
168  if (storedSize != std::tuple_size<T>::value) {
169  throw ContainerSizeException("Size of stored array doesn't match provided one.");
170  }
171 
172  RecursiveVisitor recursiveVisitor(*this, name);
173  GetTupleVisitor visitor(recursiveVisitor);
174  visitFields(values, &visitor);
175  }
176 
178  {
179  public:
180  GetTupleVisitor(RecursiveVisitor& visitor) : mVisitor(visitor) {}
181 
182  template<typename T>
183  void visit(T& value)
184  {
185  const std::string k = key(mVisitor.mKeyPrefix, idx);
186  if (!mVisitor.mStore.prefixExists(k)) {
187  throw InternalIntegrityException("Corrupted list serialization.");
188  }
189  mVisitor.visitImpl(k, value);
190 
191  ++idx;
192  }
193 
194  private:
195  RecursiveVisitor& mVisitor;
196  size_t idx = 0;
197  };
198 };
199 
200 } // namespace cargo
201 
202 #endif // CARGO_SQLITE_FROM_KVSTORE_VISITOR_BASE_HPP
bool prefixExists(const std::string &key)
Definition: kvstore.cpp:259
Internal configuration helper.
void getInternal(const std::string &name, std::map< std::string, V > &values)
Definition: from-kvstore-visitor-base.hpp:147
Declaration of a class for key-value storage in a sqlite3 database.
Definition: kvstore.hpp:43
size_t idx
Definition: from-kvstore-visitor-base.hpp:196
Definition: from-kvstore-visitor-base.hpp:177
Helper function for iterating tuples, pairs and arrays.
Invalid integral type integrity error.
Definition: exception.hpp:51
FromKVStoreVisitorBase(const FromKVStoreVisitorBase &visitor, const std::string &prefix)
Definition: from-kvstore-visitor-base.hpp:77
Tuple or pair checker.
std::string mKeyPrefix
Definition: from-kvstore-visitor-base.hpp:63
RecursiveVisitor & mVisitor
Definition: from-kvstore-visitor-base.hpp:195
Internal configuration helper.
void visit(T &value)
Definition: from-kvstore-visitor-base.hpp:183
Container size does not match.
Definition: exception.hpp:59
std::string key(const Arg1 &a1, const Args &...args)
Concatenates all parameters into one std::string.
Definition: kvstore-visitor-utils.hpp:60
void getInternal(const std::string &name, std::array< T, N > &values)
Definition: from-kvstore-visitor-base.hpp:128
void getInternal(const std::string &name, std::vector< T > &values)
Definition: from-kvstore-visitor-base.hpp:108
void getInternal(const std::string &name, T &value)
Definition: from-kvstore-visitor-base.hpp:86
void visit(const std::string &name, T &value)
Definition: from-kvstore-visitor-base.hpp:56
FromKVStoreVisitorBase & operator=(const FromKVStoreVisitorBase &)=delete
Exceptions for libcargo.
void getInternal(const std::string &name, T &values)
Definition: from-kvstore-visitor-base.hpp:163
KVStore & mStore
Definition: from-kvstore-visitor-base.hpp:62
KVStore visitors utilities.
std::string get(const std::string &key)
Gets the value corresponding to the key.
Definition: kvstore.cpp:168
Base class for KVStore visitors.
Definition: from-kvstore-visitor-base.hpp:51
Check whether type is accepted by streaming operators.
void visitImpl(const std::string &name, T &value)
Definition: from-kvstore-visitor-base.hpp:66
GetTupleVisitor(RecursiveVisitor &visitor)
Definition: from-kvstore-visitor-base.hpp:180
void visitFields(T &t, F f, A...args)
Definition: visit-fields.hpp:58
FromKVStoreVisitorBase(KVStore &store, const std::string &prefix)
Definition: from-kvstore-visitor-base.hpp:71