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 while, 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 explicitly 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 constructors below anyway; they should take a flag,
59 : : // variant or not, but not the type
60 : :
61 : : /** \brief Constructor
62 : : *
63 : : * This constructor takes an initialization value, and optionally a type
64 : : * which can only be Type::Variant or the default one.
65 : : *
66 : : *
67 : : * \throw sl3::ErrTypeMisMatch if given type is incompatible
68 : : * \param val initial value
69 : : * \param type wanted type, default set to type but can
70 : : * be set to DbValue::Variant if wanted
71 : : */
72 : : explicit DbValue (int val, Type type = Type::Int);
73 : :
74 : : /**
75 : : * \copydoc DbValue(int val, Type type = Type::Int)
76 : : */
77 : : explicit DbValue (int64_t val, Type type = Type::Int);
78 : :
79 : : /**
80 : : * \copydoc DbValue(int val, Type type = Type::Int)
81 : : */
82 : : explicit DbValue (std::string val, Type type = Type::Text);
83 : :
84 : : /**
85 : : * \copydoc DbValue(int val, Type type = Type::Int)
86 : : */
87 : : explicit DbValue (double val, Type type = Type::Real);
88 : :
89 : : /**
90 : : * \copydoc DbValue(int val, Type type = Type::Int)
91 : : */
92 : : explicit DbValue (Blob val, Type type = Type::Blob);
93 : :
94 : : /**
95 : : * \brief Destructor
96 : : */
97 : 924 : ~DbValue () noexcept = default;
98 : :
99 : : /**
100 : : * \brief Copy constructor
101 : : */
102 : 215 : DbValue (const DbValue&) noexcept = default;
103 : :
104 : : /**
105 : : * \brief Move constructor
106 : : */
107 : 325 : DbValue (DbValue&&) noexcept = default;
108 : :
109 : : /** \brief Assignment
110 : : * \throw sl3::ErrTypeMisMatch if getType is incompatible
111 : : * \note , only value assignment happens here,
112 : : * the type does not change; the storage type might change if the type is
113 : : * a variant.
114 : : *
115 : : * \param val new value
116 : : * \return reference to this
117 : : */
118 : : DbValue& operator= (const DbValue& val);
119 : :
120 : : /**
121 : : * \copydoc operator=(const DbValue& val)
122 : : */
123 : : DbValue& operator= (DbValue&& val);
124 : :
125 : : /**
126 : : * \copydoc operator=(const DbValue& val)
127 : : */
128 : : DbValue& operator= (int val);
129 : :
130 : : /**
131 : : * \copydoc operator=(const DbValue& val)
132 : : */
133 : : DbValue& operator= (const int64_t& val);
134 : :
135 : : /**
136 : : * \copydoc operator=(const DbValue& val)
137 : : */
138 : : DbValue& operator= (const double& val);
139 : :
140 : : /**
141 : : * \copydoc operator=(const DbValue& val)
142 : : */
143 : : DbValue& operator= (const std::string& val);
144 : :
145 : : /**
146 : : * \copydoc operator=(const DbValue& val)
147 : : */
148 : : DbValue&
149 : 10 : operator= (const char* val)
150 : : {
151 : 30 : return *this = std::string{val};
152 : : }
153 : :
154 : : /**
155 : : * \copydoc operator=(const DbValue& val)
156 : : */
157 : : DbValue& operator= (const Blob& val);
158 : :
159 : : /**
160 : : * \copydoc operator=(const DbValue& val)
161 : : */
162 : : DbValue& operator= (const Value& val);
163 : :
164 : : /** \brief Assignment
165 : : * \throw sl3::ErrTypeMisMatch if getType is incompatible
166 : : * \note , only value assignment happens here,
167 : : * the type does not change; the storage type might change if the type is
168 : : * a variant.
169 : : * \param val new value
170 : : */
171 : : void set (int val);
172 : :
173 : : /**
174 : : * \copydoc set(int val)
175 : : */
176 : : void set (int64_t val);
177 : :
178 : : /**
179 : : * \copydoc set(int val)
180 : : */
181 : : void set (const std::string& val);
182 : :
183 : : /**
184 : : * \copydoc set(int val)
185 : : */
186 : : void set (double val);
187 : :
188 : : /**
189 : : * \copydoc set(int val)
190 : : */
191 : : void set (const Blob& val);
192 : :
193 : : /** \brief Value access
194 : : * \return reference to the underlying Value
195 : : */
196 : : const Value& getValue () const noexcept;
197 : :
198 : : /** \brief Value access
199 : : * Just a shorter way than getValue.
200 : : * \return reference to the
201 : : * underlying Value
202 : : */
203 : : const Value&
204 : 10 : value () const noexcept
205 : : {
206 : 10 : return getValue ();
207 : : };
208 : :
209 : : /** \brief Value access
210 : : * \throw sl3::ErrNullValueAccess if value is null.
211 : : * \throw sl3::ErrTypeMisMatch if getType is incorrect
212 : : * \return reference to the value
213 : : */
214 : : const int64_t& getInt () const;
215 : :
216 : : /**
217 : : * \copydoc getInt() const
218 : : */
219 : : const double& getReal () const;
220 : :
221 : : /**
222 : : * \copydoc getInt() const
223 : : */
224 : : const std::string& getText () const;
225 : :
226 : : /**
227 : : * \copydoc getInt() const
228 : : */
229 : : const Blob& getBlob () const;
230 : :
231 : : /** \brief Value access with default for a NULL value.
232 : : *
233 : : * \throw sl3::ErrTypeMisMatch if getType is incorrect
234 : : * \param defval default value to return if value is NULL
235 : : * \return the value or the given defval in case the value is NULL
236 : : */
237 : : int64_t getInt (int64_t defval) const;
238 : :
239 : : /**
240 : : * \copydoc getInt(int64_t defval) const;
241 : : */
242 : : double getReal (double defval) const;
243 : :
244 : : /**
245 : : * \copydoc getInt(int64_t defval) const;
246 : : */
247 : : std::string getText (const std::string& defval) const;
248 : :
249 : : /**
250 : : * \copydoc getInt(int64_t defval) const;
251 : : */
252 : : Blob getBlob (const Blob& defval) const;
253 : :
254 : : /** \brief Value access with default for a NULL and different type value.
255 : : *
256 : : * This method will not throw. If the actual value is null or of a
257 : : * different type, the given default value will be returned.
258 : : *
259 : : * \param defval default value to return
260 : : * \return the value or the given default value if the value needs to be
261 : : * replaced
262 : : */
263 : : int64_t get (int64_t defval) const;
264 : :
265 : : /**
266 : : * \copydoc get(int64_t defval) const;
267 : : */
268 : : int64_t get (int defval) const;
269 : :
270 : : /**
271 : : * \copydoc get(int64_t defval) const;
272 : : */
273 : : double get (double defval) const;
274 : :
275 : : /**
276 : : * \copydoc get(int64_t defval) const;
277 : : */
278 : : std::string get (const std::string& defval) const;
279 : :
280 : : /**
281 : : * \copydoc get(int64_t defval) const;
282 : : */
283 : : Blob get (const Blob& defval) const;
284 : :
285 : : /** \brief Moves the current value into the return value
286 : : *
287 : : * After calling this function the value will be Null.
288 : : *
289 : : * \throw sl3::ErrTypeMisMatch in case of wrong type.
290 : : * \return The value
291 : : */
292 : : std::string ejectText ();
293 : :
294 : : /**
295 : : * \copydoc ejectText()
296 : : */
297 : : Blob ejectBlob ();
298 : :
299 : : /**
300 : : * \brief Set to NULL
301 : : */
302 : : void setNull ();
303 : :
304 : : /**
305 : : * \brief Check Null
306 : : * \return if the value is null
307 : : */
308 : : bool isNull () const;
309 : :
310 : : /**
311 : : * \brief The Type of the value.
312 : : *
313 : : * This is the type with which the Value has been created
314 : : * and will not change.
315 : : *
316 : : * The type might be Type::Variant, so that a DbValue can hold any value,
317 : : *
318 : : * or a specific Type to guarantee that only the allowed type is used.
319 : : *
320 : : * \return the type
321 : : */
322 : : Type dbtype () const;
323 : :
324 : : /**
325 : : * \brief Returns the type of the underlying Value
326 : : *
327 : : * If getType() is a Variant this property
328 : : * returns the actual type information, otherwise it will be the same as
329 : : * type or null.
330 : : *
331 : : * \return the type the value actually holds
332 : : */
333 : : Type type () const;
334 : :
335 : : /**
336 : : * \brief Check if assignment would be OK
337 : : *
338 : : * If this function returns true, the other value can
339 : : * be assigned
340 : : * because it is type compatible.
341 : : *
342 : : * \param other value to check
343 : : * \return true if the other value can be assigned
344 : : */
345 : : bool canAssign (const DbValue& other) const;
346 : :
347 : : /**
348 : : * \brief Swap 2 DbValues
349 : : * \param a first value to swap second value
350 : : * \param b second value to swap with first
351 : : */
352 : : friend void swap (DbValue& a, DbValue& b) noexcept;
353 : :
354 : : private:
355 : : Type _type;
356 : :
357 : : Value _value;
358 : :
359 : : friend class DbValues;
360 : :
361 : : void assign (const DbValue& other);
362 : : };
363 : :
364 : : /**
365 : : * \brief Stream op for a DbValue
366 : : *
367 : : * \param stm an outstream
368 : : * \param v the value to stream
369 : : * \return ostream
370 : : */
371 : : LIBSL3_API std::ostream& operator<< (std::ostream& stm,
372 : : const sl3::DbValue& v);
373 : :
374 : : /**
375 : : * \brief equality, including type info
376 : : *
377 : : * Check if 2 DbValue instances are of the same type and of the same value.
378 : : *
379 : : * \param a first value to compare
380 : : * \param b second value to compare
381 : : *
382 : : * \return true if the type and the current value are equal, false otherwise
383 : : */
384 : : bool dbval_type_eq (const DbValue& a, const DbValue& b) noexcept;
385 : :
386 : : /**
387 : : * \brief less than, including type info
388 : : *
389 : : * Applies following rules which are equal to the sorting rules of sqlite.
390 : : *
391 : : * - Type::Null is always less than any other storage type.
392 : : * - Type::Integer or Type::Real is always less than Type::Text or
393 : : * Type::Blob
394 : : * - Type::Text is less than Type::Blob
395 : : *
396 : : * The type used is DbValue.getStorageType.
397 : : *
398 : : * The comparison of the value itself is implemented via std::less.
399 : : *
400 : : * \param a first value to compare
401 : : * \param b second value to compare
402 : : *
403 : : * \returns true if given DbValue a is less than given DbValue b
404 : : */
405 : : bool dbval_type_lt (const DbValue& a, const DbValue& b) noexcept;
406 : :
407 : : /**
408 : : * \brief equality, ignoring type info
409 : : *
410 : : * Compares only the stored value for equality and ignores type information.
411 : : *
412 : : * \param a first value to compare
413 : : * \param b second value to compare
414 : : * \return the comparison result
415 : : */
416 : : bool dbval_eq (const DbValue& a, const DbValue& b) noexcept;
417 : :
418 : : /**
419 : : * \brief less than, ignoring type info
420 : : *
421 : : * Compares only the stored value and ignores type information.
422 : : *
423 : : * \param a first value to compare
424 : : * \param b second value to compare
425 : : * \return the comparison result
426 : : */
427 : : bool dbval_lt (const DbValue& a, const DbValue& b) noexcept;
428 : :
429 : : }
430 : :
431 : : #endif /* DbValue_HPP_ */
|