LCOV - code coverage report
Current view: top level - src/sl3 - dbvalue.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 98.9 % 188 186
Test Date: 2026-03-17 13:39:52 Functions: 100.0 % 55 55
Branches: - 0 0

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

Generated by: LCOV version 2.0-1