Exemplo n.º 1
0
/* ================================================================= */
static gboolean
save_employee (GncSqlBackend* be, QofInstance* inst)
{
    GncEmployee* emp;
    const GncGUID* guid;
    E_DB_OPERATION op;
    gboolean is_infant;
    gboolean is_ok = TRUE;

    g_return_val_if_fail (inst != NULL, FALSE);
    g_return_val_if_fail (GNC_IS_EMPLOYEE (inst), FALSE);
    g_return_val_if_fail (be != NULL, FALSE);

    emp = GNC_EMPLOYEE (inst);

    is_infant = qof_instance_get_infant (inst);
    if (qof_instance_get_destroying (inst))
    {
        op = OP_DB_DELETE;
    }
    else if (be->is_pristine_db || is_infant)
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }
    if (op != OP_DB_DELETE)
    {
        // Ensure the commodity is in the db
        is_ok = gnc_sql_save_commodity (be, gncEmployeeGetCurrency (emp));
    }

    if (is_ok)
    {
        is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp,
                                         col_table);
    }

    if (is_ok)
    {
        // Now, commit or delete any slots
        guid = qof_instance_get_guid (inst);
        if (!qof_instance_get_destroying (inst))
        {
            is_ok = gnc_sql_slots_save (be, guid, is_infant, inst);
        }
        else
        {
            is_ok = gnc_sql_slots_delete (be, guid);
        }
    }

    return is_ok;
}
Exemplo n.º 2
0
/* ================================================================= */
bool
GncSqlInvoiceBackend::commit (GncSqlBackend* be, QofInstance* inst)
{
    const GncGUID* guid;
    GncInvoice* invoice;
    E_DB_OPERATION op;
    gboolean is_infant;
    gboolean is_ok = TRUE;

    g_return_val_if_fail (inst != NULL, FALSE);
    g_return_val_if_fail (GNC_IS_INVOICE (inst), FALSE);
    g_return_val_if_fail (be != NULL, FALSE);

    invoice = GNC_INVOICE (inst);

    is_infant = qof_instance_get_infant (inst);
    if (qof_instance_get_destroying (inst))
    {
        op = OP_DB_DELETE;
    }
    else if (be->pristine() || is_infant)
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }
    if (op != OP_DB_DELETE)
    {
        // Ensure the commodity is in the db
        is_ok = gnc_sql_save_commodity (be, gncInvoiceGetCurrency (invoice));
    }

    if (is_ok)
    {
        is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_INVOICE, inst,
                                         col_table);
    }

    if (is_ok)
    {
        // Now, commit or delete any slots
        guid = qof_instance_get_guid (inst);
        if (!qof_instance_get_destroying (inst))
        {
            is_ok = gnc_sql_slots_save (be, guid, is_infant, inst);
        }
        else
        {
            is_ok = gnc_sql_slots_delete (be, guid);
        }
    }

    return is_ok;
}
Exemplo n.º 3
0
static gboolean
save_taxtable( GncSqlBackend* be, QofInstance* inst )
{
    GncTaxTable* tt;
    const GncGUID* guid;
    gint op;
    gboolean is_infant;
    gboolean is_ok;

    g_return_val_if_fail( inst != NULL, FALSE );
    g_return_val_if_fail( GNC_IS_TAXTABLE(inst), FALSE );
    g_return_val_if_fail( be != NULL, FALSE );

    tt = GNC_TAXTABLE(inst);

    is_infant = qof_instance_get_infant( inst );
    if ( qof_instance_get_destroying( inst ) )
    {
        op = OP_DB_DELETE;
    }
    else if ( be->is_pristine_db || is_infant )
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }
    is_ok = gnc_sql_do_db_operation( be, op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt, tt_col_table );

    if ( is_ok )
    {
        // Now, commit or delete any slots and tax table entries
        guid = qof_instance_get_guid( inst );
        if ( !qof_instance_get_destroying(inst) )
        {
            is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
            if ( is_ok )
            {
                is_ok = save_tt_entries( be, guid, gncTaxTableGetEntries( tt ) );
            }
        }
        else
        {
            is_ok = gnc_sql_slots_delete( be, guid );
            if ( is_ok )
            {
                is_ok = delete_all_tt_entries( be, guid );
            }
        }
    }

    return is_ok;
}
Exemplo n.º 4
0
/* ================================================================= */
static gboolean
delete_all_tt_entries( GncSqlBackend* be, const GncGUID* guid )
{
    guid_info_t guid_info;

    g_return_val_if_fail( be != NULL, FALSE );
    g_return_val_if_fail( guid != NULL, FALSE );

    guid_info.be = be;
    guid_info.guid = guid;
    return gnc_sql_do_db_operation( be, OP_DB_DELETE, TTENTRIES_TABLE_NAME,
                                    TTENTRIES_TABLE_NAME, &guid_info, guid_col_table );
}
Exemplo n.º 5
0
gboolean
gnc_sql_recurrence_delete( GncSqlBackend* be, const GncGUID* guid )
{
    recurrence_info_t recurrence_info;

    g_return_val_if_fail( be != NULL, FALSE );
    g_return_val_if_fail( guid != NULL, FALSE );

    recurrence_info.be = be;
    recurrence_info.guid = guid;
    return gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
                                    TABLE_NAME, &recurrence_info, guid_col_table );
}
Exemplo n.º 6
0
gboolean
gnc_sql_slots_delete( GncSqlBackend* be, const GncGUID* guid )
{
    gchar* buf;
    GncSqlResult* result;
    gchar guid_buf[GUID_ENCODING_LENGTH + 1];
    GncSqlStatement* stmt;
    slot_info_t slot_info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, g_string_new('\0') };

    g_return_val_if_fail( be != NULL, FALSE );
    g_return_val_if_fail( guid != NULL, FALSE );

    (void)guid_to_string_buff( guid, guid_buf );

    buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s' and slot_type in ('%d', '%d') and not guid_val is null",
                           TABLE_NAME, guid_buf, KVP_TYPE_FRAME, KVP_TYPE_GLIST );
    stmt = gnc_sql_create_statement_from_sql( be, buf );
    g_free( buf );
    if ( stmt != NULL )
    {
        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 );

            while ( row != NULL )
            {
                GncSqlColumnTableEntry table_row = col_table[guid_val_col];
                GncGUID child_guid;
                const GValue* val =
                    gnc_sql_row_get_value_at_col_name( row, table_row.col_name);
                if ( val == NULL )
                    continue;

                (void)string_to_guid( g_value_get_string( val ), &child_guid );
                gnc_sql_slots_delete( be, &child_guid );
                row = gnc_sql_result_get_next_row( result );
            }
            gnc_sql_result_dispose( result );
        }
    }

    slot_info.be = be;
    slot_info.guid = guid;
    slot_info.is_ok = TRUE;
    slot_info.is_ok = gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
                      TABLE_NAME, &slot_info, obj_guid_col_table );

    return slot_info.is_ok;
}
Exemplo n.º 7
0
gboolean
gnc_sql_recurrence_save( GncSqlBackend* be, const GncGUID* guid, const Recurrence* r )
{
    recurrence_info_t recurrence_info;

    g_return_val_if_fail( be != NULL, FALSE );
    g_return_val_if_fail( guid != NULL, FALSE );
    g_return_val_if_fail( r != NULL, FALSE );

    (void)gnc_sql_recurrence_delete( be, guid );

    recurrence_info.be = be;
    recurrence_info.guid = guid;
    recurrence_info.pRecurrence = (Recurrence*)r;
    return gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME,
                                    TABLE_NAME, &recurrence_info, col_table );
}
Exemplo n.º 8
0
/**
 * Commits a split to the database
 *
 * @param be SQL backend
 * @param inst Split
 * @return TRUE if successful, FALSE if error
 */
