gnucash unstable: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Sat Apr 14 13:22:35 EDT 2018
Updated via https://github.com/Gnucash/gnucash/commit/f680823d (commit)
via https://github.com/Gnucash/gnucash/commit/01420adb (commit)
via https://github.com/Gnucash/gnucash/commit/e90a662a (commit)
via https://github.com/Gnucash/gnucash/commit/b7396611 (commit)
via https://github.com/Gnucash/gnucash/commit/9b643574 (commit)
via https://github.com/Gnucash/gnucash/commit/e4d0ad9d (commit)
from https://github.com/Gnucash/gnucash/commit/a39ba167 (commit)
commit f680823dbfff5cc90c98139c755c727f2f19d4cb
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Apr 13 14:02:57 2018 -0700
Bug 795039 - Crash on startup using Technicolor Style sheet in report
The mingw-w64 toolchain bizarrely substitutes scm_to_locale_string()
for scm_to_utf8_string(). This results in latin1 (yeah, "locale" is
a lie) instead of utf8 which causes an assertion in
g_utf8_collate_key().
Perhaps equally bizarre, the compiler doesn't make the substitution
with scm_to_utf8_stringn(), so use that instead.
diff --git a/libgnucash/app-utils/gnc-ui-util.c b/libgnucash/app-utils/gnc-ui-util.c
index c4e3a86..5fa6430 100644
--- a/libgnucash/app-utils/gnc-ui-util.c
+++ b/libgnucash/app-utils/gnc-ui-util.c
@@ -590,13 +590,13 @@ gnc_ui_account_get_tax_info_string (const Account *account)
{
gchar *form = NULL;
- /* Note: using scm_to_utf8_string directly here instead
+ /* Note: using scm_to_utf8_stringn directly here instead
of our wrapper gnc_scm_to_utf8_string. 'form' should
be freed with 'free' instead of 'g_free'. This will
be taken care of automatically during scm_dynwind_end,
because we inform guile of this memory allocation via
scm_dynwind_free a little further. */
- form = scm_to_utf8_string (form_scm);
+ form = scm_to_utf8_stringn (form_scm, NULL);
if (!form)
{
if (tax_related)
diff --git a/libgnucash/core-utils/gnc-guile-utils.c b/libgnucash/core-utils/gnc-guile-utils.c
index e86fe9f..99e46d7 100644
--- a/libgnucash/core-utils/gnc-guile-utils.c
+++ b/libgnucash/core-utils/gnc-guile-utils.c
@@ -43,7 +43,7 @@ gchar *gnc_scm_to_utf8_string(SCM scm_string)
gchar* s;
char * str;
- str = scm_to_utf8_string(scm_string);
+ str = scm_to_utf8_stringn(scm_string, NULL);
s = g_strdup(str);
free (str);
return s;
commit 01420adb9989f49a0413b4a9bbf34494623a5443
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Mar 24 16:30:34 2018 -0700
Bug 772776 - VERY large queries (over 11000 fields in IN clause) slow...
down GnuCash
Replace with joins or subqueries. Affords a 20% speedup on Windows.
diff --git a/libgnucash/backend/sql/gnc-slots-sql.cpp b/libgnucash/backend/sql/gnc-slots-sql.cpp
index ab2d6e4..ca719f3 100644
--- a/libgnucash/backend/sql/gnc-slots-sql.cpp
+++ b/libgnucash/backend/sql/gnc-slots-sql.cpp
@@ -821,44 +821,6 @@ load_slot_for_list_item (GncSqlBackend* sql_be, GncSqlRow& row,
}
-void
-gnc_sql_slots_load_for_instancevec (GncSqlBackend* sql_be, InstanceVec& instances)
-{
- QofCollection* coll;
- std::stringstream sql;
-
- g_return_if_fail (sql_be != NULL);
-
- // Ignore empty list
- if (instances.empty()) return;
-
- coll = qof_instance_get_collection (instances[0]);
-
- // Create the query for all slots for all items on the list
-
- sql << "SELECT * FROM " << TABLE_NAME << " WHERE " <<
- obj_guid_col_table[0]->name();
- if (instances.size() != 1)
- sql << " IN (";
- else
- sql << " = ";
-
- gnc_sql_append_guids_to_sql (sql, instances);
- if (instances.size() > 1)
- sql << ")";
-
- // Execute the query and load the slots
- auto stmt = sql_be->create_statement_from_sql(sql.str());
- if (stmt == nullptr)
- {
- PERR ("stmt == NULL, SQL = '%s'\n", sql.str().c_str());
- return;
- }
- auto result = sql_be->execute_select_statement (stmt);
- for (auto row : *result)
- load_slot_for_list_item (sql_be, row, coll);
-}
-
static void
load_slot_for_book_object (GncSqlBackend* sql_be, GncSqlRow& row,
BookLookupFn lookup_fn)
diff --git a/libgnucash/backend/sql/gnc-slots-sql.h b/libgnucash/backend/sql/gnc-slots-sql.h
index 0cdf3a6..b7b9891 100644
--- a/libgnucash/backend/sql/gnc-slots-sql.h
+++ b/libgnucash/backend/sql/gnc-slots-sql.h
@@ -76,17 +76,6 @@ gboolean gnc_sql_slots_delete (GncSqlBackend* sql_be, const GncGUID* guid);
*/
void gnc_sql_slots_load (GncSqlBackend* sql_be, QofInstance* inst);
-/**
- * gnc_sql_slots_load_for_instancevec - Loads slots for a set of QofInstance*
- * from the db. Loading slots for a set is faster than loading for one object
- * at a time because fewer SQL queries are used.
- *
- * @param sql_be SQL backend
- * @param list List of objects
- */
-void gnc_sql_slots_load_for_instancevec (GncSqlBackend* sql_be,
- InstanceVec& instances);
-
typedef QofInstance* (*BookLookupFn) (const GncGUID* guid,
const QofBook* book);
diff --git a/libgnucash/backend/sql/gnc-sql-backend.cpp b/libgnucash/backend/sql/gnc-sql-backend.cpp
index 1a8af92..536b76b 100644
--- a/libgnucash/backend/sql/gnc-sql-backend.cpp
+++ b/libgnucash/backend/sql/gnc-sql-backend.cpp
@@ -510,19 +510,19 @@ GncSqlBackend::sync(QofBook* book)
void
GncSqlBackend::begin(QofInstance* inst)
{
- g_return_if_fail (inst != NULL);
+ //g_return_if_fail (inst != NULL);
- ENTER (" ");
- LEAVE ("");
+ //ENTER (" ");
+ //LEAVE ("");
}
void
GncSqlBackend::rollback(QofInstance* inst)
{
- g_return_if_fail (inst != NULL);
+ //g_return_if_fail (inst != NULL);
- ENTER (" ");
- LEAVE ("");
+ //ENTER (" ");
+ //LEAVE ("");
}
void
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.cpp b/libgnucash/backend/sql/gnc-transaction-sql.cpp
index 5d94e69..ca8cb97 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-transaction-sql.cpp
@@ -247,52 +247,36 @@ load_single_split (GncSqlBackend* sql_be, GncSqlRow& row)
}
return pSplit;
}
-
-static void
-load_splits_for_sql_subquery (GncSqlBackend* sql_be, std::string subquery)
-{
- g_return_if_fail (sql_be != NULL);
- const std::string sskey(tx_guid_col_table[0]->name());
- std::string sql("SELECT * FROM " SPLIT_TABLE " WHERE ");
- sql += sskey + " IN (" + subquery + ")";
- auto stmt = sql_be->create_statement_from_sql(sql);
- auto result = sql_be->execute_select_statement(stmt);
- for (auto row : *result)
- load_single_split (sql_be, row);
- const std::string spkey(split_col_table[0]->name());
- std::string sub_subquery("SELECT DISTINCT ");
- sub_subquery += spkey + " FROM " SPLIT_TABLE " WHERE " + sskey +
- " IN (" + subquery + ")";
- gnc_sql_slots_load_for_sql_subquery(sql_be, sub_subquery,
- (BookLookupFn)xaccSplitLookup);
-}
-
static void
-load_splits_for_tx_list (GncSqlBackend* sql_be, InstanceVec& transactions)
+load_splits_for_transactions (GncSqlBackend* sql_be, std::string selector)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
+ const std::string spkey(split_col_table[0]->name());
+ const std::string sskey(tx_guid_col_table[0]->name());
+ const std::string tpkey(tx_col_table[0]->name());
- sql << "SELECT * FROM " << SPLIT_TABLE << " WHERE " <<
- tx_guid_col_table[0]->name() << " IN (";
- gnc_sql_append_guids_to_sql (sql, transactions);
- sql << ")";
+ std::string sql("SELECT ");
+ if (selector.empty())
+ {
+ sql += SPLIT_TABLE ".* FROM " SPLIT_TABLE " INNER JOIN "
+ TRANSACTION_TABLE " WHERE " SPLIT_TABLE "." + sskey + " = "
+ TRANSACTION_TABLE "." + tpkey;
+ selector = "(SELECT DISTINCT " + tpkey + " FROM " TRANSACTION_TABLE ")";
+ }
+ else
+ sql += " * FROM " SPLIT_TABLE " WHERE " + sskey + " IN " + selector;
// Execute the query and load the splits
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement (stmt);
- InstanceVec instances;
for (auto row : *result)
- {
Split* s = load_single_split (sql_be, row);
- if (s != nullptr)
- instances.push_back(QOF_INSTANCE(s));
- }
-
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ sql = "SELECT DISTINCT ";
+ sql += spkey + " FROM " SPLIT_TABLE " WHERE " + sskey + " IN " + selector;
+ gnc_sql_slots_load_for_sql_subquery(sql_be, sql,
+ (BookLookupFn)xaccSplitLookup);
}
static Transaction*
@@ -356,19 +340,30 @@ typedef struct
* @param stmt SQL statement
*/
static void
-query_transactions (GncSqlBackend* sql_be, const GncSqlStatementPtr& stmt)
+query_transactions (GncSqlBackend* sql_be, std::string selector)
{
g_return_if_fail (sql_be != NULL);
- g_return_if_fail (stmt != NULL);
+ const std::string tpkey(tx_col_table[0]->name());
+ std::string sql("SELECT * FROM " TRANSACTION_TABLE);
+
+ if (!selector.empty() && selector[0] == '(')
+ sql += " WHERE " + tpkey + " IN " + selector;
+ else if (!selector.empty()) // plain condition
+ sql += " WHERE " + selector;
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
if (result->begin() == result->end())
+ {
+ PINFO("Query %s returned no results", sql.c_str());
return;
-
+ }
+
Transaction* tx;
// Load the transactions
InstanceVec instances;
+ instances.reserve(result->size());
for (auto row : *result)
{
tx = load_single_tx (sql_be, row);
@@ -382,8 +377,15 @@ query_transactions (GncSqlBackend* sql_be, const GncSqlStatementPtr& stmt)
// Load all splits and slots for the transactions
if (!instances.empty())
{
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
- load_splits_for_tx_list (sql_be, instances);
+ const std::string tpkey(tx_col_table[0]->name());
+ if (selector.empty())
+ {
+ selector = "(SELECT DISTINCT ";
+ selector += tpkey + " FROM " TRANSACTION_TABLE +")";
+ }
+ load_splits_for_transactions (sql_be, selector);
+ gnc_sql_slots_load_for_sql_subquery (sql_be, selector,
+ (BookLookupFn)xaccTransLookup);
}
// Commit all of the transactions
@@ -691,16 +693,15 @@ void gnc_sql_transaction_load_tx_for_account (GncSqlBackend* sql_be,
g_return_if_fail (account != NULL);
guid = qof_instance_get_guid (QOF_INSTANCE (account));
- (void)guid_to_string_buff (guid, guid_buf);
- query_sql = g_strdup_printf (
- "SELECT DISTINCT t.* FROM %s AS t, %s AS s WHERE s.tx_guid=t.guid AND s.account_guid ='%s'",
- TRANSACTION_TABLE, SPLIT_TABLE, guid_buf);
- auto stmt = sql_be->create_statement_from_sql(query_sql);
- g_free (query_sql);
- if (stmt != nullptr)
- {
- query_transactions (sql_be, stmt);
- }
+
+ const std::string tpkey(tx_col_table[0]->name()); //guid
+ const std::string spkey(split_col_table[0]->name()); //guid
+ const std::string stkey(split_col_table[1]->name()); //txn_guid
+ const std::string sakey(split_col_table[2]->name()); //account_guid
+ std::string sql("(SELECT DISTINCT ");
+ sql += stkey + " FROM " SPLIT_TABLE " WHERE " + sakey + " = '";
+ sql += gnc::GUID(*guid).to_string() + "')";
+ query_transactions (sql_be, sql);
}
/**
@@ -713,44 +714,7 @@ void
GncSqlTransBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
-
- std::string query_sql("SELECT * FROM " TRANSACTION_TABLE);
- auto stmt = sql_be->create_statement_from_sql(query_sql);
-
- if (stmt != nullptr)
- {
- auto result = sql_be->execute_select_statement(stmt);
- if (result->begin() == result->end())
- return;
-
- Transaction* tx;
-
- // Load the transactions
- InstanceVec instances;
- instances.reserve(result->size());
- for (auto row : *result)
- {
- tx = load_single_tx (sql_be, row);
- if (tx != nullptr)
- {
- xaccTransScrubPostedDate (tx);
- instances.push_back(QOF_INSTANCE(tx));
- }
- }
- if (instances.empty())
- return;
- const std::string tpkey(tx_col_table[0]->name());
- std::string subquery("SELECT DISTINCT ");
- subquery += tpkey + " FROM " TRANSACTION_TABLE;
- gnc_sql_slots_load_for_sql_subquery (sql_be, subquery,
- (BookLookupFn)xaccTransLookup);
- load_splits_for_sql_subquery (sql_be, subquery);
-
- // Commit all of the transactions
- for (auto instance : instances)
- xaccTransCommitEdit(GNC_TRANSACTION(instance));
-
- }
+ query_transactions (sql_be, "");
}
static void
@@ -995,12 +959,11 @@ GncSqlColumnTableEntryImpl<CT_TXREF>::load (const GncSqlBackend* sql_be,
tx = xaccTransLookup (&guid, sql_be->book());
// If the transaction is not found, try loading it
+ std::string tpkey(tx_col_table[0]->name());
if (tx == nullptr)
{
- auto buf = std::string{"SELECT * FROM "} + TRANSACTION_TABLE +
- " WHERE guid='" + val + "'";
- auto stmt = sql_be->create_statement_from_sql (buf);
- query_transactions ((GncSqlBackend*)sql_be, stmt);
+ std::string sql = tpkey + " = '" + val + "'";
+ query_transactions ((GncSqlBackend*)sql_be, sql);
tx = xaccTransLookup (&guid, sql_be->book());
}
diff --git a/libgnucash/engine/TransLog.c b/libgnucash/engine/TransLog.c
index 7584bc0..b88d982 100644
--- a/libgnucash/engine/TransLog.c
+++ b/libgnucash/engine/TransLog.c
@@ -230,7 +230,7 @@ xaccTransWriteLog (Transaction *trans, char flag)
if (!gen_logs)
{
- PINFO ("Attempt to write disabled transaction log");
+ PINFO ("Attempt to write disabled transaction log");
return;
}
if (!trans_log) return;
commit e90a662a20299d5cbd649cc855cb491a3d9dc228
Author: John Ralls <jralls at ceridwen.us>
Date: Mon Mar 26 16:59:49 2018 -0700
Use subquery instead of instancevec GncSqlTransBackend::load_all.
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.cpp b/libgnucash/backend/sql/gnc-transaction-sql.cpp
index 6013aaa..5d94e69 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-transaction-sql.cpp
@@ -249,6 +249,25 @@ load_single_split (GncSqlBackend* sql_be, GncSqlRow& row)
}
static void
+load_splits_for_sql_subquery (GncSqlBackend* sql_be, std::string subquery)
+{
+ g_return_if_fail (sql_be != NULL);
+ const std::string sskey(tx_guid_col_table[0]->name());
+ std::string sql("SELECT * FROM " SPLIT_TABLE " WHERE ");
+ sql += sskey + " IN (" + subquery + ")";
+ auto stmt = sql_be->create_statement_from_sql(sql);
+ auto result = sql_be->execute_select_statement(stmt);
+ for (auto row : *result)
+ load_single_split (sql_be, row);
+ const std::string spkey(split_col_table[0]->name());
+ std::string sub_subquery("SELECT DISTINCT ");
+ sub_subquery += spkey + " FROM " SPLIT_TABLE " WHERE " + sskey +
+ " IN (" + subquery + ")";
+ gnc_sql_slots_load_for_sql_subquery(sql_be, sub_subquery,
+ (BookLookupFn)xaccSplitLookup);
+}
+
+static void
load_splits_for_tx_list (GncSqlBackend* sql_be, InstanceVec& transactions)
{
g_return_if_fail (sql_be != NULL);
@@ -695,12 +714,42 @@ GncSqlTransBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- auto query_sql = g_strdup_printf ("SELECT * FROM %s", TRANSACTION_TABLE);
+ std::string query_sql("SELECT * FROM " TRANSACTION_TABLE);
auto stmt = sql_be->create_statement_from_sql(query_sql);
- g_free (query_sql);
+
if (stmt != nullptr)
{
- query_transactions (sql_be, stmt);
+ auto result = sql_be->execute_select_statement(stmt);
+ if (result->begin() == result->end())
+ return;
+
+ Transaction* tx;
+
+ // Load the transactions
+ InstanceVec instances;
+ instances.reserve(result->size());
+ for (auto row : *result)
+ {
+ tx = load_single_tx (sql_be, row);
+ if (tx != nullptr)
+ {
+ xaccTransScrubPostedDate (tx);
+ instances.push_back(QOF_INSTANCE(tx));
+ }
+ }
+ if (instances.empty())
+ return;
+ const std::string tpkey(tx_col_table[0]->name());
+ std::string subquery("SELECT DISTINCT ");
+ subquery += tpkey + " FROM " TRANSACTION_TABLE;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, subquery,
+ (BookLookupFn)xaccTransLookup);
+ load_splits_for_sql_subquery (sql_be, subquery);
+
+ // Commit all of the transactions
+ for (auto instance : instances)
+ xaccTransCommitEdit(GNC_TRANSACTION(instance));
+
}
}
commit b739661171edad92c678b5bbf6e5814c34518a24
Author: John Ralls <jralls at ceridwen.us>
Date: Sun Mar 25 10:19:44 2018 -0700
Remove functions marked G_UNUSED.
More noise reduction.
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.cpp b/libgnucash/backend/sql/gnc-transaction-sql.cpp
index e54728c..6013aaa 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-transaction-sql.cpp
@@ -872,199 +872,6 @@ typedef struct
gboolean has_been_run;
} split_query_info_t;
-#define TX_GUID_CHECK 0
-
-G_GNUC_UNUSED static gpointer
-compile_split_query (GncSqlBackend* sql_be, QofQuery* query)
-{
- split_query_info_t* query_info = NULL;
- gchar* query_sql;
-
- g_return_val_if_fail (sql_be != NULL, NULL);
- g_return_val_if_fail (query != NULL, NULL);
-
- query_info = static_cast<decltype (query_info)> (
- g_malloc (sizeof (split_query_info_t)));
- g_assert (query_info != NULL);
- query_info->has_been_run = FALSE;
-
- if (qof_query_has_terms (query))
- {
- GList* orterms = qof_query_get_terms (query);
- GList* orTerm;
- std::stringstream sql;
- gboolean need_OR = FALSE;
-
- for (orTerm = orterms; orTerm != NULL; orTerm = orTerm->next)
- {
- GList* andterms = (GList*)orTerm->data;
- GList* andTerm;
- gboolean need_AND = FALSE;
-#if TX_GUID_CHECK
- gboolean has_tx_guid_check = FALSE;
-#endif
- if (need_OR)
- {
- sql << " OR ";
- }
- sql << "(";
- for (andTerm = andterms; andTerm != NULL; andTerm = andTerm->next)
- {
- QofQueryTerm* term;
- GSList* paramPath;
- gboolean unknownPath = FALSE;
-
- term = (QofQueryTerm*)andTerm->data;
- paramPath = qof_query_term_get_param_path (term);
- const char* path = static_cast<decltype (path)> (paramPath->data);
- const char* next_path =
- static_cast<decltype (next_path)> (paramPath->next->data);
- if (strcmp (path, QOF_PARAM_BOOK) == 0) continue;
-
-#if SIMPLE_QUERY_COMPILATION
- if (strcmp (path, SPLIT_ACCOUNT) != 0 ||
- strcmp (next_path, QOF_PARAM_GUID) != 0) continue;
-#endif
-
- if (need_AND) sql<< " AND ";
-
- if (strcmp (path, SPLIT_ACCOUNT) == 0 &&
- strcmp (next_path, QOF_PARAM_GUID) == 0)
- {
- convert_query_term_to_sql (sql_be, "s.account_guid", term,
- sql);
-#if SIMPLE_QUERY_COMPILATION
- goto done_compiling_query;
-#endif
-
- }
- else if (strcmp (path, SPLIT_RECONCILE) == 0)
- {
- convert_query_term_to_sql (sql_be, "s.reconcile_state",
- term, sql);
-
- }
- else if (strcmp (path, SPLIT_TRANS) == 0)
- {
-#if TX_GUID_CHECK
- if (!has_tx_guid_check)
- {
- sql << "(splits.tx_guid = transactions.guid) AND ");
- has_tx_guid_check = TRUE;
- }
-#endif
- if (strcmp (next_path, TRANS_DATE_POSTED) == 0)
- {
- convert_query_term_to_sql (sql_be, "t.post_date", term,
- sql);
- }
- else if (strcmp (next_path, TRANS_DESCRIPTION) == 0)
- {
- convert_query_term_to_sql (sql_be, "t.description",
- term, sql);
- }
- else
- {
- unknownPath = TRUE;
- }
-
- }
- else if (strcmp (path, SPLIT_VALUE) == 0)
- {
- convert_query_term_to_sql (sql_be,
- "s.value_num/s.value_denom",
- term, sql);
- }
- else
- {
- unknownPath = TRUE;
- }
-
- if (unknownPath)
- {
- std::stringstream name;
- name << static_cast<char*>(paramPath->data);
- for (;paramPath->next != NULL; paramPath = paramPath->next)
- {
- next_path =
- static_cast<decltype (next_path)>(paramPath->next->data);
- name << "." << next_path;
- }
- PERR ("Unknown SPLIT query field: %s\n",
- name.str().c_str());
- }
- need_AND = TRUE;
- }
-
- /* If the last char in the string is a '(', then for some reason, there were
- no terms added to the SQL. If so, remove it and ignore the OR term. */
- if (!sql.str().empty() && sql.str().back() == '(')
- {
- sql.str().erase(sql.str().back());
- need_OR = FALSE;
- }
- else
- {
- sql << ")";
- need_OR = TRUE;
- }
- }
-
-#if SIMPLE_QUERY_COMPILATION
-done_compiling_query:
-#endif
- if (!sql.str().empty())
- {
-#if SIMPLE_QUERY_COMPILATION
- sql<< ")";
-#endif
- query_sql = g_strdup_printf (
- "SELECT DISTINCT t.* FROM %s AS t, %s AS s WHERE s.tx_guid=t.guid AND %s",
- TRANSACTION_TABLE, SPLIT_TABLE, sql.str().c_str());
- }
- else
- {
- query_sql = g_strdup_printf ("SELECT * FROM %s", TRANSACTION_TABLE);
- }
- query_info->stmt = sql_be->create_statement_from_sql(query_sql);
- g_free (query_sql);
-
- }
- else
- {
- query_sql = g_strdup_printf ("SELECT * FROM %s", TRANSACTION_TABLE);
- query_info->stmt = sql_be->create_statement_from_sql(query_sql);
- g_free (query_sql);
- }
-
- return query_info;
-}
-
-G_GNUC_UNUSED static void
-run_split_query (GncSqlBackend* sql_be, gpointer pQuery)
-{
- split_query_info_t* query_info = (split_query_info_t*)pQuery;
-
- g_return_if_fail (sql_be != NULL);
- g_return_if_fail (pQuery != NULL);
-
- if (!query_info->has_been_run)
- {
- query_transactions (sql_be, query_info->stmt);
- query_info->has_been_run = TRUE;
- query_info->stmt = nullptr;
- }
-}
-
-G_GNUC_UNUSED static void
-free_split_query (GncSqlBackend* sql_be, gpointer pQuery)
-{
- g_return_if_fail (sql_be != NULL);
- g_return_if_fail (pQuery != NULL);
-
- g_free (pQuery);
-}
-
/* ----------------------------------------------------------------- */
typedef struct
{
@@ -1118,22 +925,6 @@ static const EntryVec acct_balances_col_table
(QofSetterFunc)set_acct_bal_balance),
};
-G_GNUC_UNUSED static single_acct_balance_t*
-load_single_acct_balances (const GncSqlBackend* sql_be, GncSqlRow& row)
-{
- single_acct_balance_t* bal = NULL;
-
- g_return_val_if_fail (sql_be != NULL, NULL);
-
- bal = static_cast<decltype (bal)> (g_malloc (sizeof (single_acct_balance_t)));
- g_assert (bal != NULL);
-
- bal->sql_be = sql_be;
- gnc_sql_load_object (sql_be, row, NULL, bal, acct_balances_col_table);
-
- return bal;
-}
-
/* ----------------------------------------------------------------- */
template<> void
GncSqlColumnTableEntryImpl<CT_TXREF>::load (const GncSqlBackend* sql_be,
commit 9b643574274c5f13093c6b4d3add25a6fc0f309f
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Mar 24 18:16:00 2018 -0700
Remove LOAD_TRANSACTIONS_AS_NEEDED from SQL backend.
We're not ready for that and until we are it's just noise.
diff --git a/libgnucash/backend/sql/gnc-account-sql.cpp b/libgnucash/backend/sql/gnc-account-sql.cpp
index e926b0d..f80370b 100644
--- a/libgnucash/backend/sql/gnc-account-sql.cpp
+++ b/libgnucash/backend/sql/gnc-account-sql.cpp
@@ -273,27 +273,6 @@ GncSqlAccountBackend::load_all (GncSqlBackend* sql_be)
});
}
-#if LOAD_TRANSACTIONS_AS_NEEDED
- /* Load starting balances */
- auto bal_slist = gnc_sql_get_account_balances_slist (sql_be);
- for (auto bal = bal_slist; bal != NULL; bal = bal->next)
- {
- acct_balances_t* balances = (acct_balances_t*)bal->data;
-
- qof_instance_increase_editlevel (balances->acct);
- g_object_set (balances->acct,
- "start-balance", &balances->balance,
- "start-cleared-balance", &balances->cleared_balance,
- "start-reconciled-balance", &balances->reconciled_balance,
- NULL);
-
- qof_instance_decrease_editlevel (balances->acct);
- }
- if (bal_slist != NULL)
- {
- g_slist_free (bal_slist);
- }
-#endif
LEAVE ("");
}
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.cpp b/libgnucash/backend/sql/gnc-transaction-sql.cpp
index 8f92178..e54728c 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-transaction-sql.cpp
@@ -64,7 +64,6 @@ extern "C"
#include "gnc-slots-sql.h"
#define SIMPLE_QUERY_COMPILATION 1
-#define LOAD_TRANSACTIONS_AS_NEEDED 0
static QofLogModule log_module = G_LOG_DOMAIN;
@@ -264,13 +263,17 @@ load_splits_for_tx_list (GncSqlBackend* sql_be, InstanceVec& transactions)
// Execute the query and load the splits
auto stmt = sql_be->create_statement_from_sql(sql.str());
auto result = sql_be->execute_select_statement (stmt);
+ InstanceVec instances;
for (auto row : *result)
+ {
Split* s = load_single_split (sql_be, row);
- sql = "SELECT DISTINCT ";
- sql += spkey + " FROM " SPLIT_TABLE " WHERE " + sskey + " IN " + selector;
- gnc_sql_slots_load_for_sql_subquery(sql_be, sql,
- (BookLookupFn)xaccSplitLookup);
+ if (s != nullptr)
+ instances.push_back(QOF_INSTANCE(s));
+ }
+
+ if (!instances.empty())
+ gnc_sql_slots_load_for_instancevec (sql_be, instances);
}
static Transaction*
@@ -344,19 +347,6 @@ query_transactions (GncSqlBackend* sql_be, const GncSqlStatementPtr& stmt)
return;
Transaction* tx;
-#if LOAD_TRANSACTIONS_AS_NEEDED
- GSList* bal_list = NULL;
- Account* root = gnc_book_get_root_account (sql_be->book());
-
- qof_event_suspend ();
- xaccAccountBeginEdit (root);
-
- // Save the start/ending balances (balance, cleared and reconciled) for
- // every account.
- gnc_account_foreach_descendant (gnc_book_get_root_account (sql_be->primary_book),
- save_account_balances,
- &bal_list);
-#endif
// Load the transactions
InstanceVec instances;
@@ -381,71 +371,9 @@ query_transactions (GncSqlBackend* sql_be, const GncSqlStatementPtr& stmt)
for (auto instance : instances)
xaccTransCommitEdit(GNC_TRANSACTION(instance));
-#if LOAD_TRANSACTIONS_AS_NEEDED
- // Update the account balances based on the loaded splits. If the end
- // balance has changed, update the start balance so that the end
- // balance is the same as it was before the splits were loaded.
- // Repeat for cleared and reconciled balances.
- for (auto nextbal = bal_list; nextbal != NULL; nextbal = nextbal->next)
- {
- full_acct_balances_t* balns = (full_acct_balances_t*)nextbal->data;
- gnc_numeric* pnew_end_bal;
- gnc_numeric* pnew_end_c_bal;
- gnc_numeric* pnew_end_r_bal;
- gnc_numeric adj;
-
- g_object_get (balns->acc,
- "end-balance", &pnew_end_bal,
- "end-cleared-balance", &pnew_end_c_bal,
- "end-reconciled-balance", &pnew_end_r_bal,
- NULL);
-
- qof_instance_increase_editlevel (balns - acc);
- if (!gnc_numeric_eq (*pnew_end_bal, balns->end_bal))
- {
- adj = gnc_numeric_sub (balns->end_bal, *pnew_end_bal,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- balns->start_bal = gnc_numeric_add (balns->start_bal, adj,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- g_object_set (balns->acc, "start-balance", &balns->start_bal, NULL);
- qof_instance_decrease_editlevel (balns - acc);
- }
- if (!gnc_numeric_eq (*pnew_end_c_bal, balns->end_cleared_bal))
- {
- adj = gnc_numeric_sub (balns->end_cleared_bal, *pnew_end_c_bal,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- balns->start_cleared_bal = gnc_numeric_add (balns->start_cleared_bal, adj,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- g_object_set (balns->acc, "start-cleared-balance", &balns->start_cleared_bal,
- NULL);
- }
- if (!gnc_numeric_eq (*pnew_end_r_bal, balns->end_reconciled_bal))
- {
- adj = gnc_numeric_sub (balns->end_reconciled_bal, *pnew_end_r_bal,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- balns->start_reconciled_bal = gnc_numeric_add (balns->start_reconciled_bal,
- adj,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- g_object_set (balns->acc, "start-reconciled-balance",
- &balns->start_reconciled_bal, NULL);
- }
- qof_instance_decrease_editlevel (balns - acc);
- xaccAccountRecomputeBalance (balns->acc);
- g_free (pnew_end_bal);
- g_free (pnew_end_c_bal);
- g_free (pnew_end_r_bal);
- g_free (balns);
- }
- if (bal_list != NULL)
- {
- g_slist_free (bal_list);
- }
-
- xaccAccountCommitEdit (root);
- qof_event_resume ();
-#endif
}
+
/* ================================================================= */
/**
* Creates the transaction and split tables.
@@ -1206,89 +1134,6 @@ load_single_acct_balances (const GncSqlBackend* sql_be, GncSqlRow& row)
return bal;
}
-GSList*
-gnc_sql_get_account_balances_slist (GncSqlBackend* sql_be)
-{
-#if LOAD_TRANSACTIONS_AS_NEEDED
- gchar* buf;
- GSList* bal_slist = NULL;
-
- g_return_val_if_fail (sql_be != NULL, NULL);
-
- buf = g_strdup_printf ("SELECT account_guid, reconcile_state, sum(quantity_num) as quantity_num, quantity_denom FROM %s GROUP BY account_guid, reconcile_state, quantity_denom ORDER BY account_guid, reconcile_state",
- SPLIT_TABLE);
- auto stmt = sql_be->create_statement_from_sql(buf);
- g_assert (stmt != nullptr);
- g_free (buf);
- auto result = sql_be->execute_select_statement(stmt);
- acct_balances_t* bal = NULL;
-
- for (auto row : *result)
- {
- single_acct_balance_t* single_bal;
-
- // Get the next reconcile state balance and merge with other balances
- single_bal = load_single_acct_balances (sql_be, row);
- if (single_bal != NULL)
- {
- if (bal != NULL && bal->acct != single_bal->acct)
- {
- bal->cleared_balance = gnc_numeric_add (bal->cleared_balance,
- bal->reconciled_balance,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- bal->balance = gnc_numeric_add (bal->balance, bal->cleared_balance,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- bal_slist = g_slist_append (bal_slist, bal);
- bal = NULL;
- }
- if (bal == NULL)
- {
- bal = g_malloc ((gsize)sizeof (acct_balances_t));
- g_assert (bal != NULL);
-
- bal->acct = single_bal->acct;
- bal->balance = gnc_numeric_zero ();
- bal->cleared_balance = gnc_numeric_zero ();
- bal->reconciled_balance = gnc_numeric_zero ();
- }
- if (single_bal->reconcile_state == 'n')
- {
- bal->balance = gnc_numeric_add (bal->balance, single_bal->balance,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- }
- else if (single_bal->reconcile_state == 'c')
- {
- bal->cleared_balance = gnc_numeric_add (bal->cleared_balance,
- single_bal->balance,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- }
- else if (single_bal->reconcile_state == 'y')
- {
- bal->reconciled_balance = gnc_numeric_add (bal->reconciled_balance,
- single_bal->balance,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- }
- g_free (single_bal);
- }
- }
-
- // Add the final balance
- if (bal != NULL)
- {
- bal->cleared_balance = gnc_numeric_add (bal->cleared_balance,
- bal->reconciled_balance,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- bal->balance = gnc_numeric_add (bal->balance, bal->cleared_balance,
- GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
- bal_slist = g_slist_append (bal_slist, bal);
- }
-
- return bal_slist;
-#else
- return NULL;
-#endif
-}
-
/* ----------------------------------------------------------------- */
template<> void
GncSqlColumnTableEntryImpl<CT_TXREF>::load (const GncSqlBackend* sql_be,
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.h b/libgnucash/backend/sql/gnc-transaction-sql.h
index f1b11cd..78d35b2 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.h
+++ b/libgnucash/backend/sql/gnc-transaction-sql.h
@@ -69,13 +69,5 @@ typedef struct
gnc_numeric reconciled_balance;
} acct_balances_t;
-/**
- * Returns a list of acct_balances_t structures, one for each account which
- * has splits.
- *
- * @param sql_be SQL backend
- * @return GSList of acct_balances_t structures
- */
-GSList* gnc_sql_get_account_balances_slist (GncSqlBackend* sql_be);
#endif /* GNC_TRANSACTION_SQL_H */
commit e4d0ad9ddaecd18467433568b474f391d70496b9
Author: John Ralls <jralls at ceridwen.us>
Date: Sat Mar 24 17:55:03 2018 -0700
Reduce use of gnc_sql_slots_load_for_instancevec.
diff --git a/libgnucash/backend/sql/gnc-account-sql.cpp b/libgnucash/backend/sql/gnc-account-sql.cpp
index f0113ed..e926b0d 100644
--- a/libgnucash/backend/sql/gnc-account-sql.cpp
+++ b/libgnucash/backend/sql/gnc-account-sql.cpp
@@ -220,16 +220,14 @@ GncSqlAccountBackend::load_all (GncSqlBackend* sql_be)
pBook = sql_be->book();
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
for (auto row : *result)
load_single_account (sql_be, row, l_accounts_needing_parents);
- sql.str("");
- sql << "SELECT DISTINCT guid FROM " << TABLE_NAME;
- gnc_sql_slots_load_for_sql_subquery (sql_be, sql.str().c_str(),
+ sql = "SELECT DISTINCT guid FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
(BookLookupFn)xaccAccountLookup);
/* While there are items on the list of accounts needing parents,
diff --git a/libgnucash/backend/sql/gnc-bill-term-sql.cpp b/libgnucash/backend/sql/gnc-bill-term-sql.cpp
index ae813d8..31b4445 100644
--- a/libgnucash/backend/sql/gnc-bill-term-sql.cpp
+++ b/libgnucash/backend/sql/gnc-bill-term-sql.cpp
@@ -224,30 +224,35 @@ load_single_billterm (GncSqlBackend* sql_be, GncSqlRow& row,
return pBillTerm;
}
+/* Because gncBillTermLookup has the arguments backwards: */
+static inline GncBillTerm*
+gnc_billterm_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_BILLTERM, GncBillTerm);
+}
+
void
GncSqlBillTermBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
BillTermParentGuidVec l_billterms_needing_parents;
for (auto row : *result)
{
auto pBillTerm =
load_single_billterm (sql_be, row, l_billterms_needing_parents);
- if (pBillTerm != nullptr)
- instances.push_back(QOF_INSTANCE(pBillTerm));
}
delete result;
-
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_billterm_lookup);
/* While there are items on the list of billterms needing parents,
try to see if the parent has now been loaded. Theory says that if
diff --git a/libgnucash/backend/sql/gnc-budget-sql.cpp b/libgnucash/backend/sql/gnc-budget-sql.cpp
index 9ad5fba..826e56d 100644
--- a/libgnucash/backend/sql/gnc-budget-sql.cpp
+++ b/libgnucash/backend/sql/gnc-budget-sql.cpp
@@ -327,22 +327,19 @@ load_single_budget (GncSqlBackend* sql_be, GncSqlRow& row)
void
GncSqlBudgetBackend::load_all (GncSqlBackend* sql_be)
{
- InstanceVec instances;
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << BUDGET_TABLE;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " BUDGET_TABLE);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
for (auto row : *result)
- {
auto b = load_single_budget (sql_be, row);
- if (b != nullptr)
- instances.push_back(QOF_INSTANCE(b));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " BUDGET_TABLE;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_budget_lookup);
}
/* ================================================================= */
diff --git a/libgnucash/backend/sql/gnc-commodity-sql.cpp b/libgnucash/backend/sql/gnc-commodity-sql.cpp
index 451b55a..32689d3 100644
--- a/libgnucash/backend/sql/gnc-commodity-sql.cpp
+++ b/libgnucash/backend/sql/gnc-commodity-sql.cpp
@@ -142,9 +142,8 @@ GncSqlCommodityBackend::load_all (GncSqlBackend* sql_be)
gnc_commodity_table* pTable;
pTable = gnc_commodity_table_get_table (sql_be->book());
- std::stringstream sql;
- sql << "SELECT * FROM " << COMMODITIES_TABLE;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " COMMODITIES_TABLE);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
for (auto row : *result)
@@ -162,11 +161,12 @@ GncSqlCommodityBackend::load_all (GncSqlBackend* sql_be)
qof_instance_set_guid (QOF_INSTANCE (pCommodity), &guid);
}
- auto sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s", COMMODITIES_TABLE);
- gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
- (BookLookupFn)gnc_commodity_find_commodity_by_guid);
- g_free (sql);
}
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " COMMODITIES_TABLE;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_commodity_find_commodity_by_guid);
}
/* ================================================================= */
static gboolean
diff --git a/libgnucash/backend/sql/gnc-customer-sql.cpp b/libgnucash/backend/sql/gnc-customer-sql.cpp
index de713eb..d4c2bfa 100644
--- a/libgnucash/backend/sql/gnc-customer-sql.cpp
+++ b/libgnucash/backend/sql/gnc-customer-sql.cpp
@@ -117,26 +117,30 @@ load_single_customer (GncSqlBackend* sql_be, GncSqlRow& row)
return pCustomer;
}
+/* Because gncCustomerLookup has the arguments backwards: */
+static inline GncCustomer*
+gnc_customer_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_CUSTOMER, GncCustomer);
+}
+
void
GncSqlCustomerBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
for (auto row : *result)
- {
GncCustomer* pCustomer = load_single_customer (sql_be, row);
- if (pCustomer != nullptr)
- instances.push_back(QOF_INSTANCE(pCustomer));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_customer_lookup);
}
/* ================================================================= */
diff --git a/libgnucash/backend/sql/gnc-employee-sql.cpp b/libgnucash/backend/sql/gnc-employee-sql.cpp
index 79c6346..afa0e90 100644
--- a/libgnucash/backend/sql/gnc-employee-sql.cpp
+++ b/libgnucash/backend/sql/gnc-employee-sql.cpp
@@ -101,30 +101,33 @@ load_single_employee (GncSqlBackend* sql_be, GncSqlRow& row)
return pEmployee;
}
+/* Because gncCustomerLookup has the arguments backwards: */
+static inline GncEmployee*
+gnc_employee_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_EMPLOYEE, GncEmployee);
+}
void
GncSqlEmployeeBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
-
for (auto row : *result)
- {
GncEmployee* pEmployee = load_single_employee (sql_be, row);
- if (pEmployee != nullptr)
- instances.push_back(QOF_INSTANCE(pEmployee));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_employee_lookup);
}
+
/* ================================================================= */
void
GncSqlEmployeeBackend::create_tables (GncSqlBackend* sql_be)
diff --git a/libgnucash/backend/sql/gnc-entry-sql.cpp b/libgnucash/backend/sql/gnc-entry-sql.cpp
index 764ffa4..f68e210 100644
--- a/libgnucash/backend/sql/gnc-entry-sql.cpp
+++ b/libgnucash/backend/sql/gnc-entry-sql.cpp
@@ -186,26 +186,30 @@ load_single_entry (GncSqlBackend* sql_be, GncSqlRow& row)
return pEntry;
}
+/* Because gncEntryLookup has the arguments backwards: */
+static inline GncEntry*
+gnc_entry_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_ENTRY, GncEntry);
+}
+
void
GncSqlEntryBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
for (auto row : *result)
- {
GncEntry* pEntry = load_single_entry (sql_be, row);
- if (pEntry != nullptr)
- instances.push_back(QOF_INSTANCE(pEntry));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec(sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_entry_lookup);
}
/* ================================================================= */
diff --git a/libgnucash/backend/sql/gnc-invoice-sql.cpp b/libgnucash/backend/sql/gnc-invoice-sql.cpp
index e0cc87a..29a18fd 100644
--- a/libgnucash/backend/sql/gnc-invoice-sql.cpp
+++ b/libgnucash/backend/sql/gnc-invoice-sql.cpp
@@ -124,26 +124,30 @@ load_single_invoice (GncSqlBackend* sql_be, GncSqlRow& row)
return pInvoice;
}
+/* Because gncInvoiceLookup has the arguments backwards: */
+static inline GncInvoice*
+gnc_invoice_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_INVOICE, GncInvoice);
+}
+
void
GncSqlInvoiceBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
for (auto row : *result)
- {
GncInvoice* pInvoice = load_single_invoice (sql_be, row);
- if (pInvoice != nullptr)
- instances.push_back(QOF_INSTANCE(pInvoice));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_invoice_lookup);
}
/* ================================================================= */
diff --git a/libgnucash/backend/sql/gnc-job-sql.cpp b/libgnucash/backend/sql/gnc-job-sql.cpp
index dd4d9f5..48e17aa 100644
--- a/libgnucash/backend/sql/gnc-job-sql.cpp
+++ b/libgnucash/backend/sql/gnc-job-sql.cpp
@@ -96,26 +96,30 @@ load_single_job (GncSqlBackend* sql_be, GncSqlRow& row)
return pJob;
}
+/* Because gncJobLookup has the arguments backwards: */
+static inline GncJob*
+gnc_job_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_JOB, GncJob);
+}
+
void
GncSqlJobBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
for (auto row : *result)
- {
GncJob* pJob = load_single_job (sql_be, row);
- if (pJob != nullptr)
- instances.push_back(QOF_INSTANCE(pJob));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_job_lookup);
}
/* ================================================================= */
diff --git a/libgnucash/backend/sql/gnc-order-sql.cpp b/libgnucash/backend/sql/gnc-order-sql.cpp
index b870a22..50cde38 100644
--- a/libgnucash/backend/sql/gnc-order-sql.cpp
+++ b/libgnucash/backend/sql/gnc-order-sql.cpp
@@ -98,26 +98,30 @@ load_single_order (GncSqlBackend* sql_be, GncSqlRow& row)
return pOrder;
}
+/* Because gncOrderLookup has the arguments backwards: */
+static inline GncOrder*
+gnc_order_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_ORDER, GncOrder);
+}
+
void
GncSqlOrderBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
for (auto row : *result)
- {
GncOrder* pOrder = load_single_order (sql_be, row);
- if (pOrder != nullptr)
- instances.push_back(QOF_INSTANCE(pOrder));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_order_lookup);
}
/* ================================================================= */
diff --git a/libgnucash/backend/sql/gnc-price-sql.cpp b/libgnucash/backend/sql/gnc-price-sql.cpp
index 85c440c..6a12872 100644
--- a/libgnucash/backend/sql/gnc-price-sql.cpp
+++ b/libgnucash/backend/sql/gnc-price-sql.cpp
@@ -102,9 +102,8 @@ GncSqlPriceBackend::load_all (GncSqlBackend* sql_be)
pBook = sql_be->book();
pPriceDB = gnc_pricedb_get_db (pBook);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
if (stmt != nullptr)
{
auto result = sql_be->execute_select_statement(stmt);
@@ -112,7 +111,6 @@ GncSqlPriceBackend::load_all (GncSqlBackend* sql_be)
return;
GNCPrice* pPrice;
- gchar* sql;
gnc_pricedb_set_bulk_update (pPriceDB, TRUE);
for (auto row : *result)
@@ -126,10 +124,11 @@ GncSqlPriceBackend::load_all (GncSqlBackend* sql_be)
}
}
gnc_pricedb_set_bulk_update (pPriceDB, FALSE);
-
- sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s", TABLE_NAME);
- gnc_sql_slots_load_for_sql_subquery (sql_be, sql, (BookLookupFn)gnc_price_lookup);
- g_free (sql);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_price_lookup);
}
}
diff --git a/libgnucash/backend/sql/gnc-schedxaction-sql.cpp b/libgnucash/backend/sql/gnc-schedxaction-sql.cpp
index f7909fd..c883a92 100644
--- a/libgnucash/backend/sql/gnc-schedxaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-schedxaction-sql.cpp
@@ -115,18 +115,23 @@ load_single_sx (GncSqlBackend* sql_be, GncSqlRow& row)
return pSx;
}
+/* Because SchedXaction doesn't define a lookup function: */
+static inline SchedXaction*
+gnc_sx_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_SCHEDXACTION, SchedXaction);
+}
+
void
GncSqlSchedXactionBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << SCHEDXACTION_TABLE;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
- if (stmt == NULL) return;
+ std::string sql("SELECT * FROM " SCHEDXACTION_TABLE);
+ auto stmt = sql_be->create_statement_from_sql(sql);
+ if (stmt == nullptr) return;
auto result = sql_be->execute_select_statement(stmt);
SchedXactions* sxes;
- InstanceVec instances;
sxes = gnc_book_get_schedxactions (sql_be->book());
for (auto row : *result)
@@ -135,14 +140,13 @@ GncSqlSchedXactionBackend::load_all (GncSqlBackend* sql_be)
sx = load_single_sx (sql_be, row);
if (sx != nullptr)
- {
gnc_sxes_add_sx (sxes, sx);
- instances.push_back(QOF_INSTANCE(sx));
- }
}
-
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " SCHEDXACTION_TABLE;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_sx_lookup);
}
diff --git a/libgnucash/backend/sql/gnc-slots-sql.cpp b/libgnucash/backend/sql/gnc-slots-sql.cpp
index ca26617..ab2d6e4 100644
--- a/libgnucash/backend/sql/gnc-slots-sql.cpp
+++ b/libgnucash/backend/sql/gnc-slots-sql.cpp
@@ -766,19 +766,15 @@ gnc_sql_slots_load (GncSqlBackend* sql_be, QofInstance* inst)
static void
slots_load_info (slot_info_t* pInfo)
{
- gchar guid_buf[GUID_ENCODING_LENGTH + 1];
-
g_return_if_fail (pInfo != NULL);
g_return_if_fail (pInfo->be != NULL);
g_return_if_fail (pInfo->guid != NULL);
g_return_if_fail (pInfo->pKvpFrame != NULL);
- (void)guid_to_string_buff (pInfo->guid, guid_buf);
-
- std::stringstream buf;
- buf << "SELECT * FROM " << TABLE_NAME <<
- " WHERE obj_guid='" << guid_buf << "'";
- auto stmt = pInfo->be->create_statement_from_sql (buf.str());
+ gnc::GUID guid(*pInfo->guid);
+ std::string sql("SELECT * FROM " TABLE_NAME " WHERE obj_guid='");
+ sql += guid.to_string() + "'";
+ auto stmt = pInfo->be->create_statement_from_sql(sql);
if (stmt != nullptr)
{
auto result = pInfo->be->execute_select_statement (stmt);
@@ -897,29 +893,25 @@ load_slot_for_book_object (GncSqlBackend* sql_be, GncSqlRow& row,
* @param lookup_fn Lookup function
*/
void gnc_sql_slots_load_for_sql_subquery (GncSqlBackend* sql_be,
- const gchar* subquery,
+ const std::string subquery,
BookLookupFn lookup_fn)
{
- gchar* sql;
-
g_return_if_fail (sql_be != NULL);
// Ignore empty subquery
- if (subquery == NULL) return;
+ if (subquery.empty()) return;
- sql = g_strdup_printf ("SELECT * FROM %s WHERE %s IN (%s)",
- TABLE_NAME, obj_guid_col_table[0]->name(),
- subquery);
+ std::string pkey(obj_guid_col_table[0]->name());
+ std::string sql("SELECT * FROM " TABLE_NAME " WHERE ");
+ sql += pkey + " IN (" + subquery + ")";
// Execute the query and load the slots
auto stmt = sql_be->create_statement_from_sql(sql);
if (stmt == nullptr)
{
- PERR ("stmt == NULL, SQL = '%s'\n", sql);
- g_free (sql);
+ PERR ("stmt == NULL, SQL = '%s'\n", sql.c_str());
return;
}
- g_free (sql);
auto result = sql_be->execute_select_statement(stmt);
for (auto row : *result)
load_slot_for_book_object (sql_be, row, lookup_fn);
diff --git a/libgnucash/backend/sql/gnc-slots-sql.h b/libgnucash/backend/sql/gnc-slots-sql.h
index 56ef2e5..0cdf3a6 100644
--- a/libgnucash/backend/sql/gnc-slots-sql.h
+++ b/libgnucash/backend/sql/gnc-slots-sql.h
@@ -100,7 +100,7 @@ typedef QofInstance* (*BookLookupFn) (const GncGUID* guid,
* @param lookup_fn Lookup function to get the right object from the book
*/
void gnc_sql_slots_load_for_sql_subquery (GncSqlBackend* sql_be,
- const gchar* subquery,
+ const std::string subquery,
BookLookupFn lookup_fn);
void gnc_sql_init_slots_handler (void);
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.cpp b/libgnucash/backend/sql/gnc-transaction-sql.cpp
index c8ddd1e..8f92178 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-transaction-sql.cpp
@@ -264,17 +264,13 @@ load_splits_for_tx_list (GncSqlBackend* sql_be, InstanceVec& transactions)
// Execute the query and load the splits
auto stmt = sql_be->create_statement_from_sql(sql.str());
auto result = sql_be->execute_select_statement (stmt);
- InstanceVec instances;
for (auto row : *result)
- {
Split* s = load_single_split (sql_be, row);
- if (s != nullptr)
- instances.push_back(QOF_INSTANCE(s));
- }
-
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ sql = "SELECT DISTINCT ";
+ sql += spkey + " FROM " SPLIT_TABLE " WHERE " + sskey + " IN " + selector;
+ gnc_sql_slots_load_for_sql_subquery(sql_be, sql,
+ (BookLookupFn)xaccSplitLookup);
}
static Transaction*
diff --git a/libgnucash/backend/sql/gnc-vendor-sql.cpp b/libgnucash/backend/sql/gnc-vendor-sql.cpp
index ae60b3a..a73c29c 100644
--- a/libgnucash/backend/sql/gnc-vendor-sql.cpp
+++ b/libgnucash/backend/sql/gnc-vendor-sql.cpp
@@ -106,26 +106,30 @@ load_single_vendor (GncSqlBackend* sql_be, GncSqlRow& row)
return pVendor;
}
+/* Because gncVendorLookup has the arguments backwards: */
+static inline GncVendor*
+gnc_vendor_lookup (const GncGUID *guid, const QofBook *book)
+{
+ QOF_BOOK_RETURN_ENTITY(book, guid, GNC_ID_VENDOR, GncVendor);
+}
+
void
GncSqlVendorBackend::load_all (GncSqlBackend* sql_be)
{
g_return_if_fail (sql_be != NULL);
- std::stringstream sql;
- sql << "SELECT * FROM " << TABLE_NAME;
- auto stmt = sql_be->create_statement_from_sql(sql.str());
+ std::string sql("SELECT * FROM " TABLE_NAME);
+ auto stmt = sql_be->create_statement_from_sql(sql);
auto result = sql_be->execute_select_statement(stmt);
- InstanceVec instances;
for (auto row : *result)
- {
GncVendor* pVendor = load_single_vendor (sql_be, row);
- if (pVendor != nullptr)
- instances.push_back(QOF_INSTANCE(pVendor));
- }
- if (!instances.empty())
- gnc_sql_slots_load_for_instancevec (sql_be, instances);
+ std::string pkey(col_table[0]->name());
+ sql = "SELECT DISTINCT ";
+ sql += pkey + " FROM " TABLE_NAME;
+ gnc_sql_slots_load_for_sql_subquery (sql_be, sql,
+ (BookLookupFn)gnc_vendor_lookup);
}
/* ================================================================= */
Summary of changes:
libgnucash/app-utils/gnc-ui-util.c | 4 +-
libgnucash/backend/sql/gnc-account-sql.cpp | 31 +-
libgnucash/backend/sql/gnc-bill-term-sql.cpp | 23 +-
libgnucash/backend/sql/gnc-budget-sql.cpp | 17 +-
libgnucash/backend/sql/gnc-commodity-sql.cpp | 14 +-
libgnucash/backend/sql/gnc-customer-sql.cpp | 24 +-
libgnucash/backend/sql/gnc-employee-sql.cpp | 25 +-
libgnucash/backend/sql/gnc-entry-sql.cpp | 24 +-
libgnucash/backend/sql/gnc-invoice-sql.cpp | 24 +-
libgnucash/backend/sql/gnc-job-sql.cpp | 24 +-
libgnucash/backend/sql/gnc-order-sql.cpp | 24 +-
libgnucash/backend/sql/gnc-price-sql.cpp | 15 +-
libgnucash/backend/sql/gnc-schedxaction-sql.cpp | 26 +-
libgnucash/backend/sql/gnc-slots-sql.cpp | 66 +---
libgnucash/backend/sql/gnc-slots-sql.h | 13 +-
libgnucash/backend/sql/gnc-sql-backend.cpp | 12 +-
libgnucash/backend/sql/gnc-transaction-sql.cpp | 468 +++---------------------
libgnucash/backend/sql/gnc-transaction-sql.h | 8 -
libgnucash/backend/sql/gnc-vendor-sql.cpp | 24 +-
libgnucash/core-utils/gnc-guile-utils.c | 2 +-
libgnucash/engine/TransLog.c | 2 +-
21 files changed, 229 insertions(+), 641 deletions(-)
More information about the gnucash-changes
mailing list