GnuCash  5.6-150-g038405b370+
gnc-lots-sql.cpp
1 /********************************************************************
2  * gnc-lots-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 \********************************************************************/
29 #include <guid.hpp>
30 #include <config.h>
31 
32 #include <glib.h>
33 
34 #include "qof.h"
35 #include "Account.h"
36 #include "gnc-lot.h"
37 
38 #if defined( S_SPLINT_S )
39 #include "splint-defs.h"
40 #endif
41 
42 #include "gnc-sql-connection.hpp"
43 #include "gnc-sql-backend.hpp"
44 #include "gnc-sql-object-backend.hpp"
45 #include "gnc-sql-column-table-entry.hpp"
46 #include "gnc-slots-sql.h"
47 
48 #include "gnc-lots-sql.h"
49 
50 static QofLogModule log_module = G_LOG_DOMAIN;
51 
52 #define TABLE_NAME "lots"
53 #define TABLE_VERSION 2
54 
55 static gpointer get_lot_account (gpointer pObject);
56 static void set_lot_account (gpointer pObject, gpointer pValue);
57 
58 static const EntryVec col_table
59 ({
60  gnc_sql_make_table_entry<CT_GUID>("guid", 0, COL_NNUL | COL_PKEY, "guid"),
61  gnc_sql_make_table_entry<CT_ACCOUNTREF>("account_guid", 0, 0,
62  (QofAccessFunc)get_lot_account,
63  set_lot_account),
64  gnc_sql_make_table_entry<CT_BOOLEAN>("is_closed", 0, COL_NNUL, "is-closed")
65 });
66 
67 GncSqlLotsBackend::GncSqlLotsBackend() :
68  GncSqlObjectBackend(TABLE_VERSION, GNC_ID_LOT,
69  TABLE_NAME, col_table) {}
70 
71 /* ================================================================= */
72 static gpointer
73 get_lot_account (gpointer pObject)
74 {
75  const GNCLot* lot;
76  Account* pAccount;
77 
78  g_return_val_if_fail (pObject != NULL, NULL);
79  g_return_val_if_fail (GNC_IS_LOT (pObject), NULL);
80 
81  lot = GNC_LOT (pObject);
82  pAccount = gnc_lot_get_account (lot);
83  return pAccount;
84 }
85 
86 static void
87 set_lot_account (gpointer pObject, gpointer pValue)
88 {
89  GNCLot* lot;
90  Account* pAccount;
91 
92  g_return_if_fail (pObject != NULL && GNC_IS_LOT (pObject));
93  g_return_if_fail (pValue == NULL || GNC_IS_ACCOUNT (pValue));
94 
95  lot = GNC_LOT (pObject);
96  pAccount = GNC_ACCOUNT (pValue);
97  if (pAccount != NULL)
98  {
99  xaccAccountInsertLot (pAccount, lot);
100  }
101 }
102 
103 static GNCLot*
104 load_single_lot (GncSqlBackend* sql_be, GncSqlRow& row)
105 {
106  GNCLot* lot;
107 
108  g_return_val_if_fail (sql_be != NULL, NULL);
109 
110  lot = gnc_lot_new (sql_be->book());
111 
112  gnc_lot_begin_edit (lot);
113  gnc_sql_load_object (sql_be, row, GNC_ID_LOT, lot, col_table);
114  gnc_lot_commit_edit (lot);
115 
116  return lot;
117 }
118 
119 void
121 {
122  g_return_if_fail (sql_be != NULL);
123 
124  std::stringstream sql;
125  sql << "SELECT * FROM " << TABLE_NAME;
126  auto stmt = sql_be->create_statement_from_sql(sql.str());
127  if (stmt != nullptr)
128  {
129  auto result = sql_be->execute_select_statement(stmt);
130  if (result->begin () == nullptr)
131  return;
132  for (auto row : *result)
133  load_single_lot (sql_be, row);
134 
135  auto sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s",
136  TABLE_NAME);
137  gnc_sql_slots_load_for_sql_subquery (sql_be, sql, (BookLookupFn)gnc_lot_lookup);
138  g_free (sql);
139  }
140 }
141 
142 /* ================================================================= */
143 void
145 {
146  gint version;
147 
148  g_return_if_fail (sql_be != NULL);
149 
150  version = sql_be->get_table_version( TABLE_NAME);
151  if (version == 0)
152  {
153  /* The table doesn't exist, so create it */
154  (void)sql_be->create_table(TABLE_NAME, TABLE_VERSION, col_table);
155  }
156  else if (version < m_version)
157  {
158  /* Version 1 -> 2 removes the 'NOT NULL' constraint on the account_guid
159  field.
160 
161  Create a temporary table, copy the data from the old table, delete the
162  old table, then rename the new one. */
163 
164  sql_be->upgrade_table(TABLE_NAME, col_table);
165  sql_be->set_table_version (TABLE_NAME, TABLE_VERSION);
166 
167  PINFO ("Lots table upgraded from version 1 to version %d\n", TABLE_VERSION);
168  }
169 }
170 
171 static void
172 do_save_lot (QofInstance* inst, gpointer data)
173 {
174  auto s = reinterpret_cast<write_objects_t*>(data);
175 
176  if (s->is_ok)
177  {
178  s->commit (inst);
179  }
180 }
181 
182 bool
184 {
185  g_return_val_if_fail (sql_be != NULL, FALSE);
186  write_objects_t data{sql_be, true, this};
187 
188  qof_collection_foreach (qof_book_get_collection (sql_be->book(), GNC_ID_LOT),
189  (QofInstanceForeachCB)do_save_lot, &data);
190  return data.is_ok;
191 }
192 
193 /* ================================================================= */
194 template<> void
196  GncSqlRow& row,
197  QofIdTypeConst obj_name,
198  gpointer pObject) const noexcept
199 {
200  load_from_guid_ref(row, obj_name, pObject,
201  [sql_be](GncGUID* g){
202  return gnc_lot_lookup(g, sql_be->book());
203  });
204 }
205 
206 template<> void
208 {
209  add_objectref_guid_to_table(vec);
210 }
211 
212 template<> void
214  const gpointer pObject,
215  PairVec& vec) const noexcept
216 {
217  add_objectref_guid_to_query(obj_name, pObject, vec);
218 }
219 
220 /* ========================== END OF FILE ===================== */
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
bool set_table_version(const std::string &table_name, uint_t version) noexcept
Registers the version for a table.
GncSqlResultPtr execute_select_statement(const GncSqlStatementPtr &stmt) const noexcept
Executes an SQL SELECT statement and returns the result rows.
void gnc_sql_slots_load_for_sql_subquery(GncSqlBackend *sql_be, const std::string subquery, BookLookupFn lookup_fn)
gnc_sql_slots_load_for_sql_subquery - Loads slots for all objects whose guid is supplied by a subquer...
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
Definition: qofid.h:82
load and save accounts data to SQL
STRUCTS.
void(* QofInstanceForeachCB)(QofInstance *, gpointer user_data)
Callback type for qof_collection_foreach.
Definition: qofid.h:146
void add_to_query(QofIdTypeConst obj_name, void *pObject, PairVec &vec) const noexcept override
Add a pair of the table column heading and object&#39;s value&#39;s string representation to a PairVec; used ...
void xaccAccountInsertLot(Account *acc, GNCLot *lot)
The xaccAccountInsertLot() method will register the indicated lot with this account.
Definition: Account.cpp:2126
void load_all(GncSqlBackend *) override
Load all objects of m_type in the database into memory.
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.
Account handling public routines.
Row of SQL Query results.
void upgrade_table(const std::string &table_name, const EntryVec &col_table) noexcept
Upgrades a table to a new structure.
load and save data to SQL
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Definition: qofclass.h:178
Encapsulates per-class table schema with functions to load, create a table, commit a changed front-en...
bool write(GncSqlBackend *) override
Write all objects of m_type_name to the database.
Data-passing struct for callbacks to qof_object_foreach() used in GncSqlObjectBackend::write().
void create_tables(GncSqlBackend *) override
Conditionally create or update a database table from m_col_table.
void add_to_table(ColVec &vec) const noexcept override
Add a GncSqlColumnInfo structure for the column type to a ColVec.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
Definition: qofbook.cpp:521
Account * gnc_lot_get_account(const GNCLot *lot)
Returns the account with which this lot is associated.
Definition: gnc-lot.cpp:377
The type used to store guids in C.
Definition: guid.h:75
uint_t get_table_version(const std::string &table_name) const noexcept
Returns the version number for a DB table.
Main SQL backend structure.