Branch data 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 : 4 : 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 : 25 : GncSqlColumnTableEntryImpl<CT_OWNERREF>::add_to_table(ColVec& vec) const noexcept
158 : : {
159 : 25 : auto buf = g_strdup_printf ("%s_type", m_col_name);
160 : : GncSqlColumnInfo info(buf, BCT_INT, 0, false, false,
161 : 50 : m_flags & COL_PKEY, m_flags & COL_NNUL);
162 : 25 : vec.emplace_back(std::move(info));
163 : : /* Buf isn't leaking, it belongs to ColVec now. */
164 : 25 : buf = g_strdup_printf ("%s_guid", m_col_name);
165 : : GncSqlColumnInfo info2(buf, BCT_STRING, GUID_ENCODING_LENGTH, false, false,
166 : 50 : m_flags & COL_PKEY, m_flags & COL_NNUL);
167 : 25 : vec.emplace_back(std::move(info2));
168 : 25 : }
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 : 2 : 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 : }
|