LCOV - code coverage report
Current view: top level - src/sl3 - dbvalue.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 100.0 % 191 191
Test Date: 2024-12-09 18:45:33 Functions: 100.0 % 54 54
Branches: 61.8 % 144 89

             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
        

Generated by: LCOV version 2.0-1