mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Move gnc_sql_do_db_operation and gnc_sql_object_is_it_in_db into GncSqlBackend.
This commit is contained in:
parent
f2eb13fc55
commit
b838c1ebf3
@ -357,7 +357,7 @@ GncSqlAccountBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc,
|
||||
is_ok = sql_be->do_db_operation (op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc,
|
||||
col_table);
|
||||
}
|
||||
|
||||
|
@ -87,21 +87,6 @@ extern "C"
|
||||
#include "gnc-vendor-sql.h"
|
||||
|
||||
static void gnc_sql_init_object_handlers (void);
|
||||
static GncSqlStatementPtr build_insert_statement (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table);
|
||||
static GncSqlStatementPtr build_update_statement (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table);
|
||||
static GncSqlStatementPtr build_delete_statement (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table);
|
||||
|
||||
#define TRANSACTION_NAME "trans"
|
||||
|
||||
@ -544,19 +529,6 @@ gnc_sql_load_object (const GncSqlBackend* sql_be, GncSqlRow& row,
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
static GncSqlStatementPtr
|
||||
create_single_col_select_statement (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
const GncSqlColumnTableEntryPtr table_row)
|
||||
{
|
||||
g_return_val_if_fail (sql_be != NULL, NULL);
|
||||
g_return_val_if_fail (table_name != NULL, NULL);
|
||||
|
||||
auto sql = std::string{"SELECT "} + table_row->name() + " FROM " + table_name;
|
||||
return sql_be->create_statement_from_sql(sql.c_str());
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
uint_t
|
||||
@ -577,184 +549,4 @@ gnc_sql_append_guids_to_sql (std::stringstream& sql, const InstanceVec& instance
|
||||
|
||||
return instances.size();
|
||||
}
|
||||
/* ================================================================= */
|
||||
static PairVec
|
||||
get_object_values (QofIdTypeConst obj_name,
|
||||
gpointer pObject, const EntryVec& table)
|
||||
{
|
||||
PairVec vec;
|
||||
|
||||
for (auto const& table_row : table)
|
||||
{
|
||||
if (!(table_row->is_autoincr()))
|
||||
{
|
||||
table_row->add_to_query (obj_name, pObject, vec);
|
||||
}
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_sql_object_is_it_in_db (GncSqlBackend* sql_be, const gchar* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table)
|
||||
{
|
||||
guint count;
|
||||
g_return_val_if_fail (sql_be != NULL, FALSE);
|
||||
g_return_val_if_fail (table_name != NULL, FALSE);
|
||||
g_return_val_if_fail (obj_name != NULL, FALSE);
|
||||
g_return_val_if_fail (pObject != NULL, FALSE);
|
||||
|
||||
/* SELECT * FROM */
|
||||
auto stmt = create_single_col_select_statement (sql_be, table_name, table[0]);
|
||||
g_assert (stmt != NULL);
|
||||
|
||||
/* WHERE */
|
||||
PairVec values{get_object_values(obj_name, pObject, table)};
|
||||
stmt->add_where_cond(obj_name, values);
|
||||
auto result = sql_be->execute_select_statement (stmt);
|
||||
if (result != NULL)
|
||||
{
|
||||
auto retval = result->size() > 0;
|
||||
return retval;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_sql_do_db_operation (GncSqlBackend* sql_be,
|
||||
E_DB_OPERATION op,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table)
|
||||
{
|
||||
GncSqlStatementPtr stmt;
|
||||
bool ok = false;
|
||||
|
||||
g_return_val_if_fail (sql_be != NULL, FALSE);
|
||||
g_return_val_if_fail (table_name != NULL, FALSE);
|
||||
g_return_val_if_fail (obj_name != NULL, FALSE);
|
||||
g_return_val_if_fail (pObject != NULL, FALSE);
|
||||
|
||||
if (op == OP_DB_INSERT)
|
||||
{
|
||||
stmt = build_insert_statement (sql_be, table_name, obj_name, pObject, table);
|
||||
}
|
||||
else if (op == OP_DB_UPDATE)
|
||||
{
|
||||
stmt = build_update_statement (sql_be, table_name, obj_name, pObject, table);
|
||||
}
|
||||
else if (op == OP_DB_DELETE)
|
||||
{
|
||||
stmt = build_delete_statement (sql_be, table_name, obj_name, pObject, table);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (FALSE);
|
||||
}
|
||||
if (sql_be->execute_nonselect_statement (stmt) != -1)
|
||||
ok = true;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static GncSqlStatementPtr
|
||||
build_insert_statement (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table)
|
||||
{
|
||||
GncSqlStatementPtr stmt;
|
||||
PairVec col_values;
|
||||
std::ostringstream sql;
|
||||
|
||||
g_return_val_if_fail (sql_be != NULL, NULL);
|
||||
g_return_val_if_fail (table_name != NULL, NULL);
|
||||
g_return_val_if_fail (obj_name != NULL, NULL);
|
||||
g_return_val_if_fail (pObject != NULL, NULL);
|
||||
PairVec values{get_object_values(obj_name, pObject, table)};
|
||||
|
||||
sql << "INSERT INTO " << table_name <<"(";
|
||||
for (auto const& col_value : values)
|
||||
{
|
||||
if (col_value != *values.begin())
|
||||
sql << ",";
|
||||
sql << col_value.first;
|
||||
}
|
||||
|
||||
sql << ") VALUES(";
|
||||
for (auto col_value : values)
|
||||
{
|
||||
if (col_value != *values.begin())
|
||||
sql << ",";
|
||||
sql << sql_be->quote_string(col_value.second);
|
||||
}
|
||||
sql << ")";
|
||||
|
||||
stmt = sql_be->create_statement_from_sql(sql.str());
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static GncSqlStatementPtr
|
||||
build_update_statement (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table)
|
||||
{
|
||||
GncSqlStatementPtr stmt;
|
||||
std::ostringstream sql;
|
||||
|
||||
g_return_val_if_fail (sql_be != NULL, NULL);
|
||||
g_return_val_if_fail (table_name != NULL, NULL);
|
||||
g_return_val_if_fail (obj_name != NULL, NULL);
|
||||
g_return_val_if_fail (pObject != NULL, NULL);
|
||||
|
||||
|
||||
PairVec values{get_object_values (obj_name, pObject, table)};
|
||||
|
||||
// Create the SQL statement
|
||||
sql << "UPDATE " << table_name << " SET ";
|
||||
|
||||
for (auto const& col_value : values)
|
||||
{
|
||||
if (col_value != *values.begin())
|
||||
sql << ",";
|
||||
sql << col_value.first << "=" <<
|
||||
sql_be->quote_string(col_value.second);
|
||||
}
|
||||
|
||||
stmt = sql_be->create_statement_from_sql(sql.str());
|
||||
/* We want our where condition to be just the first column and
|
||||
* value, i.e. the guid of the object.
|
||||
*/
|
||||
values.erase(values.begin() + 1, values.end());
|
||||
stmt->add_where_cond(obj_name, values);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static GncSqlStatementPtr
|
||||
build_delete_statement (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table)
|
||||
{
|
||||
std::ostringstream sql;
|
||||
|
||||
g_return_val_if_fail (sql_be != NULL, NULL);
|
||||
g_return_val_if_fail (table_name != NULL, NULL);
|
||||
g_return_val_if_fail (obj_name != NULL, NULL);
|
||||
g_return_val_if_fail (pObject != NULL, NULL);
|
||||
|
||||
sql << "DELETE FROM " << table_name;
|
||||
auto stmt = sql_be->create_statement_from_sql (sql.str());
|
||||
|
||||
/* WHERE */
|
||||
PairVec values;
|
||||
table[0]->add_to_query (obj_name, pObject, values);
|
||||
PairVec col_values{values[0]};
|
||||
stmt->add_where_cond (obj_name, col_values);
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
/* ========================== END OF FILE ===================== */
|
||||
|
@ -58,23 +58,6 @@ class GncSqlRow;
|
||||
#define GNC_SQL_BACKEND "gnc:sql:1"
|
||||
#define GNC_SQL_BACKEND_VERSION 1
|
||||
|
||||
/**
|
||||
* Performs an operation on the database.
|
||||
*
|
||||
* @param sql_be SQL backend struct
|
||||
* @param op Operation type
|
||||
* @param table_name SQL table name
|
||||
* @param obj_name QOF object type name
|
||||
* @param pObject Gnucash object
|
||||
* @param table DB table description
|
||||
* @return TRUE if successful, FALSE if not
|
||||
*/
|
||||
gboolean gnc_sql_do_db_operation (GncSqlBackend* sql_be,
|
||||
E_DB_OPERATION op,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table);
|
||||
|
||||
|
||||
/**
|
||||
@ -90,21 +73,6 @@ void gnc_sql_load_object (const GncSqlBackend* sql_be, GncSqlRow& row,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table);
|
||||
|
||||
/**
|
||||
* Checks whether an object is in the database or not.
|
||||
*
|
||||
* @param sql_be SQL backend struct
|
||||
* @param table_name DB table name
|
||||
* @param obj_name QOF object type name
|
||||
* @param pObject Object to be checked
|
||||
* @param table DB table description
|
||||
* @return TRUE if the object is in the database, FALSE otherwise
|
||||
*/
|
||||
gboolean gnc_sql_object_is_it_in_db (GncSqlBackend* sql_be,
|
||||
const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
const gpointer pObject,
|
||||
const EntryVec& table );
|
||||
/**
|
||||
* Loads the object guid from a database row. The table must have a column
|
||||
* named "guid" with type CT_GUID.
|
||||
|
@ -281,7 +281,8 @@ save_budget_amounts (GncSqlBackend* sql_be, GncBudget* budget)
|
||||
if (gnc_budget_is_account_period_value_set (budget, info.account, i))
|
||||
{
|
||||
info.period_num = i;
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, OP_DB_INSERT, AMOUNTS_TABLE, "", &info,
|
||||
is_ok = sql_be->do_db_operation(OP_DB_INSERT, AMOUNTS_TABLE,
|
||||
"", &info,
|
||||
budget_amounts_col_table);
|
||||
}
|
||||
}
|
||||
@ -394,8 +395,8 @@ GncSqlBudgetBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
{
|
||||
op = OP_DB_UPDATE;
|
||||
}
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget,
|
||||
col_table);
|
||||
is_ok = sql_be->do_db_operation(op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget,
|
||||
col_table);
|
||||
|
||||
// Now, commit any slots and recurrence
|
||||
if (is_ok)
|
||||
|
@ -192,8 +192,8 @@ do_commit_commodity (GncSqlBackend* sql_be, QofInstance* inst,
|
||||
{
|
||||
op = OP_DB_UPDATE;
|
||||
}
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, COMMODITIES_TABLE, GNC_ID_COMMODITY,
|
||||
inst, col_table);
|
||||
is_ok = sql_be->do_db_operation(op, COMMODITIES_TABLE, GNC_ID_COMMODITY,
|
||||
inst, col_table);
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
@ -228,8 +228,8 @@ is_commodity_in_db (GncSqlBackend* sql_be, gnc_commodity* pCommodity)
|
||||
g_return_val_if_fail (sql_be != NULL, FALSE);
|
||||
g_return_val_if_fail (pCommodity != NULL, FALSE);
|
||||
|
||||
return gnc_sql_object_is_it_in_db (sql_be, COMMODITIES_TABLE, GNC_ID_COMMODITY,
|
||||
pCommodity, col_table);
|
||||
return sql_be->object_in_db (COMMODITIES_TABLE, GNC_ID_COMMODITY,
|
||||
pCommodity, col_table);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -187,8 +187,8 @@ GncSqlEmployeeBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp,
|
||||
col_table);
|
||||
is_ok = sql_be->do_db_operation(op, TABLE_NAME, GNC_ID_EMPLOYEE, emp,
|
||||
col_table);
|
||||
}
|
||||
|
||||
if (is_ok)
|
||||
|
@ -211,8 +211,8 @@ GncSqlInvoiceBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, TABLE_NAME, GNC_ID_INVOICE, inst,
|
||||
col_table);
|
||||
is_ok = sql_be->do_db_operation(op, TABLE_NAME, GNC_ID_INVOICE, inst,
|
||||
col_table);
|
||||
}
|
||||
|
||||
if (is_ok)
|
||||
|
@ -194,8 +194,8 @@ GncSqlPriceBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, TABLE_NAME, GNC_ID_PRICE, pPrice,
|
||||
col_table);
|
||||
is_ok = sql_be->do_db_operation(op, TABLE_NAME, GNC_ID_PRICE, pPrice,
|
||||
col_table);
|
||||
}
|
||||
|
||||
return is_ok;
|
||||
|
@ -251,8 +251,8 @@ gnc_sql_recurrence_save (GncSqlBackend* sql_be, const GncGUID* guid,
|
||||
recurrence_info.be = sql_be;
|
||||
recurrence_info.guid = guid;
|
||||
recurrence_info.pRecurrence = (Recurrence*)r;
|
||||
return gnc_sql_do_db_operation (sql_be, OP_DB_INSERT, TABLE_NAME,
|
||||
TABLE_NAME, &recurrence_info, col_table);
|
||||
return sql_be->do_db_operation(OP_DB_INSERT, TABLE_NAME,
|
||||
TABLE_NAME, &recurrence_info, col_table);
|
||||
}
|
||||
|
||||
void
|
||||
@ -272,8 +272,8 @@ gnc_sql_recurrence_save_list (GncSqlBackend* sql_be, const GncGUID* guid,
|
||||
for (l = schedule; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
recurrence_info.pRecurrence = (Recurrence*)l->data;
|
||||
(void)gnc_sql_do_db_operation (sql_be, OP_DB_INSERT, TABLE_NAME,
|
||||
TABLE_NAME, &recurrence_info, col_table);
|
||||
(void)sql_be->do_db_operation(OP_DB_INSERT, TABLE_NAME,
|
||||
TABLE_NAME, &recurrence_info, col_table);
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,8 +287,8 @@ gnc_sql_recurrence_delete (GncSqlBackend* sql_be, const GncGUID* guid)
|
||||
|
||||
recurrence_info.be = sql_be;
|
||||
recurrence_info.guid = guid;
|
||||
return gnc_sql_do_db_operation (sql_be, OP_DB_DELETE, TABLE_NAME,
|
||||
TABLE_NAME, &recurrence_info, guid_col_table);
|
||||
return sql_be->do_db_operation(OP_DB_DELETE, TABLE_NAME,
|
||||
TABLE_NAME, &recurrence_info, guid_col_table);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -176,8 +176,8 @@ GncSqlSchedXactionBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
{
|
||||
op = OP_DB_UPDATE;
|
||||
}
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx,
|
||||
col_table);
|
||||
is_ok = sql_be->do_db_operation(op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx,
|
||||
col_table);
|
||||
guid = qof_instance_get_guid (inst);
|
||||
if (op == OP_DB_INSERT || op == OP_DB_UPDATE)
|
||||
{
|
||||
|
@ -649,10 +649,11 @@ save_slot (const gchar* key, KvpValue* value, gpointer data)
|
||||
slot_info_t* pNewInfo = slot_info_copy (pSlot_info, guid);
|
||||
KvpValue* oldValue = pSlot_info->pKvpValue;
|
||||
pSlot_info->pKvpValue = new KvpValue {guid};
|
||||
pSlot_info->is_ok = gnc_sql_do_db_operation (pSlot_info->be,
|
||||
OP_DB_INSERT, TABLE_NAME,
|
||||
TABLE_NAME, pSlot_info,
|
||||
col_table);
|
||||
pSlot_info->is_ok = pSlot_info->be->do_db_operation(OP_DB_INSERT,
|
||||
TABLE_NAME,
|
||||
TABLE_NAME,
|
||||
pSlot_info,
|
||||
col_table);
|
||||
g_return_if_fail (pSlot_info->is_ok);
|
||||
pKvpFrame->for_each_slot (save_slot, pNewInfo);
|
||||
delete pSlot_info->pKvpValue;
|
||||
@ -667,10 +668,11 @@ save_slot (const gchar* key, KvpValue* value, gpointer data)
|
||||
slot_info_t* pNewInfo = slot_info_copy (pSlot_info, guid);
|
||||
KvpValue* oldValue = pSlot_info->pKvpValue;
|
||||
pSlot_info->pKvpValue = new KvpValue {guid}; // Transfer ownership!
|
||||
pSlot_info->is_ok = gnc_sql_do_db_operation (pSlot_info->be,
|
||||
OP_DB_INSERT, TABLE_NAME,
|
||||
TABLE_NAME, pSlot_info,
|
||||
col_table);
|
||||
pSlot_info->is_ok = pSlot_info->be->do_db_operation(OP_DB_INSERT,
|
||||
TABLE_NAME,
|
||||
TABLE_NAME,
|
||||
pSlot_info,
|
||||
col_table);
|
||||
g_return_if_fail (pSlot_info->is_ok);
|
||||
for (auto cursor = value->get<GList*> (); cursor; cursor = cursor->next)
|
||||
{
|
||||
@ -685,10 +687,11 @@ save_slot (const gchar* key, KvpValue* value, gpointer data)
|
||||
break;
|
||||
default:
|
||||
{
|
||||
pSlot_info->is_ok = gnc_sql_do_db_operation (pSlot_info->be,
|
||||
OP_DB_INSERT, TABLE_NAME,
|
||||
TABLE_NAME, pSlot_info,
|
||||
col_table);
|
||||
pSlot_info->is_ok = pSlot_info->be->do_db_operation (OP_DB_INSERT,
|
||||
TABLE_NAME,
|
||||
TABLE_NAME,
|
||||
pSlot_info,
|
||||
col_table);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -761,8 +764,9 @@ gnc_sql_slots_delete (GncSqlBackend* sql_be, const GncGUID* guid)
|
||||
slot_info.be = sql_be;
|
||||
slot_info.guid = guid;
|
||||
slot_info.is_ok = TRUE;
|
||||
slot_info.is_ok = gnc_sql_do_db_operation (sql_be, OP_DB_DELETE, TABLE_NAME,
|
||||
TABLE_NAME, &slot_info, obj_guid_col_table);
|
||||
slot_info.is_ok = sql_be->do_db_operation(OP_DB_DELETE, TABLE_NAME,
|
||||
TABLE_NAME, &slot_info,
|
||||
obj_guid_col_table);
|
||||
|
||||
return slot_info.is_ok;
|
||||
}
|
||||
|
@ -781,6 +781,166 @@ GncSqlBackend::upgrade_table (const std::string& table_name,
|
||||
execute_nonselect_statement(stmt);
|
||||
}
|
||||
|
||||
static inline PairVec
|
||||
get_object_values (QofIdTypeConst obj_name,
|
||||
gpointer pObject, const EntryVec& table)
|
||||
{
|
||||
PairVec vec;
|
||||
|
||||
for (auto const& table_row : table)
|
||||
{
|
||||
if (!(table_row->is_autoincr()))
|
||||
{
|
||||
table_row->add_to_query (obj_name, pObject, vec);
|
||||
}
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
bool
|
||||
GncSqlBackend::object_in_db (const char* table_name, QofIdTypeConst obj_name,
|
||||
const gpointer pObject, const EntryVec& table) const noexcept
|
||||
{
|
||||
guint count;
|
||||
g_return_val_if_fail (table_name != nullptr, false);
|
||||
g_return_val_if_fail (obj_name != nullptr, false);
|
||||
g_return_val_if_fail (pObject != nullptr, false);
|
||||
|
||||
/* SELECT * FROM */
|
||||
auto sql = std::string{"SELECT "} + table[0]->name() + " FROM " + table_name;
|
||||
auto stmt = create_statement_from_sql(sql.c_str());
|
||||
assert (stmt != nullptr);
|
||||
|
||||
/* WHERE */
|
||||
PairVec values{get_object_values(obj_name, pObject, table)};
|
||||
stmt->add_where_cond(obj_name, values);
|
||||
auto result = execute_select_statement (stmt);
|
||||
return (result != nullptr && result->size() > 0);
|
||||
}
|
||||
|
||||
bool
|
||||
GncSqlBackend::do_db_operation (E_DB_OPERATION op, const char* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table) const noexcept
|
||||
{
|
||||
GncSqlStatementPtr stmt;
|
||||
|
||||
g_return_val_if_fail (table_name != nullptr, false);
|
||||
g_return_val_if_fail (obj_name != nullptr, false);
|
||||
g_return_val_if_fail (pObject != nullptr, false);
|
||||
|
||||
switch(op)
|
||||
{
|
||||
case OP_DB_INSERT:
|
||||
stmt = build_insert_statement (table_name, obj_name, pObject, table);
|
||||
break;
|
||||
case OP_DB_UPDATE:
|
||||
stmt = build_update_statement (table_name, obj_name, pObject, table);
|
||||
break;
|
||||
case OP_DB_DELETE:
|
||||
stmt = build_delete_statement (table_name, obj_name, pObject, table);
|
||||
break;
|
||||
}
|
||||
if (stmt == nullptr)
|
||||
return false;
|
||||
return (execute_nonselect_statement(stmt) != -1);
|
||||
}
|
||||
|
||||
GncSqlStatementPtr
|
||||
GncSqlBackend::build_insert_statement (const char* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table) const noexcept
|
||||
{
|
||||
GncSqlStatementPtr stmt;
|
||||
PairVec col_values;
|
||||
std::ostringstream sql;
|
||||
|
||||
g_return_val_if_fail (table_name != nullptr, nullptr);
|
||||
g_return_val_if_fail (obj_name != nullptr, nullptr);
|
||||
g_return_val_if_fail (pObject != nullptr, nullptr);
|
||||
PairVec values{get_object_values(obj_name, pObject, table)};
|
||||
|
||||
sql << "INSERT INTO " << table_name <<"(";
|
||||
for (auto const& col_value : values)
|
||||
{
|
||||
if (col_value != *values.begin())
|
||||
sql << ",";
|
||||
sql << col_value.first;
|
||||
}
|
||||
|
||||
sql << ") VALUES(";
|
||||
for (auto col_value : values)
|
||||
{
|
||||
if (col_value != *values.begin())
|
||||
sql << ",";
|
||||
sql << quote_string(col_value.second);
|
||||
}
|
||||
sql << ")";
|
||||
|
||||
stmt = create_statement_from_sql(sql.str());
|
||||
return stmt;
|
||||
}
|
||||
|
||||
GncSqlStatementPtr
|
||||
GncSqlBackend::build_update_statement(const gchar* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table) const noexcept
|
||||
{
|
||||
GncSqlStatementPtr stmt;
|
||||
std::ostringstream sql;
|
||||
|
||||
g_return_val_if_fail (table_name != nullptr, nullptr);
|
||||
g_return_val_if_fail (obj_name != nullptr, nullptr);
|
||||
g_return_val_if_fail (pObject != nullptr, nullptr);
|
||||
|
||||
|
||||
PairVec values{get_object_values (obj_name, pObject, table)};
|
||||
|
||||
// Create the SQL statement
|
||||
sql << "UPDATE " << table_name << " SET ";
|
||||
|
||||
for (auto const& col_value : values)
|
||||
{
|
||||
if (col_value != *values.begin())
|
||||
sql << ",";
|
||||
sql << col_value.first << "=" <<
|
||||
quote_string(col_value.second);
|
||||
}
|
||||
|
||||
stmt = create_statement_from_sql(sql.str());
|
||||
/* We want our where condition to be just the first column and
|
||||
* value, i.e. the guid of the object.
|
||||
*/
|
||||
values.erase(values.begin() + 1, values.end());
|
||||
stmt->add_where_cond(obj_name, values);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
GncSqlStatementPtr
|
||||
GncSqlBackend::build_delete_statement(const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table) const noexcept
|
||||
{
|
||||
std::ostringstream sql;
|
||||
|
||||
g_return_val_if_fail (table_name != nullptr, nullptr);
|
||||
g_return_val_if_fail (obj_name != nullptr, nullptr);
|
||||
g_return_val_if_fail (pObject != nullptr, nullptr);
|
||||
|
||||
sql << "DELETE FROM " << table_name;
|
||||
auto stmt = create_statement_from_sql (sql.str());
|
||||
|
||||
/* WHERE */
|
||||
PairVec values;
|
||||
table[0]->add_to_query (obj_name, pObject, values);
|
||||
PairVec col_values{values[0]};
|
||||
stmt->add_where_cond (obj_name, col_values);
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
GncSqlBackend::ObjectBackendRegistry::ObjectBackendRegistry()
|
||||
{
|
||||
register_backend(std::make_shared<GncSqlBookBackend>());
|
||||
|
@ -50,6 +50,13 @@ using VersionPair = std::pair<const std::string, unsigned int>;
|
||||
using VersionVec = std::vector<VersionPair>;
|
||||
using uint_t = unsigned int;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OP_DB_INSERT,
|
||||
OP_DB_UPDATE,
|
||||
OP_DB_DELETE
|
||||
} E_DB_OPERATION;
|
||||
|
||||
/**
|
||||
*
|
||||
* Main SQL backend structure.
|
||||
@ -194,6 +201,31 @@ public:
|
||||
* @param type: The QofInstance type constant to select the object backend.
|
||||
*/
|
||||
GncSqlObjectBackendPtr get_object_backend(const std::string& type) const noexcept;
|
||||
/**
|
||||
* Checks whether an object is in the database or not.
|
||||
*
|
||||
* @param table_name DB table name
|
||||
* @param obj_name QOF object type name
|
||||
* @param pObject Object to be checked
|
||||
* @param table DB table description
|
||||
* @return TRUE if the object is in the database, FALSE otherwise
|
||||
*/
|
||||
bool object_in_db (const char* table_name, QofIdTypeConst obj_name,
|
||||
const gpointer pObject, const EntryVec& table ) const noexcept;
|
||||
/**
|
||||
* Performs an operation on the database.
|
||||
*
|
||||
* @param op Operation type
|
||||
* @param table_name SQL table name
|
||||
* @param obj_name QOF object type name
|
||||
* @param pObject Gnucash object
|
||||
* @param table DB table description
|
||||
* @return TRUE if successful, FALSE if not
|
||||
*/
|
||||
bool do_db_operation (E_DB_OPERATION op, const char* table_name,
|
||||
QofIdTypeConst obj_name, gpointer pObject,
|
||||
const EntryVec& table) const noexcept;
|
||||
|
||||
QofBook* book() const noexcept { return m_book; }
|
||||
void set_loading(bool loading) noexcept { m_loading = loading; }
|
||||
bool pristine() const noexcept { return m_is_pristine_db; }
|
||||
@ -215,6 +247,19 @@ private:
|
||||
bool write_transactions();
|
||||
bool write_template_transactions();
|
||||
bool write_schedXactions();
|
||||
GncSqlStatementPtr build_insert_statement (const char* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table) const noexcept;
|
||||
GncSqlStatementPtr build_update_statement (const gchar* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table) const noexcept;
|
||||
GncSqlStatementPtr build_delete_statement (const char* table_name,
|
||||
QofIdTypeConst obj_name,
|
||||
gpointer pObject,
|
||||
const EntryVec& table) const noexcept;
|
||||
|
||||
class ObjectBackendRegistry
|
||||
{
|
||||
public:
|
||||
|
@ -29,7 +29,6 @@ extern "C"
|
||||
#include "gnc-sql-backend.hpp"
|
||||
#include "gnc-sql-column-table-entry.hpp"
|
||||
#include "gnc-slots-sql.h"
|
||||
#include "gnc-backend-sql.h" //for gnc_sql_do_db_operation
|
||||
|
||||
static QofLogModule log_module = G_LOG_DOMAIN;
|
||||
|
||||
@ -54,8 +53,8 @@ GncSqlObjectBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
{
|
||||
op = OP_DB_UPDATE;
|
||||
}
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, m_table_name.c_str(),
|
||||
m_type_name.c_str(), inst, m_col_table);
|
||||
is_ok = sql_be->do_db_operation(op, m_table_name.c_str(),
|
||||
m_type_name.c_str(), inst, m_col_table);
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
|
@ -38,13 +38,6 @@ using GncSqlColumnTableEntryPtr = std::shared_ptr<GncSqlColumnTableEntry>;
|
||||
using EntryVec = std::vector<GncSqlColumnTableEntryPtr>;
|
||||
using InstanceVec = std::vector<QofInstance*>;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OP_DB_INSERT,
|
||||
OP_DB_UPDATE,
|
||||
OP_DB_DELETE
|
||||
} E_DB_OPERATION;
|
||||
|
||||
/**
|
||||
* Encapsulates per-class table schema with functions to load, create a table,
|
||||
* commit a changed front-end object (note that database transaction semantics
|
||||
|
@ -372,8 +372,8 @@ delete_all_tt_entries (GncSqlBackend* sql_be, const GncGUID* guid)
|
||||
|
||||
guid_info.be = sql_be;
|
||||
guid_info.guid = guid;
|
||||
return gnc_sql_do_db_operation (sql_be, OP_DB_DELETE, TTENTRIES_TABLE_NAME,
|
||||
TTENTRIES_TABLE_NAME, &guid_info, guid_col_table);
|
||||
return sql_be->do_db_operation(OP_DB_DELETE, TTENTRIES_TABLE_NAME,
|
||||
TTENTRIES_TABLE_NAME, &guid_info, guid_col_table);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -391,11 +391,9 @@ save_tt_entries (GncSqlBackend* sql_be, const GncGUID* guid, GList* entries)
|
||||
for (entry = entries; entry != NULL && is_ok; entry = entry->next)
|
||||
{
|
||||
GncTaxTableEntry* e = (GncTaxTableEntry*)entry->data;
|
||||
is_ok = gnc_sql_do_db_operation (sql_be,
|
||||
OP_DB_INSERT,
|
||||
TTENTRIES_TABLE_NAME,
|
||||
GNC_ID_TAXTABLE, e,
|
||||
ttentries_col_table);
|
||||
is_ok = sql_be->do_db_operation(OP_DB_INSERT, TTENTRIES_TABLE_NAME,
|
||||
GNC_ID_TAXTABLE, e,
|
||||
ttentries_col_table);
|
||||
}
|
||||
|
||||
return is_ok;
|
||||
@ -429,8 +427,8 @@ GncSqlTaxTableBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
{
|
||||
op = OP_DB_UPDATE;
|
||||
}
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt,
|
||||
tt_col_table);
|
||||
is_ok = sql_be->do_db_operation(op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt,
|
||||
tt_col_table);
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
|
@ -565,8 +565,8 @@ delete_splits (GncSqlBackend* sql_be, Transaction* pTx)
|
||||
g_return_val_if_fail (sql_be != NULL, FALSE);
|
||||
g_return_val_if_fail (pTx != NULL, FALSE);
|
||||
|
||||
if (!gnc_sql_do_db_operation (sql_be, OP_DB_DELETE, SPLIT_TABLE,
|
||||
SPLIT_TABLE, pTx, tx_guid_col_table))
|
||||
if (!sql_be->do_db_operation(OP_DB_DELETE, SPLIT_TABLE,
|
||||
SPLIT_TABLE, pTx, tx_guid_col_table))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@ -617,8 +617,8 @@ GncSqlSplitBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
qof_instance_set_guid (inst, guid);
|
||||
}
|
||||
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, SPLIT_TABLE, GNC_ID_SPLIT,
|
||||
inst, split_col_table);
|
||||
is_ok = sql_be->do_db_operation(op, SPLIT_TABLE, GNC_ID_SPLIT,
|
||||
inst, split_col_table);
|
||||
|
||||
if (is_ok && !qof_instance_get_destroying (inst))
|
||||
{
|
||||
@ -668,8 +668,8 @@ GncSqlTransBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
|
||||
if (is_ok)
|
||||
{
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx,
|
||||
tx_col_table);
|
||||
is_ok = sql_be->do_db_operation(op, TRANSACTION_TABLE, GNC_ID_TRANS,
|
||||
pTx, tx_col_table);
|
||||
if (! is_ok)
|
||||
{
|
||||
err = "Transaction header save failed. Check trace log for SQL errors";
|
||||
|
@ -165,8 +165,8 @@ GncSqlVendorBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
|
||||
}
|
||||
if (is_ok)
|
||||
{
|
||||
is_ok = gnc_sql_do_db_operation (sql_be, op, TABLE_NAME, GNC_ID_VENDOR, v,
|
||||
col_table);
|
||||
is_ok = sql_be->do_db_operation(op, TABLE_NAME, GNC_ID_VENDOR, v,
|
||||
col_table);
|
||||
}
|
||||
|
||||
if (is_ok)
|
||||
|
@ -748,9 +748,9 @@ gnc_sql_object_is_it_in_db (GncSqlBackend* sql_be, const gchar* table_name,// C:
|
||||
test_gnc_sql_object_is_it_in_db (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
}*/
|
||||
/* gnc_sql_do_db_operation
|
||||
/* GncSqlBackend::do_db_operation
|
||||
gboolean
|
||||
gnc_sql_do_db_operation (GncSqlBackend* sql_be,// C: 22 in 12 */
|
||||
GncSqlBackend::do_db_operation (GncSqlBackend* sql_be,// C: 22 in 12 */
|
||||
/* static void
|
||||
test_gnc_sql_do_db_operation (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user