LCOV - code coverage report
Current view: top level - libgnucash/backend/sql - gnc-sql-column-table-entry.hpp (source / functions) Hit Total Coverage
Test: gnucash.info Lines: 117 126 92.9 %
Date: 2024-10-31 11:06:40 Functions: 149 175 85.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***********************************************************************\
       2                 :            :  * gnc-sql-column-table-entry.hpp: Column Specification for SQL Table. *
       3                 :            :  *                                                                     *
       4                 :            :  * Copyright 2016 John Ralls <jralls@ceridwen.us>                      *
       5                 :            :  *                                                                     *
       6                 :            :  * This program is free software; you can redistribute it and/or       *
       7                 :            :  * modify it under the terms of the GNU General Public License as      *
       8                 :            :  * published by the Free Software Foundation; either version 2 of      *
       9                 :            :  * the License, or (at your option) any later version.                 *
      10                 :            :  *                                                                     *
      11                 :            :  * This program is distributed in the hope that it will be useful,     *
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of      *
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *
      14                 :            :  * GNU General Public License for more details.                        *
      15                 :            :  *                                                                     *
      16                 :            :  * You should have received a copy of the GNU General Public License   *
      17                 :            :  * along with this program; if not, contact:                           *
      18                 :            :  *                                                                     *
      19                 :            :  * Free Software Foundation           Voice:  +1-617-542-5942          *
      20                 :            :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652          *
      21                 :            :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                      *
      22                 :            : \***********************************************************************/
      23                 :            : 
      24                 :            : #ifndef __GNC_SQL_COLUMN_TABLE_ENTRY_HPP__
      25                 :            : #define __GNC_SQL_COLUMN_TABLE_ENTRY_HPP__
      26                 :            : 
      27                 :            : #include <qof.h>
      28                 :            : #include <memory>
      29                 :            : #include <vector>
      30                 :            : #include <iostream>
      31                 :            : #include <iomanip>
      32                 :            : 
      33                 :            : #include "gnc-sql-result.hpp"
      34                 :            : 
      35                 :            : struct GncSqlColumnInfo;
      36                 :            : using ColVec = std::vector<GncSqlColumnInfo>;
      37                 :            : using PairVec = std::vector<std::pair<std::string, std::string>>;
      38                 :            : using InstanceVec = std::vector<QofInstance*>;
      39                 :            : using uint_t = unsigned int;
      40                 :            : class GncSqlBackend;
      41                 :            : 
      42                 :            : /**
      43                 :            :  * Basic column type
      44                 :            :  */
      45                 :            : typedef enum
      46                 :            : {
      47                 :            :     BCT_STRING,
      48                 :            :     BCT_INT,
      49                 :            :     BCT_INT64,
      50                 :            :     BCT_DATE,
      51                 :            :     BCT_DOUBLE,
      52                 :            :     BCT_DATETIME
      53                 :            : } GncSqlBasicColumnType;
      54                 :            : 
      55                 :            : enum ColumnFlags : int
      56                 :            : {
      57                 :            :     COL_NO_FLAG = 0,
      58                 :            :     COL_PKEY = 0x01,    /**< The column is a primary key */
      59                 :            :     COL_NNUL = 0x02,    /**< The column may not contain a NULL value */
      60                 :            :     COL_UNIQUE = 0x04,  /**< The column must contain unique values */
      61                 :            :     COL_AUTOINC = 0x08  /**< The column is an auto-incrementing int */
      62                 :            : };
      63                 :            : 
      64                 :            : // Type for conversion of db row to object.
      65                 :            : enum GncSqlObjectType
      66                 :            : {
      67                 :            :     CT_STRING,
      68                 :            :     CT_GUID,
      69                 :            :     CT_INT,
      70                 :            :     CT_INT64,
      71                 :            :     CT_TIME,
      72                 :            :     CT_GDATE,
      73                 :            :     CT_NUMERIC,
      74                 :            :     CT_DOUBLE,
      75                 :            :     CT_BOOLEAN,
      76                 :            :     CT_ACCOUNTREF,
      77                 :            :     CT_BUDGETREF,
      78                 :            :     CT_COMMODITYREF,
      79                 :            :     CT_LOTREF,
      80                 :            :     CT_TXREF,
      81                 :            :     CT_ADDRESS,
      82                 :            :     CT_BILLTERMREF,
      83                 :            :     CT_INVOICEREF,
      84                 :            :     CT_ORDERREF,
      85                 :            :     CT_OWNERREF,
      86                 :            :     CT_TAXTABLEREF
      87                 :            : };
      88                 :            : 
      89                 :            : static inline std::string
      90                 :       1070 : quote_string(const std::string& str)
      91                 :            : {
      92                 :       1070 :     if (str == "NULL" || str == "null") return "NULL";
      93                 :            :     /* FIXME: This is here because transactions.num has a NULL
      94                 :            :      * constraint, which is dumb; it's often empty.
      95                 :            :      */
      96                 :       1070 :     if (str.empty()) return "''";
      97                 :        877 :     std::string retval;
      98                 :        877 :     retval.reserve(str.length() + 2);
      99                 :        877 :     retval.insert(0, 1, '\'');
     100                 :      17881 :     for (auto c = str.begin(); c != str.end(); ++c)
     101                 :            :     {
     102                 :      17004 :         if (*c == '\'')
     103                 :          2 :             retval += *c;
     104                 :      17004 :         retval += *c;
     105                 :            :     }
     106                 :        877 :     retval += '\'';
     107                 :        877 :     return retval;
     108                 :        877 : }
     109                 :            : 
     110                 :            : /**
     111                 :            :  * Contains all of the information required to copy information between an
     112                 :            :  * object and the database for a specific object property.
     113                 :            :  *
     114                 :            :  * If an entry contains a gobj_param_name value, this string is used as the
     115                 :            :  * property name for a call to g_object_get() or g_object_set().  If the
     116                 :            :  * gobj_param_name value is NULL but qof_param_name is not NULL, this value
     117                 :            :  * is used as the parameter name for a call to
     118                 :            :  * qof_class_get_parameter_getter().  If both of these values are NULL, getter
     119                 :            :  * and setter are the addresses of routines to return or set the parameter
     120                 :            :  * value, respectively.
     121                 :            :  *
     122                 :            :  * The database description for an object consists of an array of
     123                 :            :  * GncSqlColumnTableEntry objects, with a final member having col_name == NULL.
     124                 :            :  */
     125                 :            : 
     126                 :            : class GncSqlColumnTableEntry
     127                 :            : {
     128                 :            : public:
     129                 :      13452 :     GncSqlColumnTableEntry (const char* name, const GncSqlObjectType type,
     130                 :            :                             unsigned int s,
     131                 :            :                             int f, const char* gobj_name = nullptr,
     132                 :            :                             const char* qof_name = nullptr,
     133                 :            :                             QofAccessFunc get = nullptr,
     134                 :      13452 :                             QofSetterFunc set = nullptr) :
     135                 :      13452 :         m_col_name{name}, m_col_type{type}, m_size{s},
     136                 :      13452 :         m_flags{static_cast<ColumnFlags>(f)},
     137                 :      13452 :         m_gobj_param_name{gobj_name}, m_qof_param_name{qof_name}, m_getter{get},
     138                 :      13452 :         m_setter{set} {}
     139                 :      13452 :     virtual ~GncSqlColumnTableEntry() = default;
     140                 :            : 
     141                 :            :     /**
     142                 :            :      * Load a value into an object from the database row.
     143                 :            :      */
     144                 :            :     virtual void load(const GncSqlBackend* sql_be, GncSqlRow& row,
     145                 :            :                       QofIdTypeConst obj_name, void* pObject) const noexcept = 0;
     146                 :            :     /**
     147                 :            :      * Add a GncSqlColumnInfo structure for the column type to a
     148                 :            :      * ColVec.
     149                 :            :      */
     150                 :            :     virtual void add_to_table(ColVec& vec) const noexcept = 0;
     151                 :            :     /**
     152                 :            :      * Add a pair of the table column heading and object's value's string
     153                 :            :      * representation to a PairVec; used for constructing WHERE clauses and
     154                 :            :      * UPDATE statements.
     155                 :            :      */
     156                 :            :     virtual void add_to_query(QofIdTypeConst obj_name,
     157                 :            :                               void* pObject, PairVec& vec) const noexcept = 0;
     158                 :            :     /**
     159                 :            :      * Retrieve the getter function depending on whether it's an auto-increment
     160                 :            :      * field, a QofClass getter, or a function passed to the constructor.
     161                 :            :      */
     162                 :            :     QofAccessFunc get_getter(QofIdTypeConst obj_name) const noexcept;
     163                 :            :     /**
     164                 :            :      * Retrieve the setter function depending on whether it's an auto-increment
     165                 :            :      * field, a QofClass getter, or a function passed to the constructor.
     166                 :            :      */
     167                 :            :     QofSetterFunc get_setter(QofIdTypeConst obj_name) const noexcept;
     168                 :            :     /**
     169                 :            :      * Retrieve the field name so that we don't need to make
     170                 :            :      * create_single_col_select_statement and friend.
     171                 :            :      */
     172                 :          0 :     const char* name() const noexcept { return m_col_name; }
     173                 :            :     /**
     174                 :            :      * Report if the entry is an auto-increment field.
     175                 :            :      */
     176                 :       2033 :     bool is_autoincr() const noexcept { return m_flags & COL_AUTOINC; }
     177                 :            :     /* On the other hand, our implementation class and GncSqlColumnInfo need to
     178                 :            :      * be able to read our member variables.
     179                 :            :      */
     180                 :            :     template<GncSqlObjectType Otype> friend class GncSqlColumnTableEntryImpl;
     181                 :            :     friend struct GncSqlColumnInfo;
     182                 :        108 :     template<typename T> void load_from_guid_ref(GncSqlRow& row,
     183                 :            :                                                  QofIdTypeConst obj_name,
     184                 :            :                                                  void* pObject, T get_ref)
     185                 :            :         const noexcept
     186                 :            :     {
     187                 :            :         static QofLogModule log_module = G_LOG_DOMAIN;
     188                 :        108 :         g_return_if_fail (pObject != NULL);
     189                 :            : 
     190                 :            :         GncGUID guid;
     191                 :        108 :         auto val = row.get_string_at_col (m_col_name);
     192                 :        108 :         if (!val)
     193                 :            :         {
     194                 :          0 :             DEBUG("set parameter: No string in column %s.", m_col_name);
     195                 :          0 :             return;
     196                 :            :         }
     197                 :            : 
     198                 :        108 :         if (string_to_guid (val->c_str(), &guid))
     199                 :            :         {
     200                 :         70 :             auto target = get_ref(&guid);
     201                 :         70 :             if (target != nullptr)
     202                 :         70 :                 set_parameter (pObject, target, get_setter(obj_name),
     203                 :         70 :                                m_gobj_param_name);
     204                 :            :             else
     205                 :          0 :                 DEBUG("GUID %s returned null %s reference.",
     206                 :            :                       val->c_str(), m_gobj_param_name);
     207                 :            :         }
     208                 :            :         else
     209                 :            :         {
     210                 :         38 :             if (val->empty())
     211                 :         38 :                 DEBUG("Can't load empty guid string for column %s", m_col_name);
     212                 :            :             else
     213                 :          0 :                 DEBUG("Invalid GUID %s for column %s", val->c_str(), m_col_name);
     214                 :            :         }
     215                 :        108 :     }
     216                 :            : 
     217                 :            : 
     218                 :            : protected:
     219                 :            :     template <typename T> T
     220                 :            :     get_row_value_from_object(QofIdTypeConst obj_name, const void* pObject) const;
     221                 :            :     template <typename T> void
     222                 :            :     add_value_to_vec(QofIdTypeConst obj_name,
     223                 :            :                      const void* pObject, PairVec& vec) const;
     224                 :            : /**
     225                 :            :  * Adds a name/guid std::pair to a PairVec for creating a query.
     226                 :            :  *
     227                 :            :  * @param sql_be SQL backend struct
     228                 :            :  * @param obj_name QOF object type name
     229                 :            :  * @param pObject Object
     230                 :            :  * @param pList List
     231                 :            :  */
     232                 :            :     void add_objectref_guid_to_query (QofIdTypeConst obj_name,
     233                 :            :                                       const void* pObject,
     234                 :            :                                       PairVec& vec) const noexcept;
     235                 :            : /**
     236                 :            :  * Adds a column info structure for an object reference GncGUID to a ColVec.
     237                 :            :  *
     238                 :            :  * @param sql_be SQL backend struct
     239                 :            :  * @param pList List
     240                 :            :  */
     241                 :            :     void add_objectref_guid_to_table (ColVec& vec) const noexcept;
     242                 :            : private:
     243                 :            :     const char* m_col_name = nullptr;        /**< Column name */
     244                 :            :     const GncSqlObjectType m_col_type;        /**< Column type */
     245                 :            :     unsigned int m_size;       /**< Column size in bytes, for string columns */
     246                 :            :     ColumnFlags m_flags;           /**< Column flags */
     247                 :            :     const char* m_gobj_param_name = nullptr; /**< If non-null, g_object param name */
     248                 :            :     const char* m_qof_param_name = nullptr;  /**< If non-null, qof parameter name */
     249                 :            :     QofAccessFunc m_getter;        /**< General access function */
     250                 :            :     QofSetterFunc m_setter;        /**< General setter function */
     251                 :            :     template <typename T> T get_row_value_from_object(QofIdTypeConst obj_name,
     252                 :            :                                                       const void* pObject,
     253                 :            :                                                       std::true_type) const;
     254                 :            :     template <typename T> T get_row_value_from_object(QofIdTypeConst obj_name,
     255                 :            :                                                       const void* pObject,
     256                 :            :                                                       std::false_type) const;
     257                 :            :     template <typename T> void add_value_to_vec(QofIdTypeConst obj_name,
     258                 :            :                                                 const void* pObject,
     259                 :            :                                                 PairVec& vec, std::true_type) const;
     260                 :            :     template <typename T> void add_value_to_vec(QofIdTypeConst obj_name,
     261                 :            :                                                 const void* pObject,
     262                 :            :                                                 PairVec& vec, std::false_type) const;
     263                 :            : 
     264                 :            : };
     265                 :            : 
     266                 :            : template <GncSqlObjectType Type>
     267                 :            : class GncSqlColumnTableEntryImpl final : public GncSqlColumnTableEntry
     268                 :            : {
     269                 :            : public:
     270                 :      13452 :     GncSqlColumnTableEntryImpl (const char* name, const GncSqlObjectType type,
     271                 :            :                                 unsigned int s,
     272                 :            :                                 int f, const char* gobj_name = nullptr,
     273                 :            :                                 const char* qof_name = nullptr,
     274                 :            :                                 QofAccessFunc get = nullptr,
     275                 :            :                                 QofSetterFunc set = nullptr) :
     276                 :      13452 :         GncSqlColumnTableEntry (name, type, s, f, gobj_name,qof_name, get, set)
     277                 :      13452 :         {}
     278                 :            : 
     279                 :            :     void load(const GncSqlBackend* sql_be, GncSqlRow& row,  QofIdTypeConst obj_name,
     280                 :            :               void* pObject) const noexcept override;
     281                 :            :     void add_to_table(ColVec& vec) const noexcept override;
     282                 :            :     void add_to_query(QofIdTypeConst obj_name, void* pObject, PairVec& vec)
     283                 :            :         const noexcept override;
     284                 :            : };
     285                 :            : 
     286                 :            : using GncSqlColumnTableEntryPtr = std::shared_ptr<GncSqlColumnTableEntry>;
     287                 :            : using EntryVec = std::vector<GncSqlColumnTableEntryPtr>;
     288                 :            : 
     289                 :            : template <GncSqlObjectType Type>
     290                 :            : std::shared_ptr<GncSqlColumnTableEntryImpl<Type>>
     291                 :        472 : gnc_sql_make_table_entry(const char* name, unsigned int s, int f)
     292                 :            : {
     293                 :        472 :     return std::make_shared<GncSqlColumnTableEntryImpl<Type>>(name, Type, s, f);
     294                 :            : }
     295                 :            : 
     296                 :            : template <GncSqlObjectType Type>
     297                 :            : std::shared_ptr<GncSqlColumnTableEntryImpl<Type>>
     298                 :       6667 : gnc_sql_make_table_entry(const char* name, unsigned int s, int f,
     299                 :            :                          const char* param)
     300                 :            : {
     301                 :            :     return std::make_shared<GncSqlColumnTableEntryImpl<Type>>(name, Type, s,
     302                 :       6667 :                                                               f, param);
     303                 :            : }
     304                 :            : 
     305                 :            : class is_qof : public std::true_type {};
     306                 :            : 
     307                 :            : template <GncSqlObjectType Type>
     308                 :            : std::shared_ptr<GncSqlColumnTableEntryImpl<Type>>
     309                 :       2596 : gnc_sql_make_table_entry(const char* name, unsigned int s, int f,
     310                 :            :                          const char* param, bool qofp)
     311                 :            : {
     312                 :            :     return std::make_shared<GncSqlColumnTableEntryImpl<Type>>(name, Type, s,
     313                 :       5192 :                                                               f, nullptr,
     314                 :       2596 :                                                               param);
     315                 :            : }
     316                 :            : 
     317                 :            : template <GncSqlObjectType Type>
     318                 :            : std::shared_ptr<GncSqlColumnTableEntryImpl<Type>>
     319                 :       3658 : gnc_sql_make_table_entry(const char* name, unsigned int s, int f,
     320                 :            :                          QofAccessFunc get, QofSetterFunc set)
     321                 :            : {
     322                 :            :     return std::make_shared<GncSqlColumnTableEntryImpl<Type>>(
     323                 :       3658 :         name, Type, s, f, nullptr, nullptr, get, set);
     324                 :            : }
     325                 :            : 
     326                 :            : 
     327                 :            : template <typename T> T
     328                 :       1784 : GncSqlColumnTableEntry::get_row_value_from_object(QofIdTypeConst obj_name,
     329                 :            :                                                   const void* pObject) const
     330                 :            : {
     331                 :       3568 :     return get_row_value_from_object<T>(obj_name, pObject,
     332                 :       1784 :                                         std::is_pointer<T>());
     333                 :            : }
     334                 :            : 
     335                 :            : template <typename T> T
     336                 :       1353 : GncSqlColumnTableEntry::get_row_value_from_object(QofIdTypeConst obj_name,
     337                 :            :                                                   const void* pObject,
     338                 :            :                                                   std::true_type) const
     339                 :            : {
     340                 :       1353 :     g_return_val_if_fail(obj_name != nullptr && pObject != nullptr, nullptr);
     341                 :       1353 :     T result = nullptr;
     342                 :       1353 :     if (m_gobj_param_name != nullptr)
     343                 :        664 :         g_object_get(const_cast<void*>(pObject), m_gobj_param_name,
     344                 :            :                      &result, nullptr);
     345                 :            :     else
     346                 :            :     {
     347                 :        689 :         QofAccessFunc getter = get_getter(obj_name);
     348                 :        689 :         if (getter != nullptr)
     349                 :        689 :             result = reinterpret_cast<T>((getter)(const_cast<void*>(pObject),
     350                 :            :                                                   nullptr));
     351                 :            :     }
     352                 :       1353 :     return result;
     353                 :            : }
     354                 :            : 
     355                 :            : template <typename T> T
     356                 :         67 : GncSqlColumnTableEntry::get_row_value_from_object(QofIdTypeConst obj_name,
     357                 :            :                                                   const void* pObject,
     358                 :            :                                                   std::false_type) const
     359                 :            : {
     360                 :         67 :     g_return_val_if_fail(obj_name != nullptr && pObject != nullptr,
     361                 :            :                          static_cast<T>(0));
     362                 :         67 :     T result = static_cast<T>(0);
     363                 :         67 :     if (m_gobj_param_name != nullptr)
     364                 :          2 :         g_object_get(const_cast<void*>(pObject), m_gobj_param_name,
     365                 :            :                      &result, nullptr);
     366                 :            :     else
     367                 :            :     {
     368                 :         65 :         QofAccessFunc getter = get_getter(obj_name);
     369                 :         65 :         if (getter != nullptr)
     370                 :         65 :             result = reinterpret_cast<T>((getter)(const_cast<void*>(pObject),
     371                 :            :                                                   nullptr));
     372                 :            :     }
     373                 :         67 :     return result;
     374                 :            : }
     375                 :            : 
     376                 :            : template <typename T> void
     377                 :        496 : GncSqlColumnTableEntry::add_value_to_vec(QofIdTypeConst obj_name,
     378                 :            :                                          const void* pObject,
     379                 :            :                                          PairVec& vec) const
     380                 :            : {
     381                 :        496 :     add_value_to_vec<T>(obj_name, pObject, vec, std::is_pointer<T>());
     382                 :        496 : }
     383                 :            : 
     384                 :            : template <typename T> void
     385                 :            : GncSqlColumnTableEntry::add_value_to_vec(QofIdTypeConst obj_name,
     386                 :            :                                          const void* pObject,
     387                 :            :                                          PairVec& vec, std::true_type) const
     388                 :            : {
     389                 :            :     T s = get_row_value_from_object<T>(obj_name, pObject);
     390                 :            : 
     391                 :            :     if (s != nullptr)
     392                 :            :     {
     393                 :            :         std::ostringstream stream;
     394                 :            :         stream << *s;
     395                 :            :         vec.emplace_back(std::make_pair(std::string{m_col_name}, stream.str()));
     396                 :            :         return;
     397                 :            :     }
     398                 :            : }
     399                 :            : 
     400                 :            : template <> inline  void
     401                 :         65 : GncSqlColumnTableEntry::add_value_to_vec<double*>(QofIdTypeConst obj_name,
     402                 :            :                                          const void* pObject,
     403                 :            :                                          PairVec& vec, std::true_type) const
     404                 :            : {
     405                 :         65 :     double* s = get_row_value_from_object<double*>(obj_name, pObject);
     406                 :            : 
     407                 :         65 :     if (s != nullptr)
     408                 :            :     {
     409                 :          3 :         std::ostringstream stream;
     410                 :          3 :         stream << std::setprecision(12) << std::fixed << *s;
     411                 :          3 :         vec.emplace_back(std::make_pair(std::string{m_col_name}, stream.str()));
     412                 :          3 :         return;
     413                 :          3 :     }
     414                 :            : }
     415                 :            : 
     416                 :            : template <typename T> void
     417                 :        431 : GncSqlColumnTableEntry::add_value_to_vec(QofIdTypeConst obj_name,
     418                 :            :                                          const void* pObject,
     419                 :            :                                          PairVec& vec, std::false_type) const
     420                 :            : {
     421                 :        431 :     T s = get_row_value_from_object<T>(obj_name, pObject);
     422                 :            : 
     423                 :        431 :     std::ostringstream stream;
     424                 :        431 :     stream << s;
     425                 :        431 :     vec.emplace_back(std::make_pair(std::string{m_col_name}, stream.str()));
     426                 :        862 :     return;
     427                 :        431 : }
     428                 :            : 
     429                 :            : template <> inline void
     430                 :            : GncSqlColumnTableEntry::add_value_to_vec<double>(QofIdTypeConst obj_name,
     431                 :            :                                          const void* pObject,
     432                 :            :                                          PairVec& vec, std::false_type) const
     433                 :            : {
     434                 :            :     double s = *get_row_value_from_object<double*>(obj_name, pObject);
     435                 :            : 
     436                 :            :     std::ostringstream stream;
     437                 :            :     stream << std::setprecision(12) << std::fixed << s;
     438                 :            :     vec.emplace_back(std::make_pair(std::string{m_col_name}, stream.str()));
     439                 :            :     return;
     440                 :            : }
     441                 :            : 
     442                 :            : /**
     443                 :            :  * Load an arbitrary object from a result row.
     444                 :            :  *
     445                 :            :  * @param sql_be: GncSqlBackend*, pass-through to the implementation loader.
     446                 :            :  * @param row: The GncSqlResult
     447                 :            :  * @param obj_name: The object-name with which to retrieve the setter func.
     448                 :            :  * @param pObject: The target object being loaded.
     449                 :            :  * @param table: The table description to interpret the row.
     450                 :            :  */
     451                 :            : void gnc_sql_load_object (const GncSqlBackend* sql_be, GncSqlRow& row,
     452                 :            :                           QofIdTypeConst obj_name, gpointer pObject,
     453                 :            :                           const EntryVec& table);
     454                 :            : /**
     455                 :            :  * Create a GncGUID from a guid stored in a row.
     456                 :            :  *
     457                 :            :  * @param sql_be: The active GncSqlBackend. Pass-throug to gnc_sql_load_object.
     458                 :            :  * @param row: The GncSqlResult row.
     459                 :            :  */
     460                 :            : const GncGUID*
     461                 :            : gnc_sql_load_guid (const GncSqlBackend* sql_be, GncSqlRow& row);
     462                 :            : 
     463                 :            : /**
     464                 :            :  * Append the GUIDs of QofInstances to a SQL query.
     465                 :            :  *
     466                 :            :  * @param sql: The SQL Query in progress to which the GncGUIDS should be appended.
     467                 :            :  * @param instances: The QofInstances
     468                 :            :  * @return The number of instances
     469                 :            :  */
     470                 :            : uint_t gnc_sql_append_guids_to_sql (std::stringstream& sql,
     471                 :            :                                     const InstanceVec& instances);
     472                 :            : 
     473                 :            : /**
     474                 :            :  *  information required to create a column in a table.
     475                 :            :  */
     476                 :            : struct GncSqlColumnInfo
     477                 :            : {
     478                 :        370 :     GncSqlColumnInfo (std::string&& name, GncSqlBasicColumnType type,
     479                 :            :                       unsigned int size = 0, bool unicode = false,
     480                 :            :                       bool autoinc = false, bool primary = false,
     481                 :        370 :                       bool not_null = false) :
     482                 :        370 :         m_name{name}, m_type{type}, m_size{size}, m_unicode{unicode},
     483                 :        370 :         m_autoinc{autoinc}, m_primary_key{primary}, m_not_null{not_null}
     484                 :        370 :         {}
     485                 :        890 :     GncSqlColumnInfo(const GncSqlColumnTableEntry& e, GncSqlBasicColumnType t,
     486                 :        890 :                      unsigned int size = 0, bool unicode = true) :
     487                 :        890 :         m_name{e.m_col_name}, m_type{t}, m_size{size}, m_unicode{unicode},
     488                 :        890 :         m_autoinc(e.m_flags & COL_AUTOINC),
     489                 :        890 :         m_primary_key(e.m_flags & COL_PKEY),
     490                 :        890 :         m_not_null(e.m_flags & COL_NNUL) {}
     491                 :            :     std::string m_name; /**< Column name */
     492                 :            :     GncSqlBasicColumnType m_type; /**< Column basic type */
     493                 :            :     unsigned int m_size; /**< Column size (string types) */
     494                 :            :     bool m_unicode; /**< Column is unicode (string types) */
     495                 :            :     bool m_autoinc; /**< Column is autoinc (int type) */
     496                 :            :     bool m_primary_key; /**< Column is the primary key */
     497                 :            :     bool m_not_null; /**< Column forbids NULL values */
     498                 :            : };
     499                 :            : 
     500                 :          0 : inline bool operator==(const GncSqlColumnInfo& l,
     501                 :            :                        const GncSqlColumnInfo& r)
     502                 :            : {
     503                 :          0 :     return l.m_name == r.m_name && l.m_type == r.m_type;
     504                 :            : }
     505                 :            : 
     506                 :          0 : inline bool operator!=(const GncSqlColumnInfo& l,
     507                 :            :                        const GncSqlColumnInfo& r)
     508                 :            : {
     509                 :          0 :     return !(l == r);
     510                 :            : }
     511                 :            : 
     512                 :            : /**
     513                 :            :  * Set an object property with a setter function.
     514                 :            :  * @param pObject void* to the object being set.
     515                 :            :  * @param item the value to be set in the property.
     516                 :            :  * @param setter The function to set the property.
     517                 :            :  * The void* is an obvious wart occasioned by the fact that we're using GLists
     518                 :            :  * to hold objects. As the rewrite progresses we'll replace that with another
     519                 :            :  * template parameter.
     520                 :            :  */
     521                 :            : template <typename T, typename P, typename F>
     522                 :        331 : void set_parameter(T object, P item, F& setter)
     523                 :            : {
     524                 :        331 :     (*setter)(object, item);
     525                 :        331 : }
     526                 :            : 
     527                 :            : template <typename T, typename P>
     528                 :        450 : void set_parameter(T object, P item, QofSetterFunc setter, std::true_type)
     529                 :            : {
     530                 :        450 :     (*setter)(object, (void*)item);
     531                 :        450 : }
     532                 :            : 
     533                 :            : template <typename T, typename P>
     534                 :         58 : void set_parameter(T object, P item, QofSetterFunc setter, std::false_type)
     535                 :            : {
     536                 :         58 :     (*setter)(object, (void*)(&item));
     537                 :         58 : }
     538                 :            : 
     539                 :            : template <typename T, typename P>
     540                 :        508 : void set_parameter(T object, P item, QofSetterFunc setter)
     541                 :            : {
     542                 :        508 :     set_parameter(object, item, setter, std::is_pointer<P>());
     543                 :        508 : }
     544                 :            : 
     545                 :            : /**
     546                 :            :  * Set an object property with g_object_set.
     547                 :            :  * @param pObject void* to the object being set.
     548                 :            :  * @param item the value to set in the property.
     549                 :            :  * @param property the property name.
     550                 :            :  * The void* is an obvious wart. So is g_object_set, partly because it's GObject
     551                 :            :  * but mostly because it works off of string comparisons.
     552                 :            :  */
     553                 :            : template <typename T, typename P>
     554                 :        628 : void set_parameter(T object, P item, const char* property)
     555                 :            : {
     556                 :            :     // Properly use qof_begin_edit and qof_commit_edit{_part2}
     557                 :            :     // here. This is needed to reset the infant state of objects
     558                 :            :     // when loading them initially from sql. Failing to do so
     559                 :            :     // could prevent future editing of these objects
     560                 :            :     // Example of this is https://bugs.gnucash.org/show_bug.cgi?id=795944
     561                 :        628 :     qof_begin_edit(QOF_INSTANCE(object));
     562                 :        628 :     g_object_set(object, property, item, nullptr);
     563                 :        628 :     if (!qof_commit_edit(QOF_INSTANCE(object))) return;
     564                 :            :     // FIXME I can't use object specific callbacks in generic code
     565                 :            :     // so for now these will silently fail. As the GObject based method
     566                 :            :     // of setting qof objects should go away eventually I won't bother
     567                 :            :     // finding a proper solution for this.
     568                 :        173 :     qof_commit_edit_part2(QOF_INSTANCE(object), nullptr, nullptr, nullptr);
     569                 :            : };
     570                 :            : 
     571                 :            : /**
     572                 :            :  * Set an object property with either a g_object_set or a setter.
     573                 :            :  *
     574                 :            :  * See previous templates for the parameter meanings. This is clunky but fits in
     575                 :            :  * the current architecture for refactoring.
     576                 :            :  */
     577                 :            : template <typename T, typename P, typename F>
     578                 :       1469 : void set_parameter(T object, P item, F setter, const char* property)
     579                 :            : {
     580                 :       1469 :     if (property)
     581                 :        630 :         set_parameter(object, item, property);
     582                 :            :     else
     583                 :        839 :         set_parameter(object, item, setter);
     584                 :       1469 : }
     585                 :            : 
     586                 :            : #endif //__GNC_SQL_COLUMN_TABLE_ENTRY_HPP__

Generated by: LCOV version 1.14