GnuCash  5.6-150-g038405b370+
gnc-employee-sql.cpp
1 /********************************************************************\
2  * gnc-employee-sql.c -- employee 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 
30 #include <glib.h>
31 
32 #include <config.h>
33 
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "gnc-commodity.h"
38 #include "gncEmployeeP.h"
39 
40 #include "gnc-sql-connection.hpp"
41 #include "gnc-sql-backend.hpp"
42 #include "gnc-sql-object-backend.hpp"
43 #include "gnc-sql-column-table-entry.hpp"
44 #include "gnc-slots-sql.h"
45 #include "gnc-commodity-sql.h"
46 #include "gnc-employee-sql.h"
47 
48 #define _GNC_MOD_NAME GNC_ID_EMPLOYEE
49 
50 static QofLogModule log_module = G_LOG_DOMAIN;
51 
52 #define MAX_USERNAME_LEN 2048
53 #define MAX_ID_LEN 2048
54 #define MAX_LANGUAGE_LEN 2048
55 #define MAX_ACL_LEN 2048
56 
57 #define TABLE_NAME "employees"
58 #define TABLE_VERSION 2
59 
60 static EntryVec col_table
61 ({
62  gnc_sql_make_table_entry<CT_GUID>("guid", 0, COL_NNUL | COL_PKEY, "guid"),
63  gnc_sql_make_table_entry<CT_STRING>(
64  "username", MAX_USERNAME_LEN, COL_NNUL, "username"),
65  gnc_sql_make_table_entry<CT_STRING>("id", MAX_ID_LEN, COL_NNUL, "id"),
66  gnc_sql_make_table_entry<CT_STRING>(
67  "language", MAX_LANGUAGE_LEN, COL_NNUL, "language"),
68  gnc_sql_make_table_entry<CT_STRING>("acl", MAX_ACL_LEN, COL_NNUL, "acl"),
69  gnc_sql_make_table_entry<CT_BOOLEAN>("active", 0, COL_NNUL, "active"),
70  gnc_sql_make_table_entry<CT_COMMODITYREF>(
71  "currency", 0, COL_NNUL, "currency"),
72  gnc_sql_make_table_entry<CT_ACCOUNTREF>(
73  "ccard_guid", 0, 0, "credit-card-account"),
74  gnc_sql_make_table_entry<CT_NUMERIC>("workday", 0, COL_NNUL, "workday"),
75  gnc_sql_make_table_entry<CT_NUMERIC>("rate", 0, COL_NNUL, "rate"),
76  gnc_sql_make_table_entry<CT_ADDRESS>("addr", 0, 0, "address"),
77 });
78 
79 GncSqlEmployeeBackend::GncSqlEmployeeBackend() :
80  GncSqlObjectBackend(TABLE_VERSION, GNC_ID_EMPLOYEE,
81  TABLE_NAME, col_table) {}
82 
83 static GncEmployee*
84 load_single_employee (GncSqlBackend* sql_be, GncSqlRow& row)
85 {
86  const GncGUID* guid;
87  GncEmployee* pEmployee;
88 
89  g_return_val_if_fail (sql_be != NULL, NULL);
90 
91  guid = gnc_sql_load_guid (sql_be, row);
92  pEmployee = gncEmployeeLookup (sql_be->book(), guid);
93  if (pEmployee == NULL)
94  {
95  pEmployee = gncEmployeeCreate (sql_be->book());
96  }
97  gnc_sql_load_object (sql_be, row, GNC_ID_EMPLOYEE, pEmployee, col_table);
98  qof_instance_mark_clean (QOF_INSTANCE (pEmployee));
99 
100  return pEmployee;
101 }
102 /* Because gncCustomerLookup has the arguments backwards: */
103 static inline GncEmployee*
104 gnc_employee_lookup (const GncGUID *guid, const QofBook *book)
105 {
106  QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_EMPLOYEE, GncEmployee);
107 }
108 
109 void
111 {
112  g_return_if_fail (sql_be != NULL);
113 
114  std::string sql("SELECT * FROM " TABLE_NAME);
115  auto stmt = sql_be->create_statement_from_sql(sql);
116  auto result = sql_be->execute_select_statement(stmt);
117 
118  for (auto row : *result)
119  load_single_employee (sql_be, row);
120 
121  std::string pkey(col_table[0]->name());
122  sql = "SELECT DISTINCT ";
123  sql += pkey + " FROM " TABLE_NAME;
125  (BookLookupFn)gnc_employee_lookup);
126 }
127 
128 
129 /* ================================================================= */
130 void
132 {
133  gint version;
134 
135  g_return_if_fail (sql_be != NULL);
136 
137  version = sql_be->get_table_version( TABLE_NAME);
138  if (version == 0)
139  {
140  sql_be->create_table(TABLE_NAME, TABLE_VERSION, col_table);
141  }
142  else if (version < m_version)
143  {
144  /* Upgrade 64 bit int handling */
145  sql_be->upgrade_table(TABLE_NAME, col_table);
146  sql_be->set_table_version (TABLE_NAME, TABLE_VERSION);
147 
148  PINFO ("Employees table upgraded from version 1 to version %d\n",
149  TABLE_VERSION);
150  }
151 }
152 
153 /* ================================================================= */
154 bool
156 {
157  GncEmployee* emp;
158  const GncGUID* guid;
159  E_DB_OPERATION op;
160  gboolean is_infant;
161  gboolean is_ok = TRUE;
162 
163  g_return_val_if_fail (inst != NULL, FALSE);
164  g_return_val_if_fail (GNC_IS_EMPLOYEE (inst), FALSE);
165  g_return_val_if_fail (sql_be != NULL, FALSE);
166 
167  emp = GNC_EMPLOYEE (inst);
168 
169  is_infant = qof_instance_get_infant (inst);
170  if (qof_instance_get_destroying (inst))
171  {
172  op = OP_DB_DELETE;
173  }
174  else if (sql_be->pristine() || is_infant)
175  {
176  op = OP_DB_INSERT;
177  }
178  else
179  {
180  op = OP_DB_UPDATE;
181  }
182  if (op != OP_DB_DELETE)
183  {
184  // Ensure the commodity is in the db
185  is_ok = sql_be->save_commodity(gncEmployeeGetCurrency (emp));
186  }
187 
188  if (is_ok)
189  {
190  is_ok = sql_be->do_db_operation(op, TABLE_NAME, GNC_ID_EMPLOYEE, emp,
191  col_table);
192  }
193 
194  if (is_ok)
195  {
196  // Now, commit or delete 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 
211 /* ================================================================= */
212 static gboolean
213 employee_should_be_saved (GncEmployee* employee)
214 {
215  const char* id;
216 
217  g_return_val_if_fail (employee != NULL, FALSE);
218 
219  /* make sure this is a valid employee before we save it -- should have an ID */
220  id = gncEmployeeGetID (employee);
221  if (id == NULL || *id == '\0')
222  {
223  return FALSE;
224  }
225 
226  return TRUE;
227 }
228 
229 static void
230 write_single_employee (QofInstance* term_p, gpointer data_p)
231 {
232  write_objects_t* s = (write_objects_t*)data_p;
233 
234  g_return_if_fail (term_p != NULL);
235  g_return_if_fail (GNC_IS_EMPLOYEE (term_p));
236  g_return_if_fail (data_p != NULL);
237 
238  if (s->is_ok && employee_should_be_saved (GNC_EMPLOYEE (term_p)))
239  {
240  s->is_ok = s->obe->commit (s->be, term_p);
241  }
242 }
243 
244 bool
246 {
247  write_objects_t data;
248 
249  g_return_val_if_fail (sql_be != NULL, FALSE);
250 
251  data.be = sql_be;
252  data.is_ok = TRUE;
253  data.obe = this;
254  qof_object_foreach (GNC_ID_EMPLOYEE, sql_be->book(), write_single_employee, &data);
255 
256  return data.is_ok;
257 }
258 
259 
260 /* ========================== END OF FILE ===================== */
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.
bool create_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Creates a table in the database.
void create_tables(GncSqlBackend *) override
Conditionally create or update a database table from m_col_table.
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.
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
bool write(GncSqlBackend *) override
Write all objects of m_type_name to the database.
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
load and save data to SQL
load and save accounts data to SQL
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
gboolean gnc_sql_slots_save(GncSqlBackend *sql_be, const GncGUID *guid, gboolean is_infant, QofInstance *inst)
gnc_sql_slots_save - Saves slots for an object to the db.
#define QOF_BOOK_RETURN_ENTITY(book, guid, e_type, c_type)
Encapsulates all the information about a dataset manipulated by QOF.
Definition: qofbook.h:186
bool commit(GncSqlBackend *, QofInstance *) override
UPDATE/INSERT a single instance of m_type_name into the database.
bool save_commodity(gnc_commodity *comm) noexcept
Ensure that a commodity referenced in another object is in fact saved in the database.
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 employee data to SQL
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
Invoke the callback &#39;cb&#39; on every instance ov a particular object type.
Definition: qofobject.cpp:185
Encapsulates per-class table schema with functions to load, create a table, commit a changed front-en...
void load_all(GncSqlBackend *) override
Load all objects of m_type in the database into memory.
Data-passing struct for callbacks to qof_object_foreach() used in GncSqlObjectBackend::write().
gboolean gnc_sql_slots_delete(GncSqlBackend *sql_be, const GncGUID *guid)
gnc_sql_slots_delete - Deletes slots for an object from the db.
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.
Commodity handling public routines.
Main SQL backend structure.