TEST_F(ImapPlainTest, AddAccount)
{
// prevent the embedded beginedit/commitedit from doing anything
    qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account(t_imap, "foo", "bar", t_expense_account1);
    gnc_account_imap_add_account(t_imap, "baz", "waldo", t_expense_account2);
    gnc_account_imap_add_account(t_imap, NULL, "pepper", t_expense_account1);
    gnc_account_imap_add_account(t_imap, NULL, "salt", t_expense_account2);
    EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account)));
    EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_mark_clean(QOF_INSTANCE(t_bank_account));
    gnc_account_imap_add_account(t_imap, NULL, NULL, t_expense_account2);
    EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    gnc_account_imap_add_account(t_imap, "pork", "sausage", NULL);
    EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account)));
    qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account));

    auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account));
    auto value = root->get_slot({IMAP_FRAME, "foo", "bar"});
    auto check_account = [this](KvpValue* v) {
        return xaccAccountLookup(v->get<GncGUID*>(), this->t_imap->book); };
    EXPECT_EQ(t_expense_account1, check_account(value));
    value = root->get_slot({IMAP_FRAME, "baz", "waldo"});
    EXPECT_EQ(t_expense_account2, check_account(value));
    value = root->get_slot({IMAP_FRAME, "pepper"});
    EXPECT_EQ(t_expense_account1, check_account(value));
    value = root->get_slot({IMAP_FRAME, "salt"});
    EXPECT_EQ(t_expense_account2, check_account(value));
    value = root->get_slot({IMAP_FRAME, "pork", "sausage"});
    EXPECT_EQ(nullptr, value);
}
Exemple #2
0
static gboolean
spl_account_handler(xmlNodePtr node, gpointer data)
{
    struct split_pdata *pdata = data;
    GncGUID *id = dom_tree_to_guid(node);
    Account *account;

    g_return_val_if_fail(id, FALSE);

    account = xaccAccountLookup (id, pdata->book);
    if (!account && gnc_transaction_xml_v2_testing &&
            !guid_equal (id, guid_null ()))
    {
        account = xaccMallocAccount (pdata->book);
        xaccAccountSetGUID (account, id);
        xaccAccountSetCommoditySCU (account,
                                    xaccSplitGetAmount (pdata->split).denom);
    }

    xaccAccountInsertSplit (account, pdata->split);

    g_free(id);

    return TRUE;
}
/* Return the string entry for transfer column when template */
const char *
gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
{
    static char *name = NULL;

    kvp_frame *kvpf;

    if (!split)
        return NULL;

    kvpf = xaccSplitGetSlots (split);

    g_free (name);

    if (kvpf)
    {
        Account *account;
        GncGUID *guid;

        guid = kvp_value_get_guid(
                   kvp_frame_get_slot_path (kvpf, "sched-xaction", "account", NULL));

        account = xaccAccountLookup (guid, gnc_get_current_book ());

        name = account ? gnc_get_account_name_for_register (account) : NULL;
    }
    else
        name = NULL;

    return name;
}
static void
gnc_template_register_save_xfrm_cell (BasicCell * cell,
                                      gpointer save_data,
                                      gpointer user_data)
{
    SRSaveData *sd = save_data;
    SplitRegister *reg = user_data;
    SRInfo *info = gnc_split_register_get_info (reg);
    Account *template_acc;
    const GncGUID *acctGUID;
    kvp_frame *kvpf;
    Account *acct;

    g_return_if_fail (gnc_basic_cell_has_name (cell, XFRM_CELL));

    /* save the account GncGUID into the kvp_data. */
    acct = gnc_split_register_get_account (reg, XFRM_CELL);
    if (!acct)
    {
        PERR ("unknown account");
        return;
    }

    acctGUID = xaccAccountGetGUID (acct);
    kvpf = xaccSplitGetSlots (sd->split);
    kvp_frame_set_slot_path (kvpf, kvp_value_new_guid(acctGUID),
                             GNC_SX_ID, GNC_SX_ACCOUNT, NULL);

    template_acc = xaccAccountLookup (&info->template_account,
                                      gnc_get_current_book ());

    /* set the actual account to the fake account for these templates */
    xaccAccountInsertSplit (template_acc, sd->split);
    qof_instance_set_dirty (QOF_INSTANCE (sd->split));
}
Account *
gnc_ledger_display_leader (GNCLedgerDisplay *ld)
{
    if (!ld)
        return NULL;

    return xaccAccountLookup (&ld->leader, gnc_get_current_book ());
}
Exemple #6
0
template<> void
GncSqlColumnTableEntryImpl<CT_ACCOUNTREF>::load (const GncSqlBackend* sql_be,
                                                 GncSqlRow& row,
                                                 QofIdTypeConst obj_name,
                                                 gpointer pObject) const noexcept
{
    load_from_guid_ref(row, obj_name, pObject,
                       [sql_be](GncGUID* g){
                           return xaccAccountLookup(g, sql_be->book());
                       });
}
static void
set_acct_bal_account_from_guid( gpointer pObject, gpointer pValue )
{
    single_acct_balance_t* bal = (single_acct_balance_t*)pObject;
    const GncGUID* guid = (const GncGUID*)pValue;

    g_return_if_fail( pObject != NULL );
    g_return_if_fail( pValue != NULL );

    bal->acct = xaccAccountLookup( guid, bal->be->book );
}
Exemple #8
0
static void
gnc_payment_dialog_owner_changed (PaymentWindow *pw)
{
    Account *last_acct = NULL;
    GncGUID *guid = NULL;
    GncOwner *owner = &pw->owner;

    /* If the owner changed, the initial invoice is no longer valid */
    pw->invoice = NULL;

    /* Now handle the account tree */
    qof_instance_get (qofOwnerGetOwner (owner),
		      "payment-last-account", &guid,
		      NULL);

    /* refresh the post and acc available accounts, but cleanup first */
    if (pw->acct_types)
    {
        g_list_free(pw->acct_types);
        pw->acct_types = NULL;
    }

    if (pw->acct_commodities)
    {
        g_list_free(pw->acct_commodities);
        pw->acct_commodities = NULL;
    }

    pw->acct_types = gncOwnerGetAccountTypesList(owner);
    if (gncOwnerIsValid(owner))
        pw->acct_commodities = gncOwnerGetCommoditiesList (owner);
    pw->post_acct = gnc_account_select_combo_fill (pw->post_combo, pw->book, pw->acct_types, pw->acct_commodities);

    /* Update list of documents and pre-payments */
    gnc_payment_window_fill_docs_list (pw);

    if (guid)
    {
        last_acct = xaccAccountLookup(guid, pw->book);
    }

    /* Set the last-used transfer account, but only if we didn't
     * create this dialog from a pre-existing transaction. */
    if (last_acct && !gnc_payment_dialog_has_pre_existing_txn(pw))
    {
        gnc_tree_view_account_set_selected_account(GNC_TREE_VIEW_ACCOUNT(pw->acct_tree),
                last_acct);
    }
}
static gboolean
ttentry_acct_handler (xmlNodePtr node, gpointer ttentry_pdata)
{
    struct ttentry_pdata *pdata = ttentry_pdata;
    GncGUID *guid;
    Account * acc;

    guid = dom_tree_to_guid (node);
    g_return_val_if_fail (guid, FALSE);
    acc = xaccAccountLookup (guid, pdata->book);
    g_free (guid);
    g_return_val_if_fail (acc, FALSE);

    gncTaxTableEntrySetAccount (pdata->ttentry, acc);
    return TRUE;
}
Exemple #10
0
static gboolean
invoice_postacc_handler (xmlNodePtr node, gpointer invoice_pdata)
{
    struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
    GncGUID* guid;
    Account* acc;

    guid = dom_tree_to_guid (node);
    g_return_val_if_fail (guid, FALSE);
    acc = xaccAccountLookup (guid, pdata->book);
    g_free (guid);
    g_return_val_if_fail (acc, FALSE);

    gncInvoiceSetPostedAcc (pdata->invoice, acc);
    return TRUE;
}
Exemple #11
0
Account *gnc_ofx_kvp_get_assoc_account(const Account* investment_account)
{
    kvp_frame * acc_frame;
    kvp_value * kvp_val;
    Account *result = NULL;

    g_assert(investment_account);

    acc_frame = xaccAccountGetSlots(investment_account);
    kvp_val = kvp_frame_get_slot(acc_frame, KEY_ASSOC_INCOME_ACCOUNT);
    if (kvp_val != NULL)
    {
        result = xaccAccountLookup(kvp_value_get_guid(kvp_val),
                                   gnc_account_get_book(investment_account));
    }
    return result;
}
static gboolean
_get_template_split_account(GncSxInstance *instance, Split *template_split, Account **split_acct, GList **creation_errors)
{
    GncGUID *acct_guid;
    kvp_frame *split_kvpf;
    kvp_value *kvp_val;

    split_kvpf = xaccSplitGetSlots(template_split);
    /* contains the guid of the split's actual account. */
    kvp_val = kvp_frame_get_slot_path(split_kvpf,
                                      GNC_SX_ID,
                                      GNC_SX_ACCOUNT,
                                      NULL);
    if (kvp_val == NULL)
    {
        GString *err = g_string_new("");
        g_string_printf(err, "Null account kvp value for SX [%s], cancelling creation.",
                        xaccSchedXactionGetName(instance->parent->sx));
        g_critical("%s", err->str);
        if (creation_errors != NULL)
            *creation_errors = g_list_append(*creation_errors, err);
        else
            g_string_free(err, TRUE);
        return FALSE;
    }
    acct_guid = kvp_value_get_guid( kvp_val );
    *split_acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
    if (*split_acct == NULL)
    {
        char guid_str[GUID_ENCODING_LENGTH+1];
        GString *err;
        guid_to_string_buff((const GncGUID*)acct_guid, guid_str);
        err = g_string_new("");
        g_string_printf(err, "Unknown account for guid [%s], cancelling SX [%s] creation.",
                        guid_str, xaccSchedXactionGetName(instance->parent->sx));
        g_critical("%s", err->str);
        if (creation_errors != NULL)
            *creation_errors = g_list_append(*creation_errors, err);
        else
            g_string_free(err, TRUE);
        return FALSE;
    }

    return TRUE;
}
static gboolean
employee_ccard_handler (xmlNodePtr node, gpointer employee_pdata)
{
    struct employee_pdata *pdata = employee_pdata;
    GncGUID *guid;
    Account *ccard_acc;

    guid = dom_tree_to_guid(node);
    g_return_val_if_fail(guid, FALSE);

    ccard_acc = xaccAccountLookup (guid, pdata->book);
    g_free(guid);

    g_return_val_if_fail (ccard_acc, FALSE);
    gncEmployeeSetCCard (pdata->employee, ccard_acc);

    return TRUE;
}
Exemple #14
0
static inline gboolean
set_account(xmlNodePtr node, struct entry_pdata *pdata,
            void (*func)(GncEntry *entry, Account *acc))
{
    GncGUID *guid;
    Account * acc;

    guid = dom_tree_to_guid (node);
    g_return_val_if_fail (guid, FALSE);
    acc = xaccAccountLookup (guid, pdata->book);
    g_free (guid);
    g_return_val_if_fail (acc, FALSE);

    if (func)
        func (pdata->entry, acc);
    else
        pdata->acc = acc;
    return TRUE;
}
Exemple #15
0
static
gboolean
sx_templ_acct_handler( xmlNodePtr node, gpointer sx_pdata)
{
    struct sx_pdata *pdata = sx_pdata;
    SchedXaction *sx = pdata->sx;
    GncGUID *templ_acct_guid = dom_tree_to_guid(node);
    Account *account;

    if (!templ_acct_guid)
    {
        return FALSE;
    }

    account = xaccAccountLookup(templ_acct_guid, pdata->book);
    sx_set_template_account(sx, account);
    g_free(templ_acct_guid);

    return TRUE;
}
/* Return the string entry for transfer column when template */
const char *
gnc_tree_util_split_reg_template_get_transfer_entry (Split *split)
{
    static char *name = NULL;
    Account *account;
    GncGUID *guid = NULL;

    /* Callers either g_strdup the return or use it as a temp for comparison,
       so we keep our static ref and free it on every call. */
    g_free (name);

    if (!split)
        return NULL;
    qof_instance_get (QOF_INSTANCE (split),
		      "sx-account", &guid,
		      NULL);
    account = xaccAccountLookup (guid, gnc_get_current_book ());
    name = account ? gnc_get_account_name_for_register (account) : NULL;

    return name;
}
Exemple #17
0
static  Account*
load_single_account (GncSqlBackend* be, GncSqlRow* row,
                     GList** l_accounts_needing_parents)
{
    const GncGUID* guid;
    Account* pAccount = NULL;

    g_return_val_if_fail (be != NULL, NULL);
    g_return_val_if_fail (row != NULL, NULL);
    g_return_val_if_fail (l_accounts_needing_parents != NULL, NULL);

    guid = gnc_sql_load_guid (be, row);
    if (guid != NULL)
    {
        pAccount = xaccAccountLookup (guid, be->book);
    }
    if (pAccount == NULL)
    {
        pAccount = xaccMallocAccount (be->book);
    }
    xaccAccountBeginEdit (pAccount);
    gnc_sql_load_object (be, row, GNC_ID_ACCOUNT, pAccount, col_table);
    xaccAccountCommitEdit (pAccount);

    /* If we don't have a parent and this isn't the root account, it might be because the parent
       account hasn't been loaded yet.  Remember the account and its parent guid for later. */
    if (gnc_account_get_parent (pAccount) == NULL
        && pAccount != gnc_book_get_root_account (be->book))
    {
        account_parent_guid_struct* s = static_cast<decltype (s)> (
                                            g_malloc (sizeof (account_parent_guid_struct)));
        g_assert (s != NULL);

        s->pAccount = pAccount;
        gnc_sql_load_object (be, row, GNC_ID_ACCOUNT, s, parent_col_table);
        *l_accounts_needing_parents = g_list_prepend (*l_accounts_needing_parents, s);
    }

    return pAccount;
}
Exemple #18
0
/* ================================================================= */
static void
load_account_guid (const GncSqlBackend* be, GncSqlRow* row,
                   QofSetterFunc setter, gpointer pObject,
                   const GncSqlColumnTableEntry* table_row)
{
    const GValue* val;
    GncGUID guid;
    Account* account = NULL;

    g_return_if_fail (be != NULL);
    g_return_if_fail (row != NULL);
    g_return_if_fail (pObject != NULL);
    g_return_if_fail (table_row != NULL);

    val = gnc_sql_row_get_value_at_col_name (row, table_row->col_name);
    if (val != NULL && G_VALUE_HOLDS_STRING (val) &&
        g_value_get_string (val) != NULL)
    {
        (void)string_to_guid (g_value_get_string (val), &guid);
        account = xaccAccountLookup (&guid, be->book);
        if (account != NULL)
        {
            if (table_row->gobj_param_name != NULL)
            {
                qof_instance_increase_editlevel (pObject);
                g_object_set (pObject, table_row->gobj_param_name, account, NULL);
                qof_instance_decrease_editlevel (pObject);
            }
            else
            {
                g_return_if_fail (setter != NULL);
                (*setter) (pObject, (const gpointer)account);
            }
        }
        else
        {
            PWARN ("Account ref '%s' not found", g_value_get_string (val));
        }
    }
}
Exemple #19
0
static void
set_parent (gpointer pObject,  gpointer pValue)
{
    Account* pAccount;
    QofBook* pBook;
    GncGUID* guid = (GncGUID*)pValue;
    Account* pParent;

    g_return_if_fail (pObject != NULL);
    g_return_if_fail (GNC_IS_ACCOUNT (pObject));

    pAccount = GNC_ACCOUNT (pObject);
    pBook = qof_instance_get_book (QOF_INSTANCE (pAccount));
    if (guid != NULL)
    {
        pParent = xaccAccountLookup (guid, pBook);
        if (pParent != NULL)
        {
            gnc_account_append_child (pParent, pAccount);
        }
    }
}
Exemple #20
0
static  Account*
load_single_account (GncSqlBackend* sql_be, GncSqlRow& row,
                     ParentGuidVec& l_accounts_needing_parents)
{
    const GncGUID* guid;
    Account* pAccount = NULL;

    g_return_val_if_fail (sql_be != NULL, NULL);

    guid = gnc_sql_load_guid (sql_be, row);
    if (guid != NULL)
    {
        pAccount = xaccAccountLookup (guid, sql_be->book());
    }
    if (pAccount == NULL)
    {
        pAccount = xaccMallocAccount (sql_be->book());
    }
    xaccAccountBeginEdit (pAccount);
    gnc_sql_load_object (sql_be, row, GNC_ID_ACCOUNT, pAccount, col_table);
    xaccAccountCommitEdit (pAccount);

    /* If we don't have a parent and this isn't the root account, it might be
       because the parent account hasn't been loaded yet.  Remember the account
       and its parent guid for later. */
    if (gnc_account_get_parent (pAccount) == NULL
        && pAccount != gnc_book_get_root_account (sql_be->book()))
    {
        auto s = new ParentGuid;

        s->pAccount = pAccount;
        gnc_sql_load_object (sql_be, row, GNC_ID_ACCOUNT, s, parent_col_table);
        l_accounts_needing_parents.push_back(s);
    }

    return pAccount;
}
static gint
_get_vars_helper(Transaction *txn, void *var_hash_data)
{
    GHashTable *var_hash = (GHashTable*)var_hash_data;
    GList *split_list;
    kvp_frame *kvpf;
    kvp_value *kvp_val;
    Split *s;
    char *str;
    gnc_commodity *first_cmdty = NULL;

    split_list = xaccTransGetSplitList(txn);
    if (split_list == NULL)
    {
        return 1;
    }

    for ( ; split_list; split_list = split_list->next)
    {
        gnc_commodity *split_cmdty = NULL;
        GncGUID *acct_guid;
        Account *acct;

        s = (Split*)split_list->data;
        kvpf = xaccSplitGetSlots(s);
        kvp_val = kvp_frame_get_slot_path(kvpf,
                                          GNC_SX_ID,
                                          GNC_SX_ACCOUNT,
                                          NULL);
        acct_guid = kvp_value_get_guid(kvp_val);
        acct = xaccAccountLookup(acct_guid, gnc_get_current_book());
        split_cmdty = xaccAccountGetCommodity(acct);
        if (first_cmdty == NULL)
        {
            first_cmdty = split_cmdty;
        }

        if (! gnc_commodity_equal(split_cmdty, first_cmdty))
        {
            GncSxVariable *var;
            GString *var_name;
            const gchar *split_mnemonic, *first_mnemonic;

            var_name = g_string_sized_new(16);
            split_mnemonic = gnc_commodity_get_mnemonic(split_cmdty);
            first_mnemonic = gnc_commodity_get_mnemonic(first_cmdty);
            g_string_printf(var_name, "%s -> %s",
                            split_mnemonic ? split_mnemonic : "(null)",
                            first_mnemonic ? first_mnemonic : "(null)");
            var = gnc_sx_variable_new(g_strdup(var_name->str));
            g_hash_table_insert(var_hash, g_strdup(var->name), var);
            g_string_free(var_name, TRUE);
        }

        // existing... ------------------------------------------
        kvp_val = kvp_frame_get_slot_path(kvpf,
                                          GNC_SX_ID,
                                          GNC_SX_CREDIT_FORMULA,
                                          NULL);
        if (kvp_val != NULL)
        {
            str = kvp_value_get_string(kvp_val);
            if (str && strlen(str) != 0)
            {
                gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
            }
        }

        kvp_val = kvp_frame_get_slot_path(kvpf,
                                          GNC_SX_ID,
                                          GNC_SX_DEBIT_FORMULA,
                                          NULL);
        if (kvp_val != NULL)
        {
            str = kvp_value_get_string(kvp_val);
            if (str && strlen(str) != 0)
            {
                gnc_sx_parse_vars_from_formula(str, var_hash, NULL);
            }
        }
    }

    return 0;
}
Exemple #22
0
static void
load_all_accounts (GncSqlBackend* be)
{
    GncSqlStatement* stmt = NULL;
    GncSqlResult* result;
    QofBook* pBook;
    GList* l_accounts_needing_parents = NULL;
    GSList* bal_slist;
    GSList* bal;

    g_return_if_fail (be != NULL);

    ENTER ("");

    pBook = be->book;

    stmt = gnc_sql_create_select_statement (be, TABLE_NAME);
    if (stmt == NULL)
    {
        LEAVE ("stmt == NULL");
        return;
    }
    result = gnc_sql_execute_select_statement (be, stmt);
    gnc_sql_statement_dispose (stmt);
    if (result != NULL)
    {
        GncSqlRow* row = gnc_sql_result_get_first_row (result);
        gchar* sql;

        while (row != NULL)
        {
            load_single_account (be, row, &l_accounts_needing_parents);
            row = gnc_sql_result_get_next_row (result);
        }
        gnc_sql_result_dispose (result);

        sql = g_strdup_printf ("SELECT DISTINCT guid FROM %s", TABLE_NAME);
        gnc_sql_slots_load_for_sql_subquery (be, sql, (BookLookupFn)xaccAccountLookup);
        g_free (sql);

        /* While there are items on the list of accounts needing parents,
           try to see if the parent has now been loaded.  Theory says that if
           items are removed from the front and added to the back if the
           parent is still not available, then eventually, the list will
           shrink to size 0. */
        if (l_accounts_needing_parents != NULL)
        {
            gboolean progress_made = TRUE;
            Account* root;
            Account* pParent;
            GList* elem;

            while (progress_made)
            {
                progress_made = FALSE;
                for (elem = l_accounts_needing_parents; elem != NULL;)
                {
                    account_parent_guid_struct* s = (account_parent_guid_struct*)elem->data;
                    pParent = xaccAccountLookup (&s->guid, be->book);
                    if (pParent != NULL)
                    {
                        GList* next_elem;

                        gnc_account_append_child (pParent, s->pAccount);
                        next_elem = g_list_next (elem);
                        l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents,
                                                                         elem);
                        g_free (s);
                        elem = next_elem;
                        progress_made = TRUE;
                    }
                    else
                    {
                        /* Can't be up in the for loop because the 'then' clause reads inside a node freed
                           by g_list_delete_link(). */
                        elem = g_list_next (elem);
                    }
                }
            }

            /* Any non-ROOT accounts left over must be parented by the root account */
            root = gnc_book_get_root_account (pBook);
            while (l_accounts_needing_parents != NULL)
            {
                account_parent_guid_struct* s = (account_parent_guid_struct*)
                                                l_accounts_needing_parents->data;
                if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT)
                {
                    gnc_account_append_child (root, s->pAccount);
                }
                g_free (s);
                l_accounts_needing_parents = g_list_delete_link (l_accounts_needing_parents,
                                                                 l_accounts_needing_parents);
            }
        }

        /* Load starting balances */
        bal_slist = gnc_sql_get_account_balances_slist (be);
        for (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);
        }
    }

    LEAVE ("");
}
Exemple #23
0
void
GncSqlAccountBackend::load_all (GncSqlBackend* sql_be)
{
    QofBook* pBook;
    ParentGuidVec l_accounts_needing_parents;
    g_return_if_fail (sql_be != NULL);

    ENTER ("");

    pBook = sql_be->book();

    std::stringstream sql;
    sql << "SELECT * FROM " << TABLE_NAME;
    auto stmt = sql_be->create_statement_from_sql(sql.str());
    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(),
                                         (BookLookupFn)xaccAccountLookup);

    /* While there are items on the list of accounts needing parents,
       try to see if the parent has now been loaded.  Theory says that if
       items are removed from the front and added to the back if the
       parent is still not available, then eventually, the list will
       shrink to size 0. */
    if (!l_accounts_needing_parents.empty())
    {
        auto progress_made = true;
        std::reverse(l_accounts_needing_parents.begin(),
                     l_accounts_needing_parents.end());
	auto end = l_accounts_needing_parents.end();
        while (progress_made)
        {
            progress_made = false;
            end = std::remove_if(l_accounts_needing_parents.begin(), end,
				 [&](ParentGuidPtr s)
				 {
				     auto pParent = xaccAccountLookup (&s->guid,
								       sql_be->book());
				     if (pParent != nullptr)
				     {
					 gnc_account_append_child (pParent,
								   s->pAccount);
					 progress_made = true;
					 delete s;
					 return true;
				     }
				     return false;
				 });
        }

        /* Any non-ROOT accounts left over must be parented by the root account */
        auto root = gnc_book_get_root_account (pBook);
        end = std::remove_if(l_accounts_needing_parents.begin(), end,
			     [&](ParentGuidPtr s)
			     {
				 if (xaccAccountGetType (s->pAccount) != ACCT_TYPE_ROOT)
				     gnc_account_append_child (root, s->pAccount);
				 delete s;
				 return true;
			     });
    }

#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 ("");
}