34 #include "Recurrence.h" 36 #if defined( S_SPLINT_S ) 37 #include "splint-defs.h" 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" 46 G_GNUC_UNUSED
static QofLogModule log_module =
G_LOG_DOMAIN;
48 #define TABLE_NAME "recurrences" 49 #define TABLE_VERSION 2 51 #define BUDGET_MAX_RECURRENCE_PERIOD_TYPE_LEN 2048 52 #define BUDGET_MAX_RECURRENCE_WEEKEND_ADJUST_LEN 2048 61 static gpointer get_obj_guid (gpointer pObject);
62 static void set_obj_guid (
void);
63 static gint get_recurrence_mult (gpointer pObject);
64 static void set_recurrence_mult (gpointer pObject, gint value);
65 static gpointer get_recurrence_period_type (gpointer pObject);
66 static void set_recurrence_period_type (gpointer pObject, gpointer pValue);
67 static gpointer get_recurrence_weekend_adjust (gpointer pObject);
68 static void set_recurrence_weekend_adjust (gpointer pObject, gpointer pValue);
69 static gpointer get_recurrence_period_start (gpointer pObject);
70 static void set_recurrence_period_start (gpointer pObject, gpointer pValue);
72 static const EntryVec col_table
74 gnc_sql_make_table_entry<CT_INT>(
75 "id", 0, COL_PKEY | COL_NNUL | COL_AUTOINC),
76 gnc_sql_make_table_entry<CT_GUID>(
"obj_guid", 0, COL_NNUL,
78 gnc_sql_make_table_entry<CT_INT>(
79 "recurrence_mult", 0, COL_NNUL,
81 gnc_sql_make_table_entry<CT_STRING>(
82 "recurrence_period_type", BUDGET_MAX_RECURRENCE_PERIOD_TYPE_LEN,
84 (
QofAccessFunc)get_recurrence_period_type, set_recurrence_period_type),
85 gnc_sql_make_table_entry<CT_GDATE>(
86 "recurrence_period_start", 0, COL_NNUL,
88 set_recurrence_period_start),
89 gnc_sql_make_table_entry<CT_STRING>(
90 "recurrence_weekend_adjust", BUDGET_MAX_RECURRENCE_WEEKEND_ADJUST_LEN,
93 set_recurrence_weekend_adjust)
98 static const EntryVec guid_col_table
100 gnc_sql_make_table_entry<CT_GUID>(
"obj_guid", 0, 0,
106 static const EntryVec weekend_adjust_col_table
108 gnc_sql_make_table_entry<CT_STRING>(
109 "recurrence_weekend_adjust", BUDGET_MAX_RECURRENCE_WEEKEND_ADJUST_LEN, 0)
122 get_obj_guid (gpointer pObject)
126 g_return_val_if_fail (pObject != NULL, NULL);
128 return (gpointer)pInfo->guid;
138 get_recurrence_mult (gpointer pObject)
142 g_return_val_if_fail (pObject != NULL, 0);
143 g_return_val_if_fail (pInfo->pRecurrence != NULL, 0);
145 return (gint)pInfo->pRecurrence->mult;
149 set_recurrence_mult (gpointer pObject, gint value)
153 g_return_if_fail (pObject != NULL);
154 g_return_if_fail (pInfo->pRecurrence != NULL);
156 pInfo->pRecurrence->mult = (guint16)value;
160 get_recurrence_period_type (gpointer pObject)
164 g_return_val_if_fail (pObject != NULL, NULL);
165 g_return_val_if_fail (pInfo->pRecurrence != NULL, NULL);
167 return (gpointer)recurrencePeriodTypeToString (
168 recurrenceGetPeriodType (pInfo->pRecurrence));
172 set_recurrence_period_type (gpointer pObject, gpointer pValue)
176 g_return_if_fail (pObject != NULL);
177 g_return_if_fail (pInfo->pRecurrence != NULL);
178 g_return_if_fail (pValue != NULL);
180 pInfo->pRecurrence->ptype = recurrencePeriodTypeFromString ((gchar*)pValue);
184 get_recurrence_weekend_adjust (gpointer pObject)
188 g_return_val_if_fail (pObject != NULL, NULL);
189 g_return_val_if_fail (pInfo->pRecurrence != NULL, NULL);
191 return (gpointer)recurrenceWeekendAdjustToString (
192 recurrenceGetWeekendAdjust (pInfo->pRecurrence));
196 set_recurrence_weekend_adjust (gpointer pObject, gpointer pValue)
200 g_return_if_fail (pObject != NULL);
201 g_return_if_fail (pInfo->pRecurrence != NULL);
202 g_return_if_fail (pValue != NULL);
204 pInfo->pRecurrence->wadj = recurrenceWeekendAdjustFromString ((gchar*)pValue);
208 get_recurrence_period_start (gpointer pObject)
213 g_return_val_if_fail (pObject != NULL, NULL);
214 g_return_val_if_fail (pInfo->pRecurrence != NULL, NULL);
216 date = recurrenceGetDate (pInfo->pRecurrence);
217 return (gpointer)&date;
221 set_recurrence_period_start (gpointer pObject, gpointer pValue)
224 GDate* date = (GDate*)pValue;
226 g_return_if_fail (pObject != NULL);
227 g_return_if_fail (pInfo->pRecurrence != NULL);
228 g_return_if_fail (pValue != NULL);
230 pInfo->pRecurrence->start = *date;
241 g_return_val_if_fail (sql_be != NULL, FALSE);
242 g_return_val_if_fail (guid != NULL, FALSE);
243 g_return_val_if_fail (r != NULL, FALSE);
245 (void)gnc_sql_recurrence_delete (sql_be, guid);
247 recurrence_info.be = sql_be;
248 recurrence_info.guid = guid;
251 TABLE_NAME, &recurrence_info, col_table);
261 g_return_if_fail (sql_be != NULL);
262 g_return_if_fail (guid != NULL);
264 (void)gnc_sql_recurrence_delete (sql_be, guid);
266 recurrence_info.be = sql_be;
267 recurrence_info.guid = guid;
268 for (l = schedule; l != NULL; l = g_list_next (l))
270 recurrence_info.pRecurrence = (
Recurrence*)l->data;
272 TABLE_NAME, &recurrence_info, col_table);
281 g_return_val_if_fail (sql_be != NULL, FALSE);
282 g_return_val_if_fail (guid != NULL, FALSE);
284 recurrence_info.be = sql_be;
285 recurrence_info.guid = guid;
287 TABLE_NAME, &recurrence_info, guid_col_table);
295 g_return_if_fail (sql_be != NULL);
296 g_return_if_fail (r != NULL);
298 recurrence_info.be = sql_be;
299 recurrence_info.pRecurrence = r;
301 gnc_sql_load_object (sql_be, row, TABLE_NAME, &recurrence_info, col_table);
310 g_return_val_if_fail (sql_be != NULL, NULL);
311 g_return_val_if_fail (guid != NULL, NULL);
314 buf = g_strdup_printf (
"SELECT * FROM %s WHERE obj_guid='%s'", TABLE_NAME,
316 auto stmt = sql_be->create_statement_from_sql (buf);
327 g_return_val_if_fail (sql_be != NULL, NULL);
328 g_return_val_if_fail (guid != NULL, NULL);
330 auto result = gnc_sql_set_recurrences_from_db (sql_be, guid);
331 auto row = result->begin();
334 g_warning (
"No recurrences found");
338 g_assert (r != NULL);
339 load_recurrence (sql_be, *(result->begin()), r);
341 if (++row !=
nullptr)
342 g_warning (
"More than 1 recurrence found: first one used");
352 g_return_val_if_fail (sql_be != NULL, NULL);
353 g_return_val_if_fail (guid != NULL, NULL);
355 auto result = gnc_sql_set_recurrences_from_db (sql_be, guid);
356 for (
auto row : *result)
359 g_assert (pRecurrence != NULL);
360 load_recurrence (sql_be, row, pRecurrence);
361 list = g_list_append (list, pRecurrence);
373 weekend_adjust_col_table);
376 PERR (
"Unable to add recurrence_weekend_adjust column\n");
382 const gchar* weekend_adj_str = recurrenceWeekendAdjustToString (WEEKEND_ADJ_NONE);
383 std::stringstream sql;
384 sql <<
"UPDATE " << TABLE_NAME <<
" SET " <<
385 weekend_adjust_col_table[0]->name() <<
"='" <<
386 weekend_adj_str <<
"'";
387 auto stmt = sql_be->create_statement_from_sql(sql.str());
388 sql_be->execute_nonselect_statement(stmt);
401 g_return_if_fail (sql_be != NULL);
406 (void)sql_be->
create_table(TABLE_NAME, TABLE_VERSION, col_table);
408 else if (version < TABLE_VERSION)
413 if (version < m_version)
415 upgrade_recurrence_table_1_2 (sql_be);
418 PINFO (
"Recurrence table upgraded from version %d to version %d\n", version,
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 add_columns_to_table(const std::string &table_name, const EntryVec &col_table) const noexcept
Adds one or more columns to an existing table.
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.
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
#define PINFO(format, args...)
Print an informational note.
GncSqlRecurrenceBackend()
Recurrences are neither loadable nor committable.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
#define PERR(format, args...)
Log a serious error.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
load and save accounts data to SQL
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.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Encapsulates per-class table schema with functions to load, create a table, commit a changed front-en...
All type declarations for the whole Gnucash engine.
void create_tables(GncSqlBackend *) override
Conditionally create or update a database table from m_col_table.
Pure virtual class to iterate over a query result set.
The type used to store guids in C.
uint_t get_table_version(const std::string &table_name) const noexcept
Returns the version number for a DB table.
Main SQL backend structure.