GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-customer-sql.cpp
1/********************************************************************\
2 * gnc-customer-sql.c -- customer sql backend *
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
30#include <glib.h>
31
32#include <config.h>
33
34#include <stdlib.h>
35#include <string.h>
36
37#include "gncBillTermP.h"
38#include "gncCustomerP.h"
39#include "gncTaxTableP.h"
40
41#include "gnc-sql-connection.hpp"
42#include "gnc-sql-backend.hpp"
43#include "gnc-sql-object-backend.hpp"
44#include "gnc-sql-column-table-entry.hpp"
45#include "gnc-slots-sql.h"
46#include "gnc-customer-sql.h"
47#include "gnc-bill-term-sql.h"
48#include "gnc-tax-table-sql.h"
49
50#define _GNC_MOD_NAME GNC_ID_CUSTOMER
51
52static QofLogModule log_module = G_LOG_DOMAIN;
53
54#define TABLE_NAME "customers"
55#define TABLE_VERSION 2
56
57#define MAX_NAME_LEN 2048
58#define MAX_ID_LEN 2048
59#define MAX_NOTES_LEN 2048
60
61static EntryVec col_table
62({
63 gnc_sql_make_table_entry<CT_GUID>("guid", 0, COL_NNUL | COL_PKEY, "guid" ),
64 gnc_sql_make_table_entry<CT_STRING>("name", MAX_NAME_LEN, COL_NNUL, "name"),
65 gnc_sql_make_table_entry<CT_STRING>("id", MAX_ID_LEN, COL_NNUL,
66 CUSTOMER_ID, true),
67 gnc_sql_make_table_entry<CT_STRING>("notes", MAX_NOTES_LEN, COL_NNUL,
68 CUSTOMER_NOTES, true),
69 gnc_sql_make_table_entry<CT_BOOLEAN>("active", 0, COL_NNUL,
70 QOF_PARAM_ACTIVE, true),
71 gnc_sql_make_table_entry<CT_NUMERIC>("discount", 0, COL_NNUL,
72 CUSTOMER_DISCOUNT, true),
73 gnc_sql_make_table_entry<CT_NUMERIC>("credit", 0, COL_NNUL,
74 CUSTOMER_CREDIT, true),
75 gnc_sql_make_table_entry<CT_COMMODITYREF>("currency", 0, COL_NNUL,
76 (QofAccessFunc)gncCustomerGetCurrency,
77 (QofSetterFunc)gncCustomerSetCurrency),
78 gnc_sql_make_table_entry<CT_BOOLEAN>("tax_override", 0, COL_NNUL,
79 CUSTOMER_TT_OVER, true),
80 gnc_sql_make_table_entry<CT_ADDRESS>("addr", 0, 0, CUSTOMER_ADDR,
81 true),
82 gnc_sql_make_table_entry<CT_ADDRESS>("shipaddr", 0, 0, CUSTOMER_SHIPADDR,
83 true),
84 gnc_sql_make_table_entry<CT_BILLTERMREF>("terms", 0, 0, CUSTOMER_TERMS,
85 true),
86 gnc_sql_make_table_entry<CT_INT>("tax_included", 0, 0,
87 (QofAccessFunc)gncCustomerGetTaxIncluded,
88 (QofSetterFunc)gncCustomerSetTaxIncluded),
89 gnc_sql_make_table_entry<CT_TAXTABLEREF>("taxtable", 0, 0,
90 (QofAccessFunc)gncCustomerGetTaxTable,
91 (QofSetterFunc)gncCustomerSetTaxTable),
92});
93
94GncSqlCustomerBackend::GncSqlCustomerBackend() :
95 GncSqlObjectBackend(TABLE_VERSION, GNC_ID_CUSTOMER,
96 TABLE_NAME, col_table) {}
97
98static GncCustomer*
99load_single_customer (GncSqlBackend* sql_be, GncSqlRow& row)
100{
101 const GncGUID* guid;
102 GncCustomer* pCustomer;
103
104 g_return_val_if_fail (sql_be != NULL, NULL);
105
106 guid = gnc_sql_load_guid (sql_be, row);
107 pCustomer = gncCustomerLookup (sql_be->book(), guid);
108 if (pCustomer == NULL)
109 {
110 pCustomer = gncCustomerCreate (sql_be->book());
111 }
112 gnc_sql_load_object (sql_be, row, GNC_ID_CUSTOMER, pCustomer, col_table);
113 qof_instance_mark_clean (QOF_INSTANCE (pCustomer));
114
115 return pCustomer;
116}
117
118/* Because gncCustomerLookup has the arguments backwards: */
119static inline GncCustomer*
120gnc_customer_lookup (const GncGUID *guid, const QofBook *book)
121{
122 QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_CUSTOMER, GncCustomer);
123}
124
125void
127{
128 g_return_if_fail (sql_be != NULL);
129
130 std::string sql("SELECT * FROM " TABLE_NAME);
131 auto stmt = sql_be->create_statement_from_sql(sql);
132 auto result = sql_be->execute_select_statement(stmt);
133
134 for (auto row : *result)
135 load_single_customer (sql_be, row);
136
137 std::string pkey(col_table[0]->name());
138 sql = "SELECT DISTINCT ";
139 sql += pkey + " FROM " TABLE_NAME;
140 gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
141 (BookLookupFn)gnc_customer_lookup);
142}
143
144/* ================================================================= */
145void
147{
148 gint version;
149
150 g_return_if_fail (sql_be != NULL);
151
152 version = sql_be->get_table_version( TABLE_NAME);
153 if (version == 0)
154 {
155 sql_be->create_table(TABLE_NAME, TABLE_VERSION, col_table);
156 }
157 else if (version < m_version)
158 {
159 /* Upgrade 64 bit int handling */
160 sql_be->upgrade_table(TABLE_NAME, col_table);
161 sql_be->set_table_version (TABLE_NAME, TABLE_VERSION);
162
163 PINFO ("Customers table upgraded from version 1 to version %d\n",
164 TABLE_VERSION);
165 }
166}
167
168/* ================================================================= */
169static gboolean
170customer_should_be_saved (GncCustomer* customer)
171{
172 const char* id;
173
174 g_return_val_if_fail (customer != NULL, FALSE);
175
176 /* Make sure this is a valid customer before we save it -- should have an ID */
177 id = gncCustomerGetID (customer);
178 if (id == NULL || *id == '\0')
179 {
180 return FALSE;
181 }
182
183 return TRUE;
184}
185
186static void
187write_single_customer (QofInstance* term_p, gpointer data_p)
188{
189 auto data = reinterpret_cast<write_objects_t*>(data_p);
190
191 g_return_if_fail (term_p != NULL);
192 g_return_if_fail (GNC_IS_CUSTOMER (term_p));
193 g_return_if_fail (data_p != NULL);
194
195 if (customer_should_be_saved (GNC_CUSTOMER (term_p)))
196 {
197 data->commit (term_p);
198 }
199}
200
201bool
203{
204 write_objects_t data;
205
206 g_return_val_if_fail (sql_be != NULL, FALSE);
207
208 data.be = sql_be;
209 data.is_ok = TRUE;
210 data.obe = this;
211 qof_object_foreach (GNC_ID_CUSTOMER, sql_be->book(), write_single_customer,
212 (gpointer)&data);
213 return data.is_ok;
214}
215
216/* ========================== END OF FILE ===================== */
Main SQL backend structure.
uint_t get_table_version(const std::string &table_name) const noexcept
Returns the version number for a DB table.
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
GncSqlResultPtr execute_select_statement(const GncSqlStatementPtr &stmt) const noexcept
Executes an SQL SELECT statement and returns the result rows.
void upgrade_table(const std::string &table_name, const EntryVec &col_table) noexcept
Upgrades a table to a new structure.
bool set_table_version(const std::string &table_name, uint_t version) noexcept
Registers the version for a table.
void create_tables(GncSqlBackend *) override
Conditionally create or update a database table from m_col_table.
void load_all(GncSqlBackend *) override
Load all objects of m_type in the database into memory.
bool write(GncSqlBackend *) override
Write all objects of m_type_name to the database.
Encapsulates per-class table schema with functions to load, create a table, commit a changed front-en...
Row of SQL Query results.
load and save accounts data to SQL
load and save customer data to SQL
load and save accounts data to SQL
load and save tax table data to SQL
#define QOF_BOOK_RETURN_ENTITY(book, guid, e_type, c_type)
Encapsulates all the information about a dataset manipulated by QOF.
Definition qofbook.h:101
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Definition qofclass.h:123
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
Definition qofclass.h:130
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
Invoke the callback 'cb' on every instance ov a particular object type.
credit, discount and shipaddr are unique to GncCustomer id, name, notes, terms, addr,...
The type used to store guids in C.
Definition guid.h:75
QofBook reference.
Definition qofbook-p.hpp:47
Data-passing struct for callbacks to qof_object_foreach() used in GncSqlObjectBackend::write().