LCOV - code coverage report
Current view: top level - libgnucash/backend/sql - gnc-owner-sql.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 73.4 % 109 80
Test Date: 2026-11-02 18:19:43 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /********************************************************************\
       2              :  * gnc-owner-sql.c -- owner sql implementation                      *
       3              :  *                                                                  *
       4              :  * This program is free software; you can redistribute it and/or    *
       5              :  * modify it under the terms of the GNU General Public License as   *
       6              :  * published by the Free Software Foundation; either version 2 of   *
       7              :  * the License, or (at your option) any later version.              *
       8              :  *                                                                  *
       9              :  * This program is distributed in the hope that it will be useful,  *
      10              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      11              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      12              :  * GNU General Public License for more details.                     *
      13              :  *                                                                  *
      14              :  * You should have received a copy of the GNU General Public License*
      15              :  * along with this program; if not, contact:                        *
      16              :  *                                                                  *
      17              :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      18              :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      19              :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      20              :  *                                                                  *
      21              : \********************************************************************/
      22              : 
      23              : /** @file gnc-owner-sql.c
      24              :  *  @brief load and save address data to SQL
      25              :  *  @author Copyright (c) 2007-2008 Phil Longstaff <plongstaff@rogers.com>
      26              :  *
      27              :  * This file implements the top-level QofBackend API for saving/
      28              :  * restoring data to/from an SQL database
      29              :  */
      30              : #include <guid.hpp>
      31              : #include <config.h>
      32              : #include <qof.h>
      33              : #include <glib.h>
      34              : #include "gncCustomerP.h"
      35              : #include "gncJobP.h"
      36              : #include "gncEmployeeP.h"
      37              : #include "gncVendorP.h"
      38              : #include <cstdlib>
      39              : #include <cstring>
      40              : #include <sstream>
      41              : #include "gnc-sql-backend.hpp"
      42              : #include "gnc-sql-column-table-entry.hpp"
      43              : 
      44              : static QofLogModule log_module = G_LOG_DOMAIN;
      45              : 
      46              : typedef void (*OwnerSetterFunc) (gpointer, GncOwner*);
      47              : typedef GncOwner* (*OwnerGetterFunc) (const gpointer);
      48              : 
      49              : template<> void
      50            4 : GncSqlColumnTableEntryImpl<CT_OWNERREF>::load (const GncSqlBackend* sql_be,
      51              :                                                GncSqlRow& row,
      52              :                                                QofIdTypeConst obj_name,
      53              :                                                gpointer pObject) const noexcept
      54              : {
      55              :     GncOwnerType type;
      56              :     GncGUID guid;
      57              :     GncOwner owner;
      58            4 :     GncGUID* pGuid = nullptr;
      59              : 
      60            6 :     g_return_if_fail (sql_be != nullptr);
      61            4 :     g_return_if_fail (pObject != nullptr);
      62              : 
      63            4 :     auto book = sql_be->book();
      64            8 :     auto buf = std::string{m_col_name} + "_type";
      65              :     try
      66              :     {
      67            4 :         type = static_cast<decltype(type)>(row.get_int_at_col(buf.c_str()).value_or(0));
      68            8 :         buf = std::string{m_col_name} + "_guid";
      69            4 :         auto val = row.get_string_at_col (buf.c_str());
      70            4 :         if (val && string_to_guid (val->c_str(), &guid))
      71            2 :             pGuid = &guid;
      72            4 :     }
      73            0 :     catch (std::invalid_argument&)
      74              :     {
      75            0 :         return;
      76            0 :     }
      77            4 :     if (type == GNC_OWNER_NONE || pGuid == nullptr)
      78            2 :         return;
      79              : 
      80            2 :     switch (type)
      81              :     {
      82            0 :     case GNC_OWNER_CUSTOMER:
      83              :     {
      84            0 :         GncCustomer* cust = NULL;
      85              : 
      86            0 :         if (pGuid != NULL)
      87              :         {
      88            0 :             cust = gncCustomerLookup (book, pGuid);
      89            0 :             if (cust == NULL)
      90              :             {
      91            0 :                 cust = gncCustomerCreate (book);
      92            0 :                 gncCustomerSetGUID (cust, &guid);
      93              :             }
      94              :         }
      95            0 :         gncOwnerInitCustomer (&owner, cust);
      96            0 :         break;
      97              :     }
      98              : 
      99            1 :     case GNC_OWNER_JOB:
     100              :     {
     101            1 :         GncJob* job = NULL;
     102              : 
     103            1 :         if (pGuid != NULL)
     104              :         {
     105            1 :             job = gncJobLookup (book, pGuid);
     106            1 :             if (job == NULL)
     107              :             {
     108            1 :                 job = gncJobCreate (book);
     109            1 :                 gncJobSetGUID (job, &guid);
     110              :             }
     111              :         }
     112            1 :         gncOwnerInitJob (&owner, job);
     113            1 :         break;
     114              :     }
     115              : 
     116            1 :     case GNC_OWNER_VENDOR:
     117              :     {
     118            1 :         GncVendor* vendor = NULL;
     119              : 
     120            1 :         if (pGuid != NULL)
     121              :         {
     122            1 :             vendor = gncVendorLookup (book, pGuid);
     123            1 :             if (vendor == NULL)
     124              :             {
     125            1 :                 vendor = gncVendorCreate (book);
     126            1 :                 gncVendorSetGUID (vendor, &guid);
     127              :             }
     128              :         }
     129            1 :         gncOwnerInitVendor (&owner, vendor);
     130            1 :         break;
     131              :     }
     132              : 
     133            0 :     case GNC_OWNER_EMPLOYEE:
     134              :     {
     135            0 :         GncEmployee* employee = NULL;
     136              : 
     137            0 :         if (pGuid != NULL)
     138              :         {
     139            0 :             employee = gncEmployeeLookup (book, pGuid);
     140            0 :             if (employee == NULL)
     141              :             {
     142            0 :                 employee = gncEmployeeCreate (book);
     143            0 :                 gncEmployeeSetGUID (employee, &guid);
     144              :             }
     145              :         }
     146            0 :         gncOwnerInitEmployee (&owner, employee);
     147            0 :         break;
     148              :     }
     149              : 
     150            0 :     default:
     151            0 :         PWARN ("Invalid owner type: %d\n", type);
     152              :     }
     153            2 :     set_parameter (pObject, &owner, get_setter(obj_name), m_gobj_param_name);
     154            4 : }
     155              : 
     156              : template<> void
     157           30 : GncSqlColumnTableEntryImpl<CT_OWNERREF>::add_to_table(ColVec& vec) const noexcept
     158              : {
     159           30 :     auto buf = g_strdup_printf ("%s_type", m_col_name);
     160           90 :     GncSqlColumnInfo info(buf, BCT_INT, 0, false, false,
     161           60 :                           m_flags & COL_PKEY, m_flags & COL_NNUL);
     162           30 :     vec.emplace_back(std::move(info));
     163              : /* Buf isn't leaking, it belongs to ColVec now. */
     164           30 :     buf = g_strdup_printf ("%s_guid", m_col_name);
     165           90 :     GncSqlColumnInfo info2(buf, BCT_STRING, GUID_ENCODING_LENGTH, false, false,
     166           60 :                            m_flags & COL_PKEY, m_flags & COL_NNUL);
     167           30 :     vec.emplace_back(std::move(info2));
     168           30 : }
     169              : 
     170              : template<> void
     171            4 : GncSqlColumnTableEntryImpl<CT_OWNERREF>::add_to_query(QofIdTypeConst obj_name,
     172              :                                                       const gpointer pObject,
     173              :                                                       PairVec& vec) const noexcept
     174              : {
     175            6 :     g_return_if_fail (obj_name != NULL);
     176            4 :     g_return_if_fail (pObject != NULL);
     177              : 
     178            4 :     auto getter = (OwnerGetterFunc)get_getter (obj_name);
     179            4 :     auto owner = (*getter) (pObject);
     180              : 
     181            4 :     QofInstance* inst = nullptr;
     182            4 :     GncOwnerType type = GNC_OWNER_NONE;
     183              : 
     184            8 :     auto type_hdr = std::string{m_col_name} + "_type";
     185            8 :     auto guid_hdr = std::string{m_col_name} + "_guid";
     186              : 
     187            4 :     if (owner != nullptr)
     188              :     {
     189            4 :         type = gncOwnerGetType (owner);
     190            4 :         switch (type)
     191              :         {
     192            2 :         case GNC_OWNER_CUSTOMER:
     193            2 :             inst = QOF_INSTANCE (gncOwnerGetCustomer (owner));
     194            2 :             break;
     195              : 
     196            1 :         case GNC_OWNER_JOB:
     197            1 :             inst = QOF_INSTANCE (gncOwnerGetJob (owner));
     198            1 :             break;
     199              : 
     200            1 :         case GNC_OWNER_VENDOR:
     201            1 :             inst = QOF_INSTANCE (gncOwnerGetVendor (owner));
     202            1 :             break;
     203              : 
     204            0 :         case GNC_OWNER_EMPLOYEE:
     205            0 :             inst = QOF_INSTANCE (gncOwnerGetEmployee (owner));
     206            0 :             break;
     207              : 
     208            0 :         default:
     209            0 :             PWARN ("Invalid owner type: %d\n", type);
     210              :         }
     211              :     }
     212              : 
     213            4 :     if (inst == nullptr)
     214              :     {
     215              :         /* Twice, once for type, once for guid. */
     216            4 :         vec.emplace_back (std::make_pair (type_hdr, std::string{"NULL"}));
     217            2 :         vec.emplace_back (std::make_pair (guid_hdr, std::string{"NULL"}));
     218              : 
     219            2 :         return;
     220              :     }
     221            2 :     std::ostringstream buf;
     222              : 
     223            2 :     buf << type;
     224            2 :     vec.emplace_back(std::make_pair(type_hdr, quote_string(buf.str())));
     225            2 :     buf.str("");
     226            2 :     auto guid = qof_instance_get_guid(inst);
     227            2 :     if (guid != nullptr)
     228              :     {
     229              :         char strbuff[GUID_ENCODING_LENGTH+1];
     230            2 :         guid_to_string_buff (guid, strbuff);
     231            2 :         buf << strbuff;
     232              :     }
     233              :     else
     234            0 :         buf << "NULL";
     235            2 :     vec.emplace_back(std::make_pair(guid_hdr, quote_string(buf.str())));
     236            6 : }
        

Generated by: LCOV version 2.0-1