Branch data Line data Source code
1 : : /******************************************************************************
2 : : ------------- Copyright (c) 2009-2023 H a r a l d A c h i t z ---------------
3 : : ---------- < h a r a l d dot a c h i t z at g m a i l dot c o m > ------------
4 : : ---- This Source Code Form is subject to the terms of the Mozilla Public -----
5 : : ---- License, v. 2.0. If a copy of the MPL was not distributed with this -----
6 : : ---------- file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------
7 : : ******************************************************************************/
8 : :
9 : : #ifndef SL3_DBVALUE_HPP_
10 : : #define SL3_DBVALUE_HPP_
11 : :
12 : : #include <string>
13 : :
14 : : #include <sl3/config.hpp>
15 : : #include <sl3/error.hpp>
16 : : #include <sl3/types.hpp>
17 : : #include <sl3/value.hpp>
18 : :
19 : : // todo after a wile, type and storage type become confusing
20 : : // find better name, type should be value type,
21 : : // storage type something else, find better name!
22 : :
23 : : namespace sl3
24 : : {
25 : : /**
26 : : * \brief
27 : : *
28 : : * This class models the duck typing sqlite uses.
29 : : * It supports int, real, text, blob and null values.
30 : : *
31 : : * The type can be a variant, to support all of the possible types,
32 : : * or it can be set explicit to a wanted type.
33 : : *
34 : : * Using this type for communication with the database can ensure either
35 : : * type guarantee or give the flexibility of variant types.
36 : : *
37 : : * If a type is of type variant, the storage type can be any of the
38 : : * supported types, otherwise, if the type is set to a specific type, it
39 : : * is guaranteed that the type will match, or an exception occurs.
40 : : *
41 : : */
42 : : class LIBSL3_API DbValue
43 : : {
44 : : public:
45 : : /**
46 : : * \brief Constructor
47 : : *
48 : : * Constructs a type and the value is null.
49 : : *
50 : : * \param type wanted storage type
51 : : * If Type::Null is given, the type will be a variant.
52 : : */
53 : : DbValue (Type type) noexcept;
54 : :
55 : : // TODO constructor Value, Value - Type,
56 : : // would this maybe make the other value c'tors obsolete?
57 : : // this would be fine
58 : : // don't like the ctors below anyway, they should take a flag,
59 : : // variant or not, but not the type
60 : :
61 : : /** \brief Constructor
62 : : *
63 : : * This constructor takes a initialization value, and optionally a type
64 : : * which can only be Type::Variant or the default one.
65 : : *
66 : : * \throw sl3::ErrTypeMisMatch if given type is incompatible
67 : : * \param val initial value
68 : : * \param type wanted type, default set to type but can
69 : : * be set to DbValue::Variant if waned
70 : : */
71 : : explicit DbValue (int val, Type type = Type::Int);
72 : :
73 : : /**
74 : : * \copydoc DbValue(int val, Type type = Type::Int)
75 : : */
76 : : explicit DbValue (int64_t val, Type type = Type::Int);
77 : :
78 : : /**
79 : : * \copydoc DbValue(int val, Type type = Type::Int)
80 : : */
81 : : explicit DbValue (std::string val, Type type = Type::Text);
82 : :
83 : : /**
84 : : * \copydoc DbValue(int val, Type type = Type::Int)
85 : : */
86 : : explicit DbValue (double val, Type type = Type::Real);
87 : :
88 : : /**
89 : : * \copydoc DbValue(int val, Type type = Type::Int)
90 : : */
91 : : explicit DbValue (Blob val, Type type = Type::Blob);
92 : :
93 : : /**
94 : : * \brief Destructor
95 : : */
96 : 846 : ~DbValue () noexcept = default;
97 : :
98 : : /**
99 : : * \brief Copy constructor
100 : : */
101 : 190 : DbValue (const DbValue&) noexcept = default;
102 : :
103 : : /**
104 : : * \brief Move constructor
105 : : */
106 : 305 : DbValue (DbValue&&) noexcept = default;
107 : :
108 : : /** \brief Assignment
109 : : * \throw sl3::ErrTypeMisMatch if getType is incompatible
110 : : * \note , only value assignment happens here,
111 : : * the type does not change, the storage type might change in case of type
112 : : * is a variant.
113 : : *
114 : : * \param val new value
115 : : * \return reference to this
116 : : */
117 : : DbValue& operator= (const DbValue& val);
118 : :
119 : : /**
120 : : * \copydoc operator=(const DbValue& val)
121 : : */
122 : : DbValue& operator= (DbValue&& val);
123 : :
124 : : /**
125 : : * \copydoc operator=(const DbValue& val)
126 : : */
127 : : DbValue& operator= (int val);
128 : :
129 : : /**
130 : : * \copydoc operator=(const DbValue& val)
131 : : */
132 : : DbValue& operator= (const int64_t& val);
133 : :
134 : : /**
135 : : * \copydoc operator=(const DbValue& val)
136 : : */
137 : : DbValue& operator= (const double& val);
138 : :
139 : : /**
140 : : * \copydoc operator=(const DbValue& val)
141 : : */
142 : : DbValue& operator= (const std::string& val);
143 : :
144 : : /**
145 : : * \copydoc operator=(const DbValue& val)
146 : : */
147 : : DbValue&
148 : 10 : operator= (const char* val)
149 : : {
150 [ + - + + ]: 30 : return *this = std::string{val};
151 : : }
152 : :
153 : : /**
154 : : * \copydoc operator=(const DbValue& val)
155 : : */
156 : : DbValue& operator= (const Blob& val);
157 : :
158 : : /**
159 : : * \copydoc operator=(const DbValue& val)
160 : : */
161 : : DbValue& operator= (const Value& val);
162 : :
163 : : /** \brief Assignment
164 : : * \throw sl3::ErrTypeMisMatch if getType is incompatible
165 : : * \note , only value assignment happens here,
166 : : * the type does not change, the storage type might change in case of type
167 : : * is a variant.
168 : : * \param val new value
169 : : */
170 : : void set (int val);
171 : :
172 : : /**
173 : : * \copydoc set(int val)
174 : : */
175 : : void set (int64_t val);
176 : :
177 : : /**
178 : : * \copydoc set(int val)
179 : : */
180 : : void set (const std::string& val);
181 : :
182 : : /**
183 : : * \copydoc set(int val)
184 : : */
185 : : void set (double val);
186 : :
187 : : /**
188 : : * \copydoc set(int val)
189 : : */
190 : : void set (const Blob& val);
191 : :
192 : : /** \brief Value access
193 : : * \return reference to the underlying Value
194 : : */
195 : : const Value& getValue () const noexcept;
196 : :
197 : : /** \brief Value access
198 : : * Just s shorter way tan getValue.
199 : : * \return reference to the underlying Value
200 : : */
201 : : const Value&
202 : 10 : value () const noexcept
203 : : {
204 : 10 : return getValue ();
205 : : };
206 : :
207 : : /** \brief Value access
208 : : * \throw sl3::ErrNullValueAccess if value is null.
209 : : * \throw sl3::ErrTypeMisMatch if getType is incorrect
210 : : * \return reference to the value
211 : : */
212 : : const int64_t& getInt () const;
213 : :
214 : : /**
215 : : * \copydoc getInt() const
216 : : */
217 : : const double& getReal () const;
218 : :
219 : : /**
220 : : * \copydoc getInt() const
221 : : */
222 : : const std::string& getText () const;
223 : :
224 : : /**
225 : : * \copydoc getInt() const
226 : : */
227 : : const Blob& getBlob () const;
228 : :
229 : : /** \brief Value access with default for a NULL value.
230 : : *
231 : : * \throw sl3::ErrTypeMisMatch if getType is incorrect
232 : : * \param defval default value to return if value is NULL
233 : : * \return the value or the give defval in case value is NULL
234 : : */
235 : : int64_t getInt (int64_t defval) const;
236 : :
237 : : /**
238 : : * \copydoc getInt(int64_t defval) const;
239 : : */
240 : : double getReal (double defval) const;
241 : :
242 : : /**
243 : : * \copydoc getInt(int64_t defval) const;
244 : : */
245 : : std::string getText (const std::string& defval) const;
246 : :
247 : : /**
248 : : * \copydoc getInt(int64_t defval) const;
249 : : */
250 : : Blob getBlob (const Blob& defval) const;
251 : :
252 : : /** \brief Value access with default for a NULL and different type value.
253 : : *
254 : : * This method will not throw. If the actual value is null or of a
255 : : * different type, the fiven default value will be returned.
256 : : *
257 : : * \param defval default value to return
258 : : * \return the value or the give default value if the value needs to be
259 : : * replaced
260 : : */
261 : : int64_t get (int64_t defval) const;
262 : :
263 : : /**
264 : : * \copydoc get(int64_t defval) const;
265 : : */
266 : : int64_t get (int defval) const;
267 : :
268 : : /**
269 : : * \copydoc get(int64_t defval) const;
270 : : */
271 : : double get (double defval) const;
272 : :
273 : : /**
274 : : * \copydoc get(int64_t defval) const;
275 : : */
276 : : std::string get (const std::string& defval) const;
277 : :
278 : : /**
279 : : * \copydoc get(int64_t defval) const;
280 : : */
281 : : Blob get (const Blob& defval) const;
282 : :
283 : : /** \brief Moves the current value into the return value
284 : : *
285 : : * After calling this function the value will be Null.
286 : : *
287 : : * \throw sl3::ErrTypeMisMatch in case of wrong type.
288 : : * \return The value
289 : : */
290 : : std::string ejectText ();
291 : :
292 : : /**
293 : : * \copydoc ejectText()
294 : : */
295 : : Blob ejectBlob ();
296 : :
297 : : /**
298 : : * \brief Set to NULL
299 : : */
300 : : void setNull ();
301 : :
302 : : /**
303 : : * \brief Check Null
304 : : * \return if the value is null
305 : : */
306 : : bool isNull () const;
307 : :
308 : : /**
309 : : * \brief The Type of the value.
310 : : *
311 : : * This is the type with which the Value has been created
312 : : * and will not change.
313 : : *
314 : : * The type might be Type::Varian, so that a DbValue can hold any value,
315 : : * or a specific Type to guarantee the only the allow type is used.
316 : : *
317 : : * \return the type
318 : : */
319 : : Type dbtype () const;
320 : :
321 : : /**
322 : : * \brief Returns the type of the underlying Value
323 : : *
324 : : * If getType() is a Variant this property
325 : : * returns the actual type information, otherwise it will be the same as
326 : : * type or null.
327 : : *
328 : : * \return the type the value actual holds
329 : : */
330 : : Type type () const;
331 : :
332 : : /**
333 : : * \brief Check if assignment would be OK
334 : : *
335 : : * If this function return true, the other value can
336 : : * be assign because it is type compatible.
337 : : *
338 : : * \param other value to check
339 : : * \return true if the other value can be assigned
340 : : */
341 : : bool canAssign (const DbValue& other) const;
342 : :
343 : : /**
344 : : * \brief Swap 2 DbValues
345 : : * \param a first value to swap second value
346 : : * \param b second value to swap with first
347 : : */
348 : : friend void swap (DbValue& a, DbValue& b) noexcept;
349 : :
350 : : private:
351 : : Type _type;
352 : :
353 : : Value _value;
354 : :
355 : : friend class DbValues;
356 : :
357 : : void assign (const DbValue& other);
358 : : };
359 : :
360 : : /**
361 : : * \brief Stream op for a DbValue
362 : : *
363 : : * \param stm an outstream
364 : : * \param v the value to stream
365 : : * \return ostream
366 : : */
367 : : LIBSL3_API std::ostream& operator<< (std::ostream& stm,
368 : : const sl3::DbValue& v);
369 : :
370 : : /**
371 : : * \brief equality, including type info
372 : : *
373 : : * Check if 2 DbValue instances are of the same type and of the same value.
374 : : *
375 : : * \param a first value to compare
376 : : * \param b second value to compare
377 : : *
378 : : * \return true if the type and the current value are equal, false otherwise
379 : : */
380 : : bool dbval_type_eq (const DbValue& a, const DbValue& b) noexcept;
381 : :
382 : : /**
383 : : * \brief less than, including type info
384 : : *
385 : : * Applies following rules which are equal to the sorting rules of sqlite.
386 : : *
387 : : * - Type::Null is always less than any other storage type.
388 : : * - Type::Integer or Type::Real is always less than Type::Text or
389 : : * Type::Blob
390 : : * - Type::Text is less than Type::Blob
391 : : *
392 : : * The type used is DbValue.getStorageType.
393 : : *
394 : : * The comparison of the value itself is implemented via std::less.
395 : : *
396 : : * \param a first value to compare
397 : : * \param b second value to compare
398 : : *
399 : : * \returns true if given DbValue a is less than given DbValue b
400 : : */
401 : : bool dbval_type_lt (const DbValue& a, const DbValue& b) noexcept;
402 : :
403 : : /**
404 : : * \brief equality, ignoring type info
405 : : *
406 : : * Compares only the stored value for equality and ignores type information.
407 : : *
408 : : * \param a first value to compare
409 : : * \param b second value to compare
410 : : * \return the comparison result
411 : : */
412 : : bool dbval_eq (const DbValue& a, const DbValue& b) noexcept;
413 : :
414 : : /**
415 : : * \brief less than, ignoring type info
416 : : *
417 : : * Compares only the stored value and ignores type information.
418 : : *
419 : : * \param a first value to compare
420 : : * \param b second value to compare
421 : : * \return the comparison result
422 : : */
423 : : bool dbval_lt (const DbValue& a, const DbValue& b) noexcept;
424 : :
425 : : }
426 : :
427 : : #endif /* DbValue_HPP_ */
|