38#if defined( S_SPLINT_S )
39#include "splint-defs.h"
46#include "gnc-sql-connection.hpp"
47#include "gnc-sql-backend.hpp"
48#include "gnc-sql-object-backend.hpp"
49#include "gnc-sql-column-table-entry.hpp"
55static QofLogModule log_module = G_LOG_DOMAIN;
57#define TABLE_NAME "accounts"
58#define TABLE_VERSION 1
60static gpointer get_parent (gpointer pObject);
61static void set_parent (gpointer pObject, gpointer pValue);
62static void set_parent_guid (gpointer pObject, gpointer pValue);
64#define ACCOUNT_MAX_NAME_LEN 2048
65#define ACCOUNT_MAX_TYPE_LEN 2048
66#define ACCOUNT_MAX_CODE_LEN 2048
67#define ACCOUNT_MAX_DESCRIPTION_LEN 2048
69using AccountVec = std::vector<Account*>;
71static const EntryVec col_table
73 gnc_sql_make_table_entry<CT_GUID>(
"guid", 0, COL_NNUL | COL_PKEY,
"guid" ),
74 gnc_sql_make_table_entry<CT_STRING>(
75 "name", ACCOUNT_MAX_NAME_LEN, COL_NNUL,
"name"),
76 gnc_sql_make_table_entry<CT_STRING>(
"account_type", ACCOUNT_MAX_TYPE_LEN,
77 COL_NNUL, ACCOUNT_TYPE_,
true),
78 gnc_sql_make_table_entry<CT_COMMODITYREF>(
79 "commodity_guid", 0, 0,
"commodity"),
80 gnc_sql_make_table_entry<CT_INT>(
81 "commodity_scu", 0, COL_NNUL,
"commodity-scu"),
82 gnc_sql_make_table_entry<CT_BOOLEAN>(
83 "non_std_scu", 0, COL_NNUL,
"non-std-scu"),
84 gnc_sql_make_table_entry<CT_GUID>(
"parent_guid", 0, 0,
87 gnc_sql_make_table_entry<CT_STRING>(
88 "code", ACCOUNT_MAX_CODE_LEN, 0,
"code"),
89 gnc_sql_make_table_entry<CT_STRING>(
90 "description", ACCOUNT_MAX_DESCRIPTION_LEN, 0,
"description"),
91 gnc_sql_make_table_entry<CT_BOOLEAN>(
"hidden", 0, 0,
"hidden"),
92 gnc_sql_make_table_entry<CT_BOOLEAN>(
"placeholder", 0, 0,
"placeholder"),
94static EntryVec parent_col_table
96 gnc_sql_make_table_entry<CT_GUID>(
97 "parent_guid", 0, 0,
nullptr, (
QofSetterFunc)set_parent_guid),
100GncSqlAccountBackend::GncSqlAccountBackend() :
102 TABLE_NAME, col_table) {}
111using ParentGuidVec = std::vector<ParentGuidPtr>;
116get_parent (gpointer pObject)
122 g_return_val_if_fail (pObject != NULL, NULL);
123 g_return_val_if_fail (GNC_IS_ACCOUNT (pObject), NULL);
125 pAccount = GNC_ACCOUNT (pObject);
136 return (gpointer)parent_guid;
140set_parent (gpointer pObject, gpointer pValue)
147 g_return_if_fail (pObject != NULL);
148 g_return_if_fail (GNC_IS_ACCOUNT (pObject));
150 pAccount = GNC_ACCOUNT (pObject);
163set_parent_guid (gpointer pObject, gpointer pValue)
165 g_return_if_fail (pObject != NULL);
166 g_return_if_fail (pValue != NULL);
168 s->guid = *
static_cast<GncGUID*
>(pValue);
173 ParentGuidVec& l_accounts_needing_parents)
178 g_return_val_if_fail (sql_be != NULL, NULL);
180 guid = gnc_sql_load_guid (sql_be, row);
185 if (pAccount == NULL)
190 gnc_sql_load_object (sql_be, row, GNC_ID_ACCOUNT, pAccount, col_table);
197 && pAccount != gnc_book_get_root_account (sql_be->book()))
201 s->pAccount = pAccount;
202 gnc_sql_load_object (sql_be, row, GNC_ID_ACCOUNT, s, parent_col_table);
203 l_accounts_needing_parents.push_back(s);
213 ParentGuidVec l_accounts_needing_parents;
214 g_return_if_fail (sql_be != NULL);
218 pBook = sql_be->book();
220 std::string sql(
"SELECT * FROM " TABLE_NAME);
221 auto stmt = sql_be->create_statement_from_sql(sql);
223 for (
auto row : *result)
224 load_single_account (sql_be, row, l_accounts_needing_parents);
226 sql =
"SELECT DISTINCT guid FROM " TABLE_NAME;
227 gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
235 if (!l_accounts_needing_parents.empty())
237 auto progress_made =
true;
238 std::reverse(l_accounts_needing_parents.begin(),
239 l_accounts_needing_parents.end());
240 auto end = l_accounts_needing_parents.end();
241 while (progress_made)
243 progress_made =
false;
244 end = std::remove_if(l_accounts_needing_parents.begin(), end,
247 auto pParent = xaccAccountLookup (&s->guid,
249 if (pParent != nullptr)
251 gnc_account_append_child (pParent,
253 progress_made = true;
262 auto root = gnc_book_get_root_account (pBook);
263 end = std::remove_if(l_accounts_needing_parents.begin(), end,
266 if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT)
267 gnc_account_append_child (root, s->pAccount);
280 Account* pAcc = GNC_ACCOUNT (inst);
283 gboolean is_ok = FALSE;
284 gnc_commodity* commodity;
287 g_return_val_if_fail (sql_be != NULL, FALSE);
288 g_return_val_if_fail (inst != NULL, FALSE);
289 g_return_val_if_fail (GNC_IS_ACCOUNT (inst), FALSE);
291 ENTER (
"inst=%p", inst);
293 is_infant = qof_instance_get_infant (inst);
306 else if (sql_be->pristine() || is_infant)
316 if (op != OP_DB_DELETE && commodity != NULL)
333 is_ok = gnc_sql_slots_save (sql_be, guid, is_infant, inst);
337 is_ok = gnc_sql_slots_delete (sql_be, guid);
341 LEAVE (
"is_ok=%d", is_ok);
352 gpointer pObject)
const noexcept
354 load_from_guid_ref(row, obj_name, pObject,
363 add_objectref_guid_to_table(vec);
368 const gpointer pObject,
372 add_objectref_guid_to_query(obj_name, pObject, vec);
This is the private header for the account structure.
Account handling public routines.
bool commit(GncSqlBackend *, QofInstance *) override
UPDATE/INSERT a single instance of m_type_name into the database.
void load_all(GncSqlBackend *) override
Load all objects of m_type in the database into memory.
Main SQL backend structure.
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.
bool save_commodity(gnc_commodity *comm) noexcept
Ensure that a commodity referenced in another object is in fact saved in 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.
Encapsulates per-class table schema with functions to load, create a table, commit a changed front-en...
Row of SQL Query results.
load and save accounts data to SQL
load and save data to SQL
Commodity handling public routines.
load and save accounts data to SQL
load and save data to SQL
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship,...
Account * gnc_account_get_parent(const Account *acc)
This routine returns a pointer to the parent of the specified account.
Account * xaccMallocAccount(QofBook *book)
Constructor.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id,...
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
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.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define ENTER(format, args...)
Print a function entry debugging message.
The type used to store guids in C.