GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-commodity-sql.cpp
1/********************************************************************
2 * gnc-commodity-sql.c: load and save data to SQL *
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\********************************************************************/
28#include <guid.hpp>
29#include <config.h>
30
31#include <glib.h>
32
33#include "qof.h"
34#include "gnc-commodity.h"
35
36#include "gnc-sql-connection.hpp"
37#include "gnc-sql-backend.hpp"
38#include "gnc-sql-object-backend.hpp"
39#include "gnc-sql-column-table-entry.hpp"
40#include "gnc-commodity-sql.h"
41#include "gnc-slots-sql.h"
42
43#if defined( S_SPLINT_S )
44#include "splint-defs.h"
45#endif
46
47[[maybe_unused]] static QofLogModule log_module = G_LOG_DOMAIN;
48
49static gpointer get_quote_source_name (gpointer pObject);
50static void set_quote_source_name (gpointer pObject, gpointer pValue);
51
52#define COMMODITIES_TABLE "commodities"
53#define TABLE_VERSION 1
54
55#define COMMODITY_MAX_NAMESPACE_LEN 2048
56#define COMMODITY_MAX_MNEMONIC_LEN 2048
57#define COMMODITY_MAX_FULLNAME_LEN 2048
58#define COMMODITY_MAX_CUSIP_LEN 2048
59#define COMMODITY_MAX_QUOTESOURCE_LEN 2048
60#define COMMODITY_MAX_QUOTE_TZ_LEN 2048
61
62static const EntryVec col_table
63{
64 gnc_sql_make_table_entry<CT_GUID>(
65 "guid", 0, COL_NNUL | COL_PKEY | COL_UNIQUE, "guid"),
66 gnc_sql_make_table_entry<CT_STRING>("namespace",
67 COMMODITY_MAX_NAMESPACE_LEN, COL_NNUL,
70 gnc_sql_make_table_entry<CT_STRING>(
71 "mnemonic", COMMODITY_MAX_MNEMONIC_LEN, COL_NNUL, "mnemonic"),
72 gnc_sql_make_table_entry<CT_STRING>(
73 "fullname", COMMODITY_MAX_FULLNAME_LEN, 0, "fullname"),
74 gnc_sql_make_table_entry<CT_STRING>(
75 "cusip", COMMODITY_MAX_CUSIP_LEN, 0, "cusip"),
76 gnc_sql_make_table_entry<CT_INT>("fraction", 0, COL_NNUL, "fraction"),
77 gnc_sql_make_table_entry<CT_BOOLEAN>(
78 "quote_flag", 0, COL_NNUL, "quote_flag"),
79 gnc_sql_make_table_entry<CT_STRING>("quote_source",
80 COMMODITY_MAX_QUOTESOURCE_LEN, 0,
81 (QofAccessFunc)get_quote_source_name,
82 set_quote_source_name),
83 gnc_sql_make_table_entry<CT_STRING>(
84 "quote_tz", COMMODITY_MAX_QUOTE_TZ_LEN, 0, "quote-tz"),
85};
86
87GncSqlCommodityBackend::GncSqlCommodityBackend() :
88 GncSqlObjectBackend(TABLE_VERSION, GNC_ID_COMMODITY,
89 COMMODITIES_TABLE, col_table) {}
90/* ================================================================= */
91
92static gpointer
93get_quote_source_name (gpointer pObject)
94{
95 const gnc_commodity* pCommodity;
96
97 g_return_val_if_fail (pObject != NULL, NULL);
98 g_return_val_if_fail (GNC_IS_COMMODITY (pObject), NULL);
99
100 pCommodity = GNC_COMMODITY (pObject);
101 return (gpointer)gnc_quote_source_get_internal_name (
102 gnc_commodity_get_quote_source (pCommodity));
103}
104
105static void
106set_quote_source_name (gpointer pObject, gpointer pValue)
107{
108 gnc_commodity* pCommodity;
109 const gchar* quote_source_name = (const gchar*)pValue;
110 gnc_quote_source* quote_source;
111
112 g_return_if_fail (pObject != NULL);
113 g_return_if_fail (GNC_IS_COMMODITY (pObject));
114
115 if (pValue == NULL) return;
116
117 pCommodity = GNC_COMMODITY (pObject);
118 quote_source = gnc_quote_source_lookup_by_internal (quote_source_name);
119 gnc_commodity_set_quote_source (pCommodity, quote_source);
120}
121
122static gnc_commodity*
123load_single_commodity (GncSqlBackend* sql_be, GncSqlRow& row)
124{
125 QofBook* pBook = sql_be->book();
126 gnc_commodity* pCommodity;
127
128 pCommodity = gnc_commodity_new (pBook, NULL, NULL, NULL, NULL, 100);
129 gnc_commodity_begin_edit (pCommodity);
130 gnc_sql_load_object (sql_be, row, GNC_ID_COMMODITY, pCommodity, col_table);
131 gnc_commodity_commit_edit (pCommodity);
132
133 return pCommodity;
134}
135
136void
138{
139 gnc_commodity_table* pTable;
140
141 pTable = gnc_commodity_table_get_table (sql_be->book());
142 std::string sql("SELECT * FROM " COMMODITIES_TABLE);
143 auto stmt = sql_be->create_statement_from_sql(sql);
144 auto result = sql_be->execute_select_statement(stmt);
145
146 for (auto row : *result)
147 {
148 auto pCommodity = load_single_commodity (sql_be, row);
149
150 if (pCommodity != NULL)
151 {
152 GncGUID guid;
153
154 guid = *qof_instance_get_guid (QOF_INSTANCE (pCommodity));
155 pCommodity = gnc_commodity_table_insert (pTable, pCommodity);
156 if (qof_instance_is_dirty (QOF_INSTANCE (pCommodity)))
157 sql_be->commodity_for_postload_processing(pCommodity);
158 qof_instance_set_guid (QOF_INSTANCE (pCommodity), &guid);
159 }
160
161 }
162 std::string pkey(col_table[0]->name());
163 sql = "SELECT DISTINCT ";
164 sql += pkey + " FROM " COMMODITIES_TABLE;
165 gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
166 (BookLookupFn)gnc_commodity_find_commodity_by_guid);
167}
168/* ================================================================= */
169static gboolean
170do_commit_commodity (GncSqlBackend* sql_be, QofInstance* inst,
171 gboolean force_insert)
172{
173 const GncGUID* guid;
174 gboolean is_infant;
175 E_DB_OPERATION op;
176 gboolean is_ok;
177
178 is_infant = qof_instance_get_infant (inst);
180 {
181 op = OP_DB_DELETE;
182 }
183 else if (sql_be->pristine() || is_infant || force_insert)
184 {
185 op = OP_DB_INSERT;
186 }
187 else
188 {
189 op = OP_DB_UPDATE;
190 }
191 is_ok = sql_be->do_db_operation(op, COMMODITIES_TABLE, GNC_ID_COMMODITY,
192 inst, col_table);
193
194 if (is_ok)
195 {
196 // Now, commit any slots
197 guid = qof_instance_get_guid (inst);
198 if (!qof_instance_get_destroying (inst))
199 {
200 is_ok = gnc_sql_slots_save (sql_be, guid, is_infant, inst);
201 }
202 else
203 {
204 is_ok = gnc_sql_slots_delete (sql_be, guid);
205 }
206 }
207
208 return is_ok;
209}
210
211bool
213{
214 g_return_val_if_fail (sql_be != NULL, FALSE);
215 g_return_val_if_fail (inst != NULL, FALSE);
216 g_return_val_if_fail (GNC_IS_COMMODITY (inst), FALSE);
217 auto in_be = instance_in_db(sql_be, inst);
218 return do_commit_commodity (sql_be, inst, !in_be);
219}
220
221/* ----------------------------------------------------------------- */
222template<> void
224 GncSqlRow& row,
225 QofIdTypeConst obj_name,
226 gpointer pObject) const noexcept
227{
228 load_from_guid_ref(row, obj_name, pObject,
229 [sql_be](GncGUID* g){
230 return gnc_commodity_find_commodity_by_guid(g, sql_be->book());
231 });
232}
233
234template<> void
236{
237 add_objectref_guid_to_table(vec);
238}
239
240template<> void
242 const gpointer pObject,
243 PairVec& vec) const noexcept
244{
245 add_objectref_guid_to_query(obj_name, pObject, vec);
246}
247
248/* ========================== END OF FILE ===================== */
Main SQL backend structure.
void commodity_for_postload_processing(gnc_commodity *)
Register a commodity to be committed after loading is complete.
GncSqlResultPtr execute_select_statement(const GncSqlStatementPtr &stmt) const noexcept
Executes an SQL SELECT statement and returns the result rows.
bool do_db_operation(E_DB_OPERATION op, const char *table_name, QofIdTypeConst obj_name, gpointer pObject, const EntryVec &table) const noexcept
Performs an operation on the database.
void add_to_query(QofIdTypeConst obj_name, void *pObject, PairVec &vec) const noexcept override
Add a pair of the table column heading and object's value's string representation to a PairVec; used ...
void add_to_table(ColVec &vec) const noexcept override
Add a GncSqlColumnInfo structure for the column type to a ColVec.
void load(const GncSqlBackend *sql_be, GncSqlRow &row, QofIdTypeConst obj_name, void *pObject) const noexcept override
Load a value into an object from the database row.
void load_all(GncSqlBackend *) override
Load all objects of m_type in the database into memory.
bool commit(GncSqlBackend *, QofInstance *) override
UPDATE/INSERT a single instance of m_type_name into the database.
Encapsulates per-class table schema with functions to load, create a table, commit a changed front-en...
bool instance_in_db(const GncSqlBackend *sql_be, QofInstance *inst) const noexcept
Check the presence of an object in the backend's database.
Row of SQL Query results.
load and save data to SQL
Commodity handling public routines.
load and save accounts data to SQL
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
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
Set the namespace for the specified commodity.
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
const char * gnc_quote_source_get_internal_name(const gnc_quote_source *source)
Given a gnc_quote_source data structure, return the internal name of this quote source.
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
Create a new commodity.
void gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
Set the automatic price quote source for the specified commodity.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
Retrieve the automatic price quote source for the specified commodity.
gnc_quote_source * gnc_quote_source_lookup_by_internal(const char *name)
Given the internal (gnucash or F::Q) name of a quote source, find the data structure identified by th...
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table *table, gnc_commodity *comm)
Add a new commodity to the commodity table.
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
Definition qofid.h:82
#define qof_instance_is_dirty
Return value of is_dirty flag.
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
The type used to store guids in C.
Definition guid.h:75
QofBook reference.
Definition qofbook-p.hpp:47