34 #include "Recurrence.h" 37 #if defined( S_SPLINT_S ) 38 #include "splint-defs.h" 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" 49 #define BUDGET_TABLE "budgets" 50 #define TABLE_VERSION 1 51 #define AMOUNTS_TABLE "budget_amounts" 52 #define AMOUNTS_TABLE_VERSION 1 54 [[maybe_unused]]
static QofLogModule log_module =
G_LOG_DOMAIN;
56 #define BUDGET_MAX_NAME_LEN 2048 57 #define BUDGET_MAX_DESCRIPTION_LEN 2048 59 static const EntryVec col_table
61 gnc_sql_make_table_entry<CT_GUID>(
62 "guid", 0, COL_NNUL | COL_PKEY,
"guid"),
63 gnc_sql_make_table_entry<CT_STRING>(
64 "name", BUDGET_MAX_NAME_LEN, COL_NNUL,
"name"),
65 gnc_sql_make_table_entry<CT_STRING>(
66 "description", BUDGET_MAX_DESCRIPTION_LEN, 0,
"description"),
67 gnc_sql_make_table_entry<CT_INT>(
68 "num_periods", 0, COL_NNUL,
"num_periods"),
72 static void set_budget (gpointer pObj, gpointer val);
74 static void set_account (gpointer pObj, gpointer val);
75 static gint get_period_num (gpointer pObj);
76 static void set_period_num (gpointer pObj, gpointer val);
77 static gnc_numeric get_amount (gpointer pObj);
78 static void set_amount (gpointer pObj, gnc_numeric value);
80 GncSqlBudgetBackend::GncSqlBudgetBackend() :
82 BUDGET_TABLE, col_table) {}
91 static const EntryVec budget_amounts_col_table
93 gnc_sql_make_table_entry<CT_INT>(
94 "id", 0, COL_NNUL | COL_PKEY | COL_AUTOINC),
95 gnc_sql_make_table_entry<CT_BUDGETREF>(
"budget_guid", 0, COL_NNUL,
98 gnc_sql_make_table_entry<CT_ACCOUNTREF>(
"account_guid", 0, COL_NNUL,
101 gnc_sql_make_table_entry<CT_INT>(
"period_num", 0, COL_NNUL,
104 gnc_sql_make_table_entry<CT_NUMERIC>(
"amount", 0, COL_NNUL,
111 get_budget (gpointer pObj)
115 g_return_val_if_fail (pObj != NULL, NULL);
117 return QOF_INSTANCE (info->budget);
121 set_budget (gpointer pObj, gpointer val)
126 get_account (gpointer pObj)
130 g_return_val_if_fail (pObj != NULL, NULL);
132 return QOF_INSTANCE (info->account);
136 set_account (gpointer pObj, gpointer val)
140 g_return_if_fail (pObj != NULL);
141 g_return_if_fail (val != NULL);
142 g_return_if_fail (GNC_IS_ACCOUNT (val));
144 info->account = GNC_ACCOUNT (val);
148 get_period_num (gpointer pObj)
152 g_return_val_if_fail (pObj != NULL, 0);
154 return info->period_num;
158 set_period_num (gpointer pObj, gpointer val)
162 g_return_if_fail (pObj != NULL);
164 info->period_num = GPOINTER_TO_UINT (val);
168 get_amount (gpointer pObj)
172 g_return_val_if_fail (pObj != NULL, gnc_numeric_zero ());
174 return gnc_budget_get_account_period_value (info->budget, info->account,
179 set_amount (gpointer pObj, gnc_numeric value)
183 g_return_if_fail (pObj != NULL);
185 gnc_budget_set_account_period_value (info->budget, info->account,
186 info->period_num, value);
197 load_budget_amounts (
GncSqlBackend* sql_be, GncBudget* budget)
201 g_return_if_fail (sql_be != NULL);
202 g_return_if_fail (budget != NULL);
206 auto sql = g_strdup_printf (
"SELECT * FROM %s WHERE budget_guid='%s'",
207 AMOUNTS_TABLE, guid_buf);
208 auto stmt = sql_be->create_statement_from_sql(sql);
215 for (
auto row : *result)
216 gnc_sql_load_object (sql_be, row, NULL, &info, budget_amounts_col_table);
227 delete_budget_amounts (
GncSqlBackend* sql_be, GncBudget* budget)
231 g_return_val_if_fail (sql_be != NULL, FALSE);
232 g_return_val_if_fail (budget != NULL, FALSE);
236 std::stringstream sql;
237 sql <<
"DELETE FROM " << AMOUNTS_TABLE <<
" WHERE budget_guid='"<<
239 auto stmt = sql_be->create_statement_from_sql(sql.str());
240 sql_be->execute_nonselect_statement(stmt);
252 save_budget_amounts (
GncSqlBackend* sql_be, GncBudget* budget)
258 gboolean is_ok = TRUE;
260 g_return_val_if_fail (sql_be != NULL, FALSE);
261 g_return_val_if_fail (budget != NULL, FALSE);
264 delete_budget_amounts (sql_be, budget);
266 info.budget = budget;
267 num_periods = gnc_budget_get_num_periods (budget);
270 for (node = descendants; node != NULL && is_ok; node = g_list_next (node))
274 info.account = GNC_ACCOUNT (node->data);
275 for (i = 0; i < num_periods && is_ok; i++)
277 if (gnc_budget_is_account_period_value_set (budget, info.account, i))
282 budget_amounts_col_table);
286 g_list_free (descendants);
295 GncBudget* pBudget = NULL;
298 g_return_val_if_fail (sql_be != NULL, NULL);
300 guid = gnc_sql_load_guid (sql_be, row);
303 pBudget = gnc_budget_lookup (guid, sql_be->book());
310 gnc_budget_begin_edit (pBudget);
311 gnc_sql_load_object (sql_be, row, GNC_ID_BUDGET, pBudget, col_table);
312 load_budget_amounts (sql_be, pBudget);
313 r = gnc_sql_recurrence_load (sql_be, gnc_budget_get_guid (pBudget));
316 gnc_budget_set_recurrence (pBudget, r);
319 gnc_budget_commit_edit (pBudget);
327 g_return_if_fail (sql_be != NULL);
329 std::string sql(
"SELECT * FROM " BUDGET_TABLE);
330 auto stmt = sql_be->create_statement_from_sql(sql);
332 for (
auto row : *result)
333 load_single_budget (sql_be, row);
335 std::string pkey(col_table[0]->name());
336 sql =
"SELECT DISTINCT ";
337 sql += pkey +
" FROM " BUDGET_TABLE;
339 (BookLookupFn)gnc_budget_lookup);
348 g_return_if_fail (sql_be != NULL);
353 (void)sql_be->
create_table(BUDGET_TABLE, TABLE_VERSION, col_table);
359 (void)sql_be->
create_table(AMOUNTS_TABLE, AMOUNTS_TABLE_VERSION,
360 budget_amounts_col_table);
368 GncBudget* pBudget = GNC_BUDGET (inst);
374 g_return_val_if_fail (sql_be != NULL, FALSE);
375 g_return_val_if_fail (inst != NULL, FALSE);
376 g_return_val_if_fail (GNC_IS_BUDGET (inst), FALSE);
378 is_infant = qof_instance_get_infant (inst);
383 else if (sql_be->pristine() || is_infant)
391 is_ok = sql_be->
do_db_operation(op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget,
400 is_ok = save_budget_amounts (sql_be, pBudget);
403 is_ok = gnc_sql_recurrence_save (sql_be, guid,
404 gnc_budget_get_recurrence (pBudget));
413 is_ok = delete_budget_amounts (sql_be, pBudget);
416 is_ok = gnc_sql_recurrence_delete (sql_be, guid);
435 s->is_ok = s->obe->commit (s->be, inst);
444 g_return_val_if_fail (sql_be != NULL, FALSE);
460 gpointer pObject)
const noexcept
462 load_from_guid_ref(row, obj_name, pObject,
464 return gnc_budget_lookup (g, sql_be->book());
471 add_objectref_guid_to_table(vec);
476 const gpointer pObject,
477 PairVec& vec)
const noexcept
479 add_objectref_guid_to_query(obj_name, pObject, vec);
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.
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.
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.
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
load and save accounts data to SQL
GncBudget * gnc_budget_new(QofBook *book)
Creates and initializes a Budget.
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
void(* QofInstanceForeachCB)(QofInstance *, gpointer user_data)
Callback type for qof_collection_foreach.
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.
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 create_tables(GncSqlBackend *) override
Conditionally create or update a database table from m_col_table.
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...
bool write(GncSqlBackend *) override
Write all objects of m_type_name to the database.
void load_all(GncSqlBackend *) override
Load all objects of m_type in the database into memory.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
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.
load and save accounts data to SQL
Row of SQL Query results.
#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...
GList * gnc_account_get_descendants(const Account *account)
This routine returns a flat list of all of the accounts that are descendants of the specified account...
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.
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.
load and save data to SQL
The type used to store guids in C.
bool commit(GncSqlBackend *sql_be, QofInstance *inst) override
UPDATE/INSERT a single instance of m_type_name into the database.
uint_t get_table_version(const std::string &table_name) const noexcept
Returns the version number for a DB table.
Main SQL backend structure.