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 : }
|