static gboolean
commit_split( GncSqlBackend* be, QofInstance* inst )
{
    gint op;
    gboolean is_infant;
    gboolean is_ok;
    GncGUID *guid = (GncGUID*)qof_instance_get_guid(inst);

    g_return_val_if_fail( inst != NULL, FALSE );
    g_return_val_if_fail( be != NULL, FALSE );

    is_infant = qof_instance_get_infant( inst );
    if ( qof_instance_get_destroying( inst ) )
    {
        op = OP_DB_DELETE;
    }
    else if ( be->is_pristine_db || is_infant )
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }

    if (guid_equal (guid, guid_null ()))
    {
	*guid = guid_new_return ();
	qof_instance_set_guid (inst, guid);
    }

    is_ok = gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT,
				     inst, split_col_table );

    if ( is_ok && !qof_instance_get_destroying (inst))
    {
        is_ok = gnc_sql_slots_save( be,
                                    guid,
                                    is_infant,
                                    qof_instance_get_slots( inst ) );
    }

    return is_ok;
}
Exemplo n.º 9
0
/**
 * Deletes all of the splits for a transaction
 *
 * @param be SQL backend
 * @param pTx Transaction
 * @return TRUE if successful, FALSE if unsuccessful
 */
static gboolean
delete_splits( GncSqlBackend* be, Transaction* pTx )
{
    split_info_t split_info;

    g_return_val_if_fail( be != NULL, FALSE );
    g_return_val_if_fail( pTx != NULL, FALSE );

    if ( !gnc_sql_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE,
                                   SPLIT_TABLE, pTx, tx_guid_col_table ) )
    {
        return FALSE;
    }
    split_info.be = be;
    split_info.is_ok = TRUE;

    g_list_foreach( xaccTransGetSplitList( pTx ), delete_split_slots_cb, &split_info );

    return split_info.is_ok;
}
Exemplo n.º 10
0
void
gnc_sql_recurrence_save_list( GncSqlBackend* be, const GncGUID* guid, GList* schedule )
{
    recurrence_info_t recurrence_info;
    GList* l;

    g_return_if_fail( be != NULL );
    g_return_if_fail( guid != NULL );

    (void)gnc_sql_recurrence_delete( be, guid );

    recurrence_info.be = be;
    recurrence_info.guid = guid;
    for ( l = schedule; l != NULL; l = g_list_next( l ) )
    {
        recurrence_info.pRecurrence = (Recurrence*)l->data;
        (void)gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME,
                                       TABLE_NAME, &recurrence_info, col_table );
    }
}
Exemplo n.º 11
0
static gboolean
save_price (GncSqlBackend* be, QofInstance* inst)
{
    GNCPrice* pPrice = GNC_PRICE (inst);
    E_DB_OPERATION op;
    gboolean is_infant;
    gboolean is_ok = TRUE;

    g_return_val_if_fail (be != NULL, FALSE);
    g_return_val_if_fail (inst != NULL, FALSE);
    g_return_val_if_fail (GNC_IS_PRICE (inst), FALSE);

    is_infant = qof_instance_get_infant (inst);
    if (qof_instance_get_destroying (inst))
    {
        op = OP_DB_DELETE;
    }
    else if (be->is_pristine_db || is_infant)
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }

    if (op != OP_DB_DELETE)
    {
        /* Ensure commodity and currency are in the db */
        (void)gnc_sql_save_commodity (be, gnc_price_get_commodity (pPrice));
        is_ok = gnc_sql_save_commodity (be, gnc_price_get_currency (pPrice));
    }

    if (is_ok)
    {
        is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_PRICE, pPrice,
                                         col_table);
    }

    return is_ok;
}
Exemplo n.º 12
0
/* ================================================================= */
static gboolean
do_commit_commodity( GncSqlBackend* be, QofInstance* inst, gboolean force_insert )
{
    const GncGUID* guid;
    gboolean is_infant;
    gint op;
    gboolean is_ok;

    is_infant = qof_instance_get_infant( inst );
    if ( qof_instance_get_destroying( inst ) )
    {
        op = OP_DB_DELETE;
    }
    else if ( be->is_pristine_db || is_infant || force_insert )
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }
    is_ok = gnc_sql_do_db_operation( be, op, COMMODITIES_TABLE, GNC_ID_COMMODITY, inst, col_table );

    if ( is_ok )
    {
        // Now, commit any slots
        guid = qof_instance_get_guid( inst );
        if ( !qof_instance_get_destroying(inst) )
        {
            is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
        }
        else
        {
            is_ok = gnc_sql_slots_delete( be, guid );
        }
    }

    return is_ok;
}
Exemplo n.º 13
0
static gboolean
save_tt_entries( GncSqlBackend* be, const GncGUID* guid, GList* entries )
{
    GList* entry;
    gboolean is_ok;

    g_return_val_if_fail( be != NULL, FALSE );
    g_return_val_if_fail( guid != NULL, FALSE );

    /* First, delete the old entries for this object */
    is_ok = delete_all_tt_entries( be, guid );

    for ( entry = entries; entry != NULL && is_ok; entry = entry->next )
    {
        GncTaxTableEntry* e = (GncTaxTableEntry*)entry->data;
        is_ok = gnc_sql_do_db_operation( be,
                                         OP_DB_INSERT,
                                         TTENTRIES_TABLE_NAME,
                                         GNC_ID_TAXTABLE, e,
                                         ttentries_col_table );
    }

    return is_ok;
}
Exemplo n.º 14
0
static gboolean
save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits )
{
    const GncGUID* guid;
    gint op;
    gboolean is_infant;
    QofInstance* inst;
    gboolean is_ok = TRUE;
    gchar* err = NULL;

    g_return_val_if_fail( be != NULL, FALSE );
    g_return_val_if_fail( pTx != NULL, FALSE );

    inst = QOF_INSTANCE(pTx);
    is_infant = qof_instance_get_infant( inst );
    if ( qof_instance_get_destroying( inst ) )
    {
        op = OP_DB_DELETE;
    }
    else if ( be->is_pristine_db || is_infant )
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }

    if ( op != OP_DB_DELETE )
    {
        gnc_commodity *commodity = xaccTransGetCurrency( pTx );
        // Ensure the commodity is in the db
        is_ok = gnc_sql_save_commodity( be, commodity );
        if ( ! is_ok )
        {
            err = "Commodity save failed: Probably an invalid or missing currency";
            qof_backend_set_error( &be->be, ERR_BACKEND_DATA_CORRUPT);
        }
    }

    if ( is_ok )
    {
        is_ok = gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table );
        if ( ! is_ok )
        {
            err = "Transaction header save failed. Check trace log for SQL errors";
        }
    }

    if ( is_ok )
    {
        // Commit slots and splits
        guid = qof_instance_get_guid( inst );
        if ( !qof_instance_get_destroying(inst) )
        {
            is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
            if ( ! is_ok )
            {
                err = "Slots save failed. Check trace log for SQL errors";
            }
            if ( is_ok && do_save_splits )
            {
                is_ok = save_splits( be, guid, xaccTransGetSplitList( pTx ) );
                if ( ! is_ok )
                {
                    err = "Split save failed. Check trace log for SQL errors";
                }
            }
        }
        else
        {
            is_ok = gnc_sql_slots_delete( be, guid );
            if ( ! is_ok )
            {
                err = "Slots delete failed. Check trace log for SQL errors";
            }
            if ( is_ok )
            {
                is_ok = delete_splits( be, pTx );
                if ( ! is_ok )
                {
                    err = "Split delete failed. Check trace log for SQL errors";
                }
            }
        }
    }
    if (! is_ok )
    {
        G_GNUC_UNUSED gchar *message1 = "Transaction %s dated %s in account %s not saved due to %s.%s";
        G_GNUC_UNUSED gchar *message2 = "\nDatabase may be corrupted, check your data carefully.";
        Split* split = xaccTransGetSplit( pTx, 0);
        Account *acc = xaccSplitGetAccount( split );
        /* FIXME: This needs to be implemented
        qof_error_format_secondary_text( GTK_MESSAGE_DIALOG( msg ),
        					  message1,
        					 xaccTransGetDescription( pTx ),
        					  qof_print_date( xaccTransGetDate( pTx ) ),
        					  xaccAccountGetName( acc ),
        					  err,
        					  message2 );
        */
        PERR( "Transaction %s dated %s in account %s not saved due to %s.\n",
              xaccTransGetDescription( pTx ),
              qof_print_date( xaccTransGetDate( pTx ) ),
              xaccAccountGetName( acc ),
              err );
    }
    return is_ok;
}
Exemplo n.º 15
0
static void
save_slot( const gchar* key, KvpValue* value, gpointer data )
{
    slot_info_t* pSlot_info = (slot_info_t*)data;
    gsize curlen;

    g_return_if_fail( key != NULL );
    g_return_if_fail( value != NULL );
    g_return_if_fail( data != NULL );

    // Ignore if we've already run into a failure
    if ( !pSlot_info->is_ok )
    {
        return;
    }

    curlen = pSlot_info->path->len;
    pSlot_info->pKvpValue = value;
    if ( curlen != 0 )
    {
        (void)g_string_append( pSlot_info->path, "/" );
    }
    (void)g_string_append( pSlot_info->path, key );
    pSlot_info->value_type = kvp_value_get_type( value );

    switch ( pSlot_info->value_type )
    {
    case KVP_TYPE_FRAME:
    {
        KvpFrame* pKvpFrame = kvp_value_get_frame( value );
        GncGUID guid = guid_new_return();
        slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid );
        KvpValue *oldValue = pSlot_info->pKvpValue;
        pSlot_info->pKvpValue = kvp_value_new_guid( &guid );
        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
                            OP_DB_INSERT, TABLE_NAME,
                            TABLE_NAME, pSlot_info,
                            col_table );
        g_return_if_fail( pSlot_info->is_ok );
        kvp_frame_for_each_slot( pKvpFrame, save_slot, pNewInfo );
        kvp_value_delete( pSlot_info->pKvpValue );
        pSlot_info->pKvpValue = oldValue;
        g_string_free( pNewInfo->path, TRUE );
        g_slice_free( slot_info_t, pNewInfo );
    }
    break;
    case KVP_TYPE_GLIST:
    {
        GList *cursor;
        GncGUID guid = guid_new_return();
        slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid );
        KvpValue *oldValue = pSlot_info->pKvpValue;
        pSlot_info->pKvpValue = kvp_value_new_guid( &guid );
        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
                            OP_DB_INSERT, TABLE_NAME,
                            TABLE_NAME, pSlot_info,
                            col_table );
        g_return_if_fail( pSlot_info->is_ok );
        for (cursor = kvp_value_get_glist(value); cursor; cursor = cursor->next)
        {
            kvp_value *val = (kvp_value*)cursor->data;
            save_slot("", val, pNewInfo);
        }
        kvp_value_delete( pSlot_info->pKvpValue );
        pSlot_info->pKvpValue = oldValue;
        g_string_free( pNewInfo->path, TRUE );
        g_slice_free( slot_info_t, pNewInfo );
    }
    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 );
    }
    break;
    }

    (void)g_string_truncate( pSlot_info->path, curlen );
}
Exemplo n.º 16
0
/* ================================================================= */
gboolean
gnc_sql_save_account (GncSqlBackend* be, QofInstance* inst)
{
    Account* pAcc = GNC_ACCOUNT (inst);
    const GncGUID* guid;
    gboolean is_infant;
    gboolean is_ok = FALSE;
    gnc_commodity* commodity;
    E_DB_OPERATION op;

    g_return_val_if_fail (be != NULL, FALSE);
    g_return_val_if_fail (inst != NULL, FALSE);
    g_return_val_if_fail (GNC_IS_ACCOUNT (inst), FALSE);

    ENTER ("inst=%p", inst);

    is_infant = qof_instance_get_infant (inst);

    // If there is no commodity yet, this might be because a new account name
    // has been entered directly into the register and an account window will
    // be opened.  The account info is not complete yet, but the name has been
    // set, triggering this commit
    commodity = xaccAccountGetCommodity (pAcc);

    is_ok = TRUE;
    if (qof_instance_get_destroying (inst))
    {
        op = OP_DB_DELETE;
    }
    else if (be->is_pristine_db || is_infant)
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }

    // If not deleting the account, ensure the commodity is in the db
    if (op != OP_DB_DELETE && commodity != NULL)
    {
        is_ok = gnc_sql_save_commodity (be, commodity);
    }

    if (is_ok)
    {
        is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc,
                                         col_table);
    }

    if (is_ok)
    {
        // Now, commit or delete any slots
        guid = qof_instance_get_guid (inst);
        if (!qof_instance_get_destroying (inst))
        {
            is_ok = gnc_sql_slots_save (be, guid, is_infant, inst);
        }
        else
        {
            is_ok = gnc_sql_slots_delete (be, guid);
        }
    }

    LEAVE ("is_ok=%d", is_ok);

    return is_ok;
}
Exemplo n.º 17
0
static void
save_slot( const gchar* key, KvpValue* value, gpointer data )
{
    slot_info_t* pSlot_info = (slot_info_t*)data;
    gsize curlen;

    g_return_if_fail( key != NULL );
    g_return_if_fail( value != NULL );
    g_return_if_fail( data != NULL );

    // Ignore if we've already run into a failure
    if ( !pSlot_info->is_ok )
    {
        return;
    }

    curlen = pSlot_info->path->len;
    pSlot_info->pKvpValue = value;
    if ( curlen != 0 )
    {
        (void)g_string_append( pSlot_info->path, "/" );
    }
    (void)g_string_append( pSlot_info->path, key );
    pSlot_info->value_type = value->get_type();

    switch ( pSlot_info->value_type )
    {
    case KvpValue::Type::FRAME:
    {
        auto pKvpFrame = value->get<KvpFrame*>();
        auto guid = guid_new();
        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 );
        g_return_if_fail( pSlot_info->is_ok );
        pKvpFrame->for_each_slot(save_slot, pNewInfo);
        delete pSlot_info->pKvpValue;
        pSlot_info->pKvpValue = oldValue;
        g_string_free( pNewInfo->path, TRUE );
        g_slice_free( slot_info_t, pNewInfo );
    }
    break;
    case KvpValue::Type::GLIST:
    {
        GncGUID guid = guid_new_return();
        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 );
        g_return_if_fail( pSlot_info->is_ok );
        for (auto cursor = value->get<GList*>(); cursor; cursor = cursor->next)
        {
            auto val = static_cast<KvpValue*>(cursor->data);
            save_slot("", val, pNewInfo);
        }
        delete pSlot_info->pKvpValue;
        pSlot_info->pKvpValue = oldValue;
        g_string_free( pNewInfo->path, TRUE );
        g_slice_free( slot_info_t, pNewInfo );
    }
    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 );
    }
    break;
    }

    (void)g_string_truncate( pSlot_info->path, curlen );
}