LCOV - code coverage report
Current view: top level - include/sl3 - dbvalue.hpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 100.0 % 7 7
Test Date: 2026-03-17 13:39:52 Functions: 100.0 % 5 5
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                 :             : #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_ */
        

Generated by: LCOV version 2.0-1