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: 2024-12-09 18:45:33 Functions: 100.0 % 5 5
Branches: 75.0 % 4 3

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

Generated by: LCOV version 2.0-1