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 : : #include <sl3/dbvalue.hpp>
10 : : #include <sl3/error.hpp>
11 : :
12 : : #include <algorithm>
13 : : #include <cmath>
14 : : #include <iomanip>
15 : : #include <limits>
16 : : #include <ostream>
17 : : #include <type_traits>
18 : :
19 : : #include <iostream>
20 : :
21 : : namespace sl3
22 : : {
23 : :
24 : : namespace
25 : : {
26 : : template <typename T>
27 : : constexpr bool
28 : 123 : oneof (const T&)
29 : : {
30 : 123 : return false;
31 : : }
32 : :
33 : : template <typename T, typename T1, typename... REST>
34 : : constexpr bool
35 : 650 : oneof (const T& a, const T1& b, REST... rest)
36 : : {
37 [ + + + + ]: 650 : return (a == b ? true : oneof (a, rest...));
38 : : }
39 : :
40 : : struct check
41 : : {
42 : 22 : check (Type t)
43 : 22 : : type (t)
44 : : {
45 : 22 : } //----------------------------------------------------------------------
46 : :
47 : : bool
48 : : notNull ()
49 : : {
50 : : return type != Type::Null;
51 : : } //----------------------------------------------------------------------
52 : :
53 : : template <typename... ARGS>
54 : : bool
55 : 2 : oneOf (ARGS... args)
56 : : {
57 : 2 : return oneof (type, args...);
58 : :
59 : : } //--------------------------------------------------------------------
60 : :
61 : : bool
62 : 20 : sameAs (Type t)
63 : : {
64 : 20 : return type == t;
65 : : } //----------------------------------------------------------------------
66 : :
67 : : private:
68 : : Type type;
69 : : };
70 : :
71 : : struct ensure
72 : : {
73 : 407 : ensure (Type t)
74 : 407 : : type (t)
75 : : {
76 : 407 : } //----------------------------------------------------------------------
77 : :
78 : : ensure&
79 : : notNull ()
80 : : {
81 : : if (type == Type::Null)
82 : : throw ErrNullValueAccess ();
83 : :
84 : : return *this;
85 : : } //----------------------------------------------------------------------
86 : :
87 : : template <typename... ARGS>
88 : : ensure&
89 : 407 : oneOf (ARGS... args)
90 : : {
91 [ + + ]: 407 : if (!oneof (type, args...))
92 [ + - + - : 123 : throw ErrTypeMisMatch (typeName (type)
+ - ]
93 : : + " not one of required types");
94 : :
95 : 284 : return *this;
96 : : } //--------------------------------------------------------------------
97 : :
98 : : ensure&
99 : : sameAs (Type t)
100 : : {
101 : : if (type != t)
102 : : throw ErrTypeMisMatch (typeName (type) + "!=" + typeName (t));
103 : :
104 : : return *this;
105 : : } //----------------------------------------------------------------------
106 : :
107 : : private:
108 : : Type type;
109 : : };
110 : :
111 : : } //--------------------------------------------------------------------------
112 : :
113 : : bool
114 : 3 : dbval_type_eq (const DbValue& a, const DbValue& b) noexcept
115 : : {
116 [ + + ]: 3 : if (a.dbtype () == b.dbtype ())
117 : : {
118 : 1 : return value_type_eq (a.getValue (), b.getValue ());
119 : : }
120 : :
121 : 2 : return false;
122 : : }
123 : :
124 : : bool
125 : 4 : dbval_type_lt (const DbValue& a, const DbValue& b) noexcept
126 : : {
127 [ + + ]: 4 : if (value_type_lt (a.getValue (), b.getValue ()))
128 : : {
129 : 1 : return true;
130 : : }
131 : :
132 [ + + ]: 3 : if (value_type_eq (a.getValue (), b.getValue ()))
133 : : { // a variant is bigger
134 : 1 : return a.dbtype () < b.dbtype ();
135 : : }
136 : :
137 : 2 : return false;
138 : : }
139 : :
140 : : // how, and does this makesense ?
141 : :
142 : : bool
143 : 2 : dbval_eq (const DbValue& a, const DbValue& b) noexcept
144 : : {
145 : 2 : return value_eq (a.getValue (), b.getValue ());
146 : : }
147 : :
148 : : bool
149 : 17 : dbval_lt (const DbValue& a, const DbValue& b) noexcept
150 : : {
151 : 17 : return value_lt (a.getValue (), b.getValue ());
152 : : }
153 : :
154 : 351 : DbValue::DbValue (Type type) noexcept
155 [ + + ]: 351 : : _type (type == Type::Null ? Type::Variant : type)
156 : : {
157 : 351 : }
158 : :
159 : 51 : DbValue::DbValue (int val, Type type)
160 : 51 : : DbValue (type)
161 : : {
162 [ + + ]: 51 : ensure (type).oneOf (Type::Int, Type::Variant);
163 [ + - ]: 50 : _value = val;
164 : 51 : }
165 : :
166 : 67 : DbValue::DbValue (int64_t val, Type type)
167 : 67 : : DbValue (type)
168 : : {
169 [ + + ]: 67 : ensure (type).oneOf (Type::Int, Type::Variant);
170 [ + - ]: 65 : _value = val;
171 : 67 : }
172 : :
173 : 91 : DbValue::DbValue (std::string val, Type type)
174 : 91 : : DbValue (type)
175 : : {
176 [ + + ]: 91 : ensure (type).oneOf (Type::Text, Type::Variant);
177 [ + - ]: 88 : _value = val;
178 : 91 : }
179 : :
180 : 55 : DbValue::DbValue (double val, Type type)
181 : 55 : : DbValue (type)
182 : : {
183 [ + + ]: 55 : ensure (type).oneOf (Type::Real, Type::Variant);
184 [ + - ]: 52 : _value = val;
185 : 55 : }
186 : :
187 : 19 : DbValue::DbValue (Blob val, Type type)
188 : 19 : : DbValue (type)
189 : : {
190 [ + + ]: 19 : ensure (type).oneOf (Type::Blob, Type::Variant);
191 [ + - ]: 17 : _value = val;
192 : 19 : }
193 : :
194 : : DbValue&
195 : 54 : DbValue::operator= (const DbValue& other)
196 : : {
197 [ + + ]: 54 : if (!canAssign (other))
198 : : {
199 [ + - + - ]: 4 : throw ErrTypeMisMatch (typeName (_type) + "="
200 [ + - ]: 4 : + (other._type == Type::Variant
201 [ - - - - : 2 : ? typeName (other._type)
- - ]
202 [ - - - + : 2 : + " with storage type"
- + - - ]
203 [ - - - + : 2 : + typeName (other.type ())
- - ]
204 [ - + + - : 6 : : typeName (other._type)));
+ - ]
205 : : }
206 : :
207 : 52 : assign (other);
208 : 52 : return *this;
209 : : }
210 : :
211 : : DbValue&
212 : 11 : DbValue::operator= (DbValue&& other)
213 : : {
214 [ + + ]: 11 : if (!canAssign (other))
215 : : {
216 [ + - + - ]: 2 : throw ErrTypeMisMatch (typeName (_type) + "="
217 [ + - ]: 2 : + (other._type == Type::Variant
218 [ - - - - : 2 : ? typeName (other._type)
+ - - - ]
219 [ - - - + : 1 : + " with storage type"
- + - - ]
220 [ - - - + : 1 : + typeName (other.type ())
- - ]
221 [ - + + - ]: 3 : : typeName (other._type)));
222 : : }
223 : 10 : _value = std::move (other._value);
224 : :
225 : 10 : return *this;
226 : : }
227 : :
228 : : DbValue&
229 : 11 : DbValue::operator= (int val)
230 : : {
231 : 11 : set (val);
232 : 3 : return *this;
233 : : }
234 : :
235 : : DbValue&
236 : 9 : DbValue::operator= (const int64_t& val)
237 : : {
238 : 9 : set (val);
239 : 1 : return *this;
240 : : }
241 : :
242 : : DbValue&
243 : 9 : DbValue::operator= (const double& val)
244 : : {
245 : 9 : set (val);
246 : 1 : return *this;
247 : : }
248 : :
249 : : DbValue&
250 : 10 : DbValue::operator= (const std::string& val)
251 : : {
252 : 10 : set (val);
253 : 2 : return *this;
254 : : }
255 : :
256 : : DbValue&
257 : 9 : DbValue::operator= (const Blob& val)
258 : : {
259 : 9 : set (val);
260 : 1 : return *this;
261 : : }
262 : :
263 : : DbValue&
264 : 34 : DbValue::operator= (const Value& val)
265 : : {
266 [ + + ]: 34 : ensure (_type).oneOf (val.getType (), Type::Variant);
267 : 2 : _value = val;
268 : 2 : return *this;
269 : : }
270 : :
271 : : void
272 : 20 : DbValue::set (int val)
273 : : {
274 : : // not sure if I leaf this conversion,
275 : : // but its better in text dbval.set(12); it type is real
276 [ + + ]: 20 : if (_type == Type::Real)
277 : 1 : set (static_cast<double> (val));
278 : : else
279 : 19 : set (static_cast<int64_t> (val));
280 : 4 : }
281 : :
282 : : void
283 : 36 : DbValue::set (int64_t val)
284 : : {
285 [ + + ]: 36 : ensure (_type).oneOf (Type::Int, Type::Variant);
286 : 4 : _value = val;
287 : 4 : }
288 : :
289 : : void
290 : 18 : DbValue::set (double val)
291 : : {
292 [ + + ]: 18 : ensure (_type).oneOf (Type::Real, Type::Variant);
293 : 2 : _value = val;
294 : 2 : }
295 : :
296 : : void
297 : 19 : DbValue::set (const std::string& val)
298 : : {
299 [ + + ]: 19 : ensure (_type).oneOf (Type::Text, Type::Variant);
300 : 3 : _value = val;
301 : 3 : }
302 : :
303 : : const Value&
304 : 82 : DbValue::getValue () const noexcept
305 : : {
306 : 82 : return _value;
307 : : }
308 : :
309 : : void
310 : 17 : DbValue::set (const Blob& val)
311 : : {
312 [ + + ]: 17 : ensure (_type).oneOf (Type::Blob, Type::Variant);
313 : 1 : _value = val;
314 : 1 : }
315 : :
316 : : const int64_t&
317 : 40 : DbValue::getInt () const
318 : : {
319 : 40 : return _value.int64 ();
320 : : }
321 : :
322 : : int64_t
323 : 18 : DbValue::getInt (int64_t defval) const
324 : : {
325 [ + + ]: 18 : if (isNull ())
326 : 4 : return defval;
327 : :
328 : 14 : return _value.int64 ();
329 : : }
330 : :
331 : : const double&
332 : 17 : DbValue::getReal () const
333 : : {
334 : 17 : return _value.real ();
335 : : }
336 : :
337 : : double
338 : 7 : DbValue::getReal (double defval) const
339 : : {
340 [ + + ]: 7 : if (isNull ())
341 : 2 : return defval;
342 : :
343 : 5 : return _value.real ();
344 : : }
345 : :
346 : : const std::string&
347 : 46 : DbValue::getText () const
348 : : {
349 : 46 : return _value.text ();
350 : : }
351 : :
352 : : std::string
353 : 7 : DbValue::getText (const std::string& defval) const
354 : : {
355 [ + + ]: 7 : if (isNull ())
356 : 2 : return defval;
357 : :
358 : 5 : return _value.text ();
359 : : }
360 : :
361 : : const Blob&
362 : 13 : DbValue::getBlob () const
363 : : {
364 : 13 : return _value.blob ();
365 : : }
366 : :
367 : : Blob
368 : 7 : DbValue::getBlob (const Blob& defval) const
369 : : {
370 [ + + ]: 7 : if (isNull ())
371 : 2 : return defval;
372 : :
373 : 5 : return _value.blob ();
374 : : }
375 : :
376 : : int64_t
377 : 6 : DbValue::get (int64_t defval) const
378 : : {
379 [ + + ]: 6 : if (_value.getType () != Type::Int)
380 : 5 : return defval;
381 : :
382 : 1 : return _value.int64 ();
383 : : }
384 : :
385 : : int64_t
386 : 6 : DbValue::get (int defval) const
387 : : {
388 [ + + ]: 6 : if (_value.getType () != Type::Int)
389 : 5 : return defval;
390 : :
391 : 1 : return _value.int64 ();
392 : : }
393 : :
394 : : double
395 : 7 : DbValue::get (double defval) const
396 : : {
397 [ + + ]: 7 : if (_value.getType () != Type::Real)
398 : 6 : return defval;
399 : :
400 : 1 : return _value.real ();
401 : : }
402 : :
403 : : std::string // TODO consider change to reference, with warning in the doc
404 : 9 : DbValue::get (const std::string& defval) const
405 : : {
406 [ + + ]: 9 : if (_value.getType () != Type::Text)
407 : 8 : return defval;
408 : :
409 : 1 : return _value.text ();
410 : : }
411 : :
412 : : Blob // TODO consider change to reference, with warning in the doc
413 : 7 : DbValue::get (const Blob& defval) const
414 : : {
415 [ + + ]: 7 : if (_value.getType () != Type::Blob)
416 : 6 : return defval;
417 : :
418 : 1 : return _value.blob ();
419 : : }
420 : :
421 : : std::string
422 : 2 : DbValue::ejectText ()
423 : : {
424 : 2 : return _value.ejectText ();
425 : : }
426 : :
427 : : Blob
428 : 2 : DbValue::ejectBlob ()
429 : : {
430 : 2 : return _value.ejectBlob ();
431 : : }
432 : :
433 : : std::ostream&
434 : 18 : operator<< (std::ostream& stm, const sl3::DbValue& v)
435 : : {
436 : 18 : stm << v.getValue ();
437 : 18 : return stm;
438 : : }
439 : :
440 : : void
441 : 1 : DbValue::setNull ()
442 : : {
443 : 1 : _value.setNull ();
444 : 1 : }
445 : :
446 : : bool
447 : 44 : DbValue::isNull () const
448 : : {
449 : 44 : return _value.isNull ();
450 : : }
451 : :
452 : : Type
453 : 326 : DbValue::dbtype () const
454 : : {
455 : 326 : return _type;
456 : : }
457 : :
458 : : Type
459 : 144 : DbValue::type () const
460 : : {
461 : 144 : return _value.getType ();
462 : : }
463 : :
464 : : bool
465 : 77 : DbValue::canAssign (const DbValue& other) const
466 : : {
467 [ + + ]: 77 : if (this->dbtype () != Type::Variant)
468 : : {
469 [ + + ]: 22 : if (other.dbtype () == Type::Variant)
470 : : {
471 [ + - ]: 2 : return check (other.type ()).oneOf (_type, Type::Null);
472 : : }
473 : : else
474 : : {
475 : 20 : return check (_type).sameAs (other.dbtype ());
476 : : }
477 : : }
478 : :
479 : 55 : return true;
480 : : }
481 : :
482 : : void
483 : 55 : DbValue::assign (const DbValue& other)
484 : : {
485 : 55 : _value = other._value;
486 : 55 : }
487 : :
488 : : } // ns
|