Improve error handling. If an SQL command fails, set the qof backend error

code.  Unfortunately, at this time, the front end seems to ignore the error
(other than logging it).



git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@17606 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Phil Longstaff
2008-09-27 17:31:23 +00:00
parent 810bb601a6
commit d1198d026f
30 changed files with 792 additions and 451 deletions

View File

@@ -859,7 +859,7 @@ conn_execute_nonselect_statement( GncSqlConnection* conn, GncSqlStatement* stmt
result = dbi_conn_query( dbi_conn->conn, dbi_stmt->sql->str );
if( result == NULL ) {
PERR( "Error executing SQL %s\n", dbi_stmt->sql->str );
return 0;
return -1;
}
DEBUG( "SQL: %s\n", dbi_stmt->sql->str );
num_rows = dbi_result_get_numrows_affected( result );
@@ -910,22 +910,28 @@ conn_does_table_exist( GncSqlConnection* conn, const gchar* table_name )
}
}
static void
static gboolean
conn_begin_transaction( GncSqlConnection* conn )
{
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
return TRUE;
}
static void
static gboolean
conn_rollback_transaction( GncSqlConnection* conn )
{
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
return TRUE;
}
static void
static gboolean
conn_commit_transaction( GncSqlConnection* conn )
{
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
return TRUE;
}
static const gchar*
@@ -1009,7 +1015,7 @@ add_table_column( GString* ddl, const GncSqlColumnInfo* info )
}
}
static void
static gboolean
conn_create_table( GncSqlConnection* conn, const gchar* table_name,
const GList* col_info_list )
{
@@ -1019,9 +1025,9 @@ conn_create_table( GncSqlConnection* conn, const gchar* table_name,
guint col_num;
dbi_result result;
g_return_if_fail( conn != NULL );
g_return_if_fail( table_name != NULL );
g_return_if_fail( col_info_list != NULL );
g_return_val_if_fail( conn != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE );
g_return_val_if_fail( col_info_list != NULL, FALSE );
ddl = g_string_new( "" );
g_string_printf( ddl, "CREATE TABLE %s (", table_name );
@@ -1040,9 +1046,11 @@ conn_create_table( GncSqlConnection* conn, const gchar* table_name,
result = dbi_conn_query( dbi_conn->conn, ddl->str );
dbi_result_free( result );
g_string_free( ddl, TRUE );
return TRUE;
}
static void
static gboolean
conn_create_index( GncSqlConnection* conn, const gchar* index_name,
const gchar* table_name, const GncSqlColumnTableEntry* col_table )
{
@@ -1053,10 +1061,10 @@ conn_create_index( GncSqlConnection* conn, const gchar* index_name,
GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn;
GError* error = NULL;
g_return_if_fail( conn != NULL );
g_return_if_fail( index_name != NULL );
g_return_if_fail( table_name != NULL );
g_return_if_fail( col_table != NULL );
g_return_val_if_fail( conn != NULL, FALSE );
g_return_val_if_fail( index_name != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE );
g_return_val_if_fail( col_table != NULL, FALSE );
cnn = gda_conn->conn;
g_return_if_fail( cnn != NULL );
@@ -1123,6 +1131,8 @@ conn_create_index( GncSqlConnection* conn, const gchar* index_name,
g_object_unref( op );
}
#endif
return TRUE;
}
static gchar*

View File

@@ -263,16 +263,17 @@ create_account_tables( GncSqlBackend* be )
}
/* ================================================================= */
void
gboolean
gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst )
{
Account* pAcc = GNC_ACCOUNT(inst);
const GUID* guid;
gboolean is_infant;
gboolean is_ok = FALSE;
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_ACCOUNT(inst) );
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 );
is_infant = qof_instance_get_infant( inst );
@@ -293,19 +294,25 @@ gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst )
// If not deleting the account, ensure the commodity is in the db
if( op != OP_DB_DELETE ) {
gnc_sql_save_commodity( be, xaccAccountGetCommodity( pAcc ) );
is_ok = gnc_sql_save_commodity( be, xaccAccountGetCommodity( pAcc ) );
}
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc, col_table );
if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_ACCOUNT, pAcc, col_table );
}
// Now, commit or delete any slots
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else {
gnc_sql_slots_delete( be, guid );
}
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, qof_instance_get_slots( inst ) );
} else {
is_ok = gnc_sql_slots_delete( be, guid );
}
}
}
return is_ok;
}
/* ================================================================= */
@@ -354,8 +361,8 @@ gnc_sql_init_account_handler( void )
{
GNC_SQL_BACKEND_VERSION,
GNC_ID_ACCOUNT,
gnc_sql_save_account, /* commit */
load_all_accounts, /* initial_load */
gnc_sql_save_account, /* commit */
load_all_accounts, /* initial_load */
create_account_tables /* create_tables */
};

View File

@@ -33,6 +33,6 @@
#include <gmodule.h>
void gnc_sql_init_account_handler( void );
void gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst );
gboolean gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_ACCOUNT_SQL_H_ */

View File

@@ -63,7 +63,7 @@ static const gchar* convert_search_obj( QofIdType objType );
static void gnc_sql_init_object_handlers( void );
static void update_save_progress( GncSqlBackend* be );
static void register_standard_col_type_handlers( void );
static void reset_version_info( GncSqlBackend* be );
static gboolean reset_version_info( GncSqlBackend* be );
static GncSqlStatement* build_insert_statement( GncSqlBackend* be,
const gchar* table_name,
QofIdTypeConst obj_name, gpointer pObject,
@@ -86,7 +86,8 @@ typedef struct {
/* callback structure */
typedef struct {
gboolean ok;
gboolean is_known;
gboolean is_ok;
GncSqlBackend* be;
QofInstance* inst;
QofQuery* pQuery;
@@ -240,83 +241,110 @@ write_commodities( GncSqlBackend* be, QofBook* book )
}
}
static void
static gboolean
write_account_tree( GncSqlBackend* be, Account* root )
{
GList* descendants;
GList* node;
gboolean is_ok = TRUE;
g_return_if_fail( be != NULL );
g_return_if_fail( root != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( root != NULL, FALSE );
descendants = gnc_account_get_descendants( root );
for( node = descendants; node != NULL; node = g_list_next(node) ) {
gnc_sql_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) );
for( node = descendants; node != NULL && is_ok; node = g_list_next(node) ) {
is_ok = gnc_sql_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) );
update_save_progress( be );
}
g_list_free( descendants );
return is_ok;
}
static void
static gboolean
write_accounts( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
g_return_val_if_fail( be != NULL, FALSE );
write_account_tree( be, gnc_book_get_root_account( be->primary_book ) );
return write_account_tree( be, gnc_book_get_root_account( be->primary_book ) );
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static int
write_tx( Transaction* tx, gpointer data )
{
GncSqlBackend* be = (GncSqlBackend*)data;
write_objects_t* s = (write_objects_t*)data;
g_return_val_if_fail( tx != NULL, 0 );
g_return_val_if_fail( data != NULL, 0 );
gnc_sql_save_transaction( be, QOF_INSTANCE(tx) );
update_save_progress( be );
s->is_ok = gnc_sql_save_transaction( s->be, QOF_INSTANCE(tx) );
update_save_progress( s->be );
return 0;
if( s->is_ok ) {
return 0;
} else {
return 1;
}
}
static void
static gboolean
write_transactions( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
xaccAccountTreeForEachTransaction( gnc_book_get_root_account( be->primary_book ),
write_tx,
(gpointer)be );
&data );
return data.is_ok;
}
static void
static gboolean
write_template_transactions( GncSqlBackend* be )
{
Account* ra;
write_objects_t data;
g_return_if_fail( be != NULL );
g_return_val_if_fail( be != NULL, FALSE );
data.is_ok = TRUE;
ra = gnc_book_get_template_root( be->primary_book );
if( gnc_account_n_descendants( ra ) > 0 ) {
write_account_tree( be, ra );
xaccAccountTreeForEachTransaction( ra, write_tx, (gpointer)be );
data.is_ok = write_account_tree( be, ra );
if( data.is_ok ) {
data.be = be;
xaccAccountTreeForEachTransaction( ra, write_tx, &data );
}
}
return data.is_ok;
}
static void
static gboolean
write_schedXactions( GncSqlBackend* be )
{
GList* schedXactions;
SchedXaction* tmpSX;
gboolean is_ok = TRUE;
g_return_if_fail( be != NULL );
g_return_val_if_fail( be != NULL, FALSE );
schedXactions = gnc_book_get_schedxactions( be->primary_book )->sx_list;
for( ; schedXactions != NULL; schedXactions = schedXactions->next ) {
for( ; schedXactions != NULL && is_ok; schedXactions = schedXactions->next ) {
tmpSX = schedXactions->data;
gnc_sql_save_schedxaction( be, QOF_INSTANCE( tmpSX ) );
is_ok = gnc_sql_save_schedxaction( be, QOF_INSTANCE( tmpSX ) );
}
return is_ok;
}
static void
@@ -354,7 +382,7 @@ gnc_sql_sync_all( GncSqlBackend* be, QofBook *book )
GError* error = NULL;
gint row;
gint numTables;
gboolean status;
gboolean is_ok;
g_return_if_fail( be != NULL );
g_return_if_fail( book != NULL );
@@ -379,12 +407,22 @@ gnc_sql_sync_all( GncSqlBackend* be, QofBook *book )
// FIXME: should write the set of commodities that are used
//write_commodities( be, book );
gnc_sql_save_book( be, QOF_INSTANCE(book) );
write_accounts( be );
write_transactions( be );
write_template_transactions( be );
write_schedXactions( be );
qof_object_foreach_backend( GNC_SQL_BACKEND, write_cb, be );
is_ok = gnc_sql_save_book( be, QOF_INSTANCE(book) );
if( is_ok ) {
is_ok = write_accounts( be );
}
if( is_ok ) {
is_ok = write_transactions( be );
}
if( is_ok ) {
is_ok = write_template_transactions( be );
}
if( is_ok ) {
is_ok = write_schedXactions( be );
}
if( is_ok ) {
qof_object_foreach_backend( GNC_SQL_BACKEND, write_cb, be );
}
gnc_sql_connection_commit_transaction( be->conn );
be->is_pristine_db = FALSE;
@@ -423,11 +461,11 @@ commit_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
/* If this has already been handled, or is not the correct handler, return */
if( strcmp( pData->type_name, be_data->inst->e_type ) != 0 ) return;
if( be_data->ok ) return;
if( be_data->is_known ) return;
if( pData->commit != NULL ) {
(pData->commit)( be_data->be, be_data->inst );
be_data->ok = TRUE;
be_data->is_ok = (pData->commit)( be_data->be, be_data->inst );
be_data->is_known = TRUE;
}
}
@@ -439,7 +477,6 @@ gnc_sql_commit_edit( GncSqlBackend *be, QofInstance *inst )
{
sql_backend be_data;
GError* error;
gboolean status;
gboolean is_dirty;
gboolean is_destroying;
gboolean is_infant;
@@ -479,21 +516,30 @@ gnc_sql_commit_edit( GncSqlBackend *be, QofInstance *inst )
error = NULL;
gnc_sql_connection_begin_transaction( be->conn );
be_data.ok = FALSE;
be_data.is_known = FALSE;
be_data.be = be;
be_data.inst = inst;
qof_object_foreach_backend( GNC_SQL_BACKEND, commit_cb, &be_data );
if( !be_data.ok ) {
if( !be_data.is_known ) {
PERR( "gnc_sql_commit_edit(): Unknown object type '%s'\n", inst->e_type );
gnc_sql_connection_rollback_transaction( be->conn );
// Don't let unknown items still mark the book as being dirty
qof_instance_mark_clean(inst);
qof_book_mark_saved( be->primary_book );
LEAVE( "Rolled back" );
LEAVE( "Rolled back - unknown object type" );
return;
}
if( !be_data.is_ok ) {
// Error - roll it back
gnc_sql_connection_rollback_transaction( be->conn );
// This *should* leave things marked dirty
LEAVE( "Rolled back - database error" );
return;
}
gnc_sql_connection_commit_transaction( be->conn );
qof_instance_mark_clean(inst);
@@ -613,13 +659,13 @@ compile_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
// Is this the right item?
if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return;
if( be_data->ok ) return;
if( be_data->is_ok ) return;
if( pData->compile_query != NULL ) {
be_data->pQueryInfo->pCompiledQuery = (pData->compile_query)(
be_data->be,
be_data->pQuery );
be_data->ok = TRUE;
be_data->is_ok = TRUE;
}
}
@@ -643,14 +689,14 @@ gnc_sql_compile_query( QofBackend* pBEnd, QofQuery* pQuery )
pQueryInfo = g_malloc( sizeof( gnc_sql_query_info ) );
// Try various objects first
be_data.ok = FALSE;
be_data.is_ok = FALSE;
be_data.be = be;
be_data.pQuery = pQuery;
pQueryInfo->searchObj = searchObj;
be_data.pQueryInfo = pQueryInfo;
qof_object_foreach_backend( GNC_SQL_BACKEND, compile_query_cb, &be_data );
if( be_data.ok ) {
if( be_data.is_ok ) {
LEAVE( "" );
return be_data.pQueryInfo;
}
@@ -697,12 +743,12 @@ free_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
g_return_if_fail( pData->version == GNC_SQL_BACKEND_VERSION );
if( be_data->ok ) return;
if( be_data->is_ok ) return;
if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return;
if( pData->free_query != NULL ) {
(pData->free_query)( be_data->be, be_data->pCompiledQuery );
be_data->ok = TRUE;
be_data->is_ok = TRUE;
}
}
@@ -719,13 +765,13 @@ gnc_sql_free_query( QofBackend* pBEnd, gpointer pQuery )
ENTER( " " );
// Try various objects first
be_data.ok = FALSE;
be_data.is_ok = FALSE;
be_data.be = be;
be_data.pCompiledQuery = pQuery;
be_data.pQueryInfo = pQueryInfo;
qof_object_foreach_backend( GNC_SQL_BACKEND, free_query_cb, &be_data );
if( be_data.ok ) {
if( be_data.is_ok ) {
LEAVE( "" );
return;
}
@@ -745,14 +791,14 @@ run_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
g_return_if_fail( pData->version == GNC_SQL_BACKEND_VERSION );
if( be_data->ok ) return;
if( be_data->is_ok ) return;
// Is this the right item?
if( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 ) return;
if( pData->run_query != NULL ) {
(pData->run_query)( be_data->be, be_data->pCompiledQuery );
be_data->ok = TRUE;
be_data->is_ok = TRUE;
}
}
@@ -775,7 +821,7 @@ gnc_sql_run_query( QofBackend* pBEnd, gpointer pQuery )
qof_event_suspend();
// Try various objects first
be_data.ok = FALSE;
be_data.is_ok = FALSE;
be_data.be = be;
be_data.pCompiledQuery = pQueryInfo->pCompiledQuery;
be_data.pQueryInfo = pQueryInfo;
@@ -784,7 +830,7 @@ gnc_sql_run_query( QofBackend* pBEnd, gpointer pQuery )
be->loading = FALSE;
be->in_query = FALSE;
qof_event_resume();
// if( be_data.ok ) {
// if( be_data.is_ok ) {
// LEAVE( "" );
// return;
// }
@@ -1883,7 +1929,7 @@ gnc_sql_load_object( const GncSqlBackend* be, GncSqlRow* row,
/* ================================================================= */
GncSqlStatement*
gnc_sql_create_select_statement( const GncSqlBackend* be, const gchar* table_name )
gnc_sql_create_select_statement( GncSqlBackend* be, const gchar* table_name )
{
gchar* sql;
@@ -1895,7 +1941,7 @@ gnc_sql_create_select_statement( const GncSqlBackend* be, const gchar* table_nam
}
static GncSqlStatement*
create_single_col_select_statement( const GncSqlBackend* be,
create_single_col_select_statement( GncSqlBackend* be,
const gchar* table_name,
const GncSqlColumnTableEntry* table_row )
{
@@ -1914,15 +1960,14 @@ create_single_col_select_statement( const GncSqlBackend* be,
GncSqlResult*
gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* stmt )
{
GError* error = NULL;
GncSqlResult* result;
g_return_val_if_fail( be != NULL, NULL );
g_return_val_if_fail( stmt != NULL, NULL );
result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
if( error != NULL ) {
PERR( "SQL error: %s\n%s\n", gnc_sql_statement_to_sql( stmt ), error->message );
if( result == NULL ) {
PERR( "SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
}
@@ -1930,9 +1975,8 @@ gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* stmt )
}
GncSqlStatement*
gnc_sql_create_statement_from_sql( const GncSqlBackend* be, gchar* sql )
gnc_sql_create_statement_from_sql( GncSqlBackend* be, gchar* sql )
{
GError* error = NULL;
GncSqlStatement* stmt;
g_return_val_if_fail( be != NULL, NULL );
@@ -1940,17 +1984,17 @@ gnc_sql_create_statement_from_sql( const GncSqlBackend* be, gchar* sql )
stmt = gnc_sql_connection_create_statement_from_sql( be->conn, sql );
if( stmt == NULL ) {
PERR( "SQL error: %s\n%s\n", sql, error->message );
PERR( "SQL error: %s\n", sql );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
}
return stmt;
}
GncSqlResult*
gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql )
gnc_sql_execute_select_sql( GncSqlBackend* be, gchar* sql )
{
GncSqlStatement* stmt;
GError* error = NULL;
GncSqlResult* result = NULL;
g_return_val_if_fail( be != NULL, NULL );
@@ -1961,15 +2005,16 @@ gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql )
return NULL;
}
result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
if( error != NULL ) {
PERR( "SQL error: %s\n%s\n", sql, error->message );
if( result == NULL ) {
PERR( "SQL error: %s\n", sql );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
}
return result;
}
gint
gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql )
gnc_sql_execute_nonselect_sql( GncSqlBackend* be, gchar* sql )
{
GncSqlStatement* stmt;
gint result;
@@ -1979,7 +2024,7 @@ gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql )
stmt = gnc_sql_create_statement_from_sql( be, sql );
if( stmt == NULL ) {
return 0;
return -1;
}
result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
gnc_sql_statement_dispose( stmt );
@@ -2073,6 +2118,7 @@ gnc_sql_do_db_operation( GncSqlBackend* be,
const GncSqlColumnTableEntry* table )
{
GncSqlStatement* stmt;
gboolean ok = FALSE;
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2090,13 +2136,19 @@ gnc_sql_do_db_operation( GncSqlBackend* be,
g_assert( FALSE );
}
if( stmt != NULL ) {
gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
gnc_sql_statement_dispose( stmt );
gint result;
return TRUE;
} else {
return FALSE;
result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
if( result == -1 ) {
PERR( "SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
} else {
ok = TRUE;
}
gnc_sql_statement_dispose( stmt );
}
return ok;
}
static GSList*
@@ -2302,13 +2354,14 @@ build_delete_statement( GncSqlBackend* be,
}
/* ================================================================= */
void
gboolean
gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName,
QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table )
{
const GUID* guid;
gboolean is_infant;
gint op;
gboolean is_ok;
is_infant = qof_instance_get_infant( inst );
if( qof_instance_get_destroying( inst ) ) {
@@ -2318,24 +2371,29 @@ gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar*
} else {
op = OP_DB_UPDATE;
}
(void)gnc_sql_do_db_operation( be, op, tableName, obj_name, inst, col_table );
is_ok = gnc_sql_do_db_operation( be, op, tableName, obj_name, inst, col_table );
// Now, commit any slots
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else {
gnc_sql_slots_delete( be, guid );
}
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;
}
/* ================================================================= */
static gboolean
create_table( const GncSqlBackend* be, const gchar* table_name,
do_create_table( const GncSqlBackend* be, const gchar* table_name,
const GncSqlColumnTableEntry* col_table )
{
GList* col_info_list = NULL;
gboolean ok = FALSE;
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2347,19 +2405,19 @@ create_table( const GncSqlBackend* be, const gchar* table_name,
pHandler = get_handler( col_table );
pHandler->add_col_info_to_list_fn( be, col_table, &col_info_list );
}
gnc_sql_connection_create_table( be->conn, table_name, col_info_list );
return TRUE;
ok = gnc_sql_connection_create_table( be->conn, table_name, col_info_list );
return ok;
}
gboolean
gnc_sql_create_table( const GncSqlBackend* be, const gchar* table_name,
gnc_sql_create_table( GncSqlBackend* be, const gchar* table_name,
gint table_version, const GncSqlColumnTableEntry* col_table )
{
gboolean ok;
ok = create_table( be, table_name, col_table );
ok = do_create_table( be, table_name, col_table );
if( ok ) {
(void)gnc_sql_set_table_version( be, table_name, table_version );
ok = gnc_sql_set_table_version( be, table_name, table_version );
}
return ok;
}
@@ -2368,21 +2426,24 @@ gboolean
gnc_sql_create_temp_table( const GncSqlBackend* be, const gchar* table_name,
const GncSqlColumnTableEntry* col_table )
{
return create_table( be, table_name, col_table );
return do_create_table( be, table_name, col_table );
}
void
gboolean
gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
const gchar* table_name,
const GncSqlColumnTableEntry* col_table )
{
g_return_if_fail( be != NULL );
g_return_if_fail( index_name != NULL );
g_return_if_fail( table_name != NULL );
g_return_if_fail( col_table != NULL );
gboolean ok;
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( index_name != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE );
g_return_val_if_fail( col_table != NULL, FALSE );
gnc_sql_connection_create_index( be->conn, index_name, table_name,
ok = gnc_sql_connection_create_index( be->conn, index_name, table_name,
col_table );
return ok;
}
gint
@@ -2454,7 +2515,7 @@ gnc_sql_init_version_info( GncSqlBackend* be )
} else {
gboolean ok;
ok = create_table( be, VERSION_TABLE_NAME, version_table );
ok = do_create_table( be, VERSION_TABLE_NAME, version_table );
}
}
@@ -2463,20 +2524,23 @@ gnc_sql_init_version_info( GncSqlBackend* be )
* It also recreates the version table in the db.
*
* @param be Backend struct
* @return TRUE if successful, FALSE if error
*/
static void
static gboolean
reset_version_info( GncSqlBackend* be )
{
gboolean ok;
g_return_if_fail( be != NULL );
g_return_val_if_fail( be != NULL, FALSE );
ok = create_table( be, VERSION_TABLE_NAME, version_table );
ok = do_create_table( be, VERSION_TABLE_NAME, version_table );
if( be->versions == NULL ) {
be->versions = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL );
} else {
g_hash_table_remove_all( be->versions );
}
return ok;
}
/**
@@ -2502,10 +2566,11 @@ gnc_sql_finalize_version_info( GncSqlBackend* be )
* @return TRUE if successful, FALSE if unsuccessful
*/
gboolean
gnc_sql_set_table_version( const GncSqlBackend* be, const gchar* table_name, gint version )
gnc_sql_set_table_version( GncSqlBackend* be, const gchar* table_name, gint version )
{
gchar* sql;
gint cur_version;
gint status;
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( table_name != NULL, FALSE );
@@ -2521,7 +2586,11 @@ gnc_sql_set_table_version( const GncSqlBackend* be, const gchar* table_name, gin
VERSION_COL_NAME, version,
TABLE_COL_NAME, table_name );
}
(void)gnc_sql_execute_nonselect_sql( be, sql );
status = gnc_sql_execute_nonselect_sql( be, sql );
if( status == -1 ) {
PERR( "SQL error: %s\n", sql );
qof_backend_set_error( &be->be, ERR_BACKEND_SERVER_ERR );
}
}
g_hash_table_insert( be->versions, g_strdup( table_name ), GINT_TO_POINTER(version) );

View File

@@ -159,16 +159,16 @@ struct GncSqlStatement
struct GncSqlConnection
{
void (*dispose)( GncSqlConnection* );
GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* );
gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* );
GncSqlResult* (*executeSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns NULL if error */
gint (*executeNonSelectStatement)( GncSqlConnection*, GncSqlStatement* ); /**< Returns -1 if error */
GncSqlStatement* (*createStatementFromSql)( GncSqlConnection*, gchar* );
gboolean (*doesTableExist)( GncSqlConnection*, const gchar* );
void (*beginTransaction)( GncSqlConnection* );
void (*rollbackTransaction)( GncSqlConnection* );
void (*commitTransaction)( GncSqlConnection* );
gboolean (*beginTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
gboolean (*rollbackTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
gboolean (*commitTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */
const gchar* (*getColumnTypeName)( GncSqlConnection*, GType, gint size );
void (*createTable)( GncSqlConnection*, const gchar*, const GList* );
void (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* );
gboolean (*createTable)( GncSqlConnection*, const gchar*, const GList* ); /**< Returns TRUE if successful, FALSE if error */
gboolean (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* ); /**< Returns TRUE if successful, FALSE if error */
gchar* (*quoteString)( const GncSqlConnection*, gchar* );
};
#define gnc_sql_connection_dispose(CONN) (CONN)->dispose(CONN)
@@ -251,8 +251,10 @@ typedef struct
{
int version; /**< Backend version number */
const gchar * type_name; /**< Engine object type name */
/** Commit an instance of this object to the database */
void (*commit)( GncSqlBackend* be, QofInstance* inst );
/** Commit an instance of this object to the database
* @return TRUE if successful, FALSE if error
*/
gboolean (*commit)( GncSqlBackend* be, QofInstance* inst );
/** Load all objects of this type from the database */
void (*initial_load)( GncSqlBackend* be );
/** Create database tables for this object */
@@ -263,8 +265,10 @@ typedef struct
void (*run_query)( GncSqlBackend* be, gpointer pQuery );
/** Free a query on these objects */
void (*free_query)( GncSqlBackend* be, gpointer pQuery );
/** Write all objects of this type to the database */
void (*write)( GncSqlBackend* be );
/** Write all objects of this type to the database
* @return TRUE if successful, FALSE if error
*/
gboolean (*write)( GncSqlBackend* be );
} GncSqlObjectBackend;
#define GNC_SQL_BACKEND "gnc:sql:1"
#define GNC_SQL_BACKEND_VERSION 1
@@ -417,31 +421,35 @@ gboolean gnc_sql_do_db_operation( GncSqlBackend* be,
const GncSqlColumnTableEntry* table );
/**
* Execute an SQL SELECT statement.
* Executes an SQL SELECT statement and returns the result rows. If an error
* occurs, an entry is added to the log, an error status is returned to qof and
* NULL is returned.
*
* @param be SQL backend struct
* @param statement Statement
* @return Results
* @return Results, or NULL if an error has occured
*/
GncSqlResult* gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStatement* statement );
/**
* Executes an SQL SELECT statement from an SQL char string.
* Executes an SQL SELECT statement from an SQL char string and returns the
* result rows. If an error occurs, an entry is added to the log, an error
* status is returned to qof and NULL is returned.
*
* @param be SQL backend struct
* @param sql SQL SELECT string
* @return Results
* @return Results, or NULL if an error has occured
*/
GncSqlResult* gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql );
GncSqlResult* gnc_sql_execute_select_sql( GncSqlBackend* be, gchar* sql );
/**
* Executes an SQL non-SELECT statement from an SQL char string.
*
* @param be SQL backend struct
* @param sql SQL non-SELECT string
* @returns Number of rows affected
* @returns Number of rows affected, or -1 if an error has occured
*/
gint gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql );
gint gnc_sql_execute_nonselect_sql( GncSqlBackend* be, gchar* sql );
/**
* Creates a statement from an SQL char string.
@@ -450,7 +458,7 @@ gint gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql );
* @param sql SQL char string
* @return Statement
*/
GncSqlStatement* gnc_sql_create_statement_from_sql( const GncSqlBackend* be, gchar* sql );
GncSqlStatement* gnc_sql_create_statement_from_sql( GncSqlBackend* be, gchar* sql );
/**
* Loads a Gnucash object from the database.
@@ -497,7 +505,7 @@ gint gnc_sql_get_table_version( const GncSqlBackend* be, const gchar* table_name
* @param table_version Table version
* @return TRUE if successful, FALSE if unsuccessful
*/
gboolean gnc_sql_set_table_version( const GncSqlBackend* be,
gboolean gnc_sql_set_table_version( GncSqlBackend* be,
const gchar* table_name,
gint table_version );
@@ -510,7 +518,7 @@ gboolean gnc_sql_set_table_version( const GncSqlBackend* be,
* @param col_table DB table description
* @return TRUE if successful, FALSE if unsuccessful
*/
gboolean gnc_sql_create_table( const GncSqlBackend* be,
gboolean gnc_sql_create_table( GncSqlBackend* be,
const gchar* table_name,
gint table_version,
const GncSqlColumnTableEntry* col_table );
@@ -535,8 +543,9 @@ gboolean gnc_sql_create_temp_table( const GncSqlBackend* be,
* @param index_name Index name
* @param table_name Table name
* @param col_table Columns that the index should index
* @return TRUE if successful, FALSE if unsuccessful
*/
void gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
gboolean gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name,
const gchar* table_name, const GncSqlColumnTableEntry* col_table );
/**
@@ -566,7 +575,7 @@ const GUID* gnc_sql_load_tx_guid( const GncSqlBackend* be, GncSqlRow* row );
* @param table_name Table name
* @return Statement
*/
GncSqlStatement* gnc_sql_create_select_statement( const GncSqlBackend* be,
GncSqlStatement* gnc_sql_create_select_statement( GncSqlBackend* be,
const gchar* table_name );
/**
@@ -656,8 +665,9 @@ void gnc_sql_finalize_version_info( GncSqlBackend* be );
* @param tableName SQL table name
* @param obj_name QOF object type name
* @param col_table Column table
* @return TRUE if successful, FALSE if not
*/
void gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName,
gboolean gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* tableName,
QofIdTypeConst obj_name, const GncSqlColumnTableEntry* col_table );
void _retrieve_guid_( gpointer pObject, gpointer pValue );

View File

@@ -190,18 +190,18 @@ create_book_tables( GncSqlBackend* be )
}
/* ================================================================= */
void
gboolean
gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst)
{
const GUID* guid;
gint op;
gboolean is_infant;
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( QOF_IS_BOOK(inst) );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( QOF_IS_BOOK(inst), FALSE );
gnc_sql_commit_standard_item( be, inst, BOOK_TABLE, GNC_ID_BOOK, col_table );
return gnc_sql_commit_standard_item( be, inst, BOOK_TABLE, GNC_ID_BOOK, col_table );
}
/* ================================================================= */

View File

@@ -33,6 +33,6 @@
#include <gmodule.h>
void gnc_sql_init_book_handler( void );
void gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst );
gboolean gnc_sql_save_book( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_BOOK_SQL_H_ */

View File

@@ -135,17 +135,18 @@ create_budget_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_budget( GncSqlBackend* be, QofInstance* inst )
{
GncBudget* pBudget = GNC_BUDGET(inst);
const GUID* guid;
gint op;
gboolean is_infant;
gboolean is_ok;
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_BUDGET(inst) );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_BUDGET(inst), FALSE );
is_infant = qof_instance_get_infant( inst );
if( qof_instance_get_destroying( inst ) ) {
@@ -155,32 +156,55 @@ save_budget( GncSqlBackend* be, QofInstance* inst )
} else {
op = OP_DB_UPDATE;
}
(void)gnc_sql_do_db_operation( be, op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget, col_table );
is_ok = gnc_sql_do_db_operation( be, op, BUDGET_TABLE, GNC_ID_BUDGET, pBudget, col_table );
// Now, commit any slots and recurrence
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_recurrence_save( be, guid, gnc_budget_get_recurrence( pBudget ) );
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else {
gnc_sql_recurrence_delete( be, guid );
gnc_sql_slots_delete( be, guid );
}
if( is_ok ) {
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
is_ok = gnc_sql_recurrence_save( be, guid, gnc_budget_get_recurrence( pBudget ) );
if( is_ok ) {
is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
}
} else {
is_ok = gnc_sql_recurrence_delete( be, guid );
if( is_ok ) {
gnc_sql_slots_delete( be, guid );
}
}
}
return is_ok;
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
do_save_budget( QofInstance* inst, gpointer data )
{
save_budget( (GncSqlBackend*)data, inst );
write_objects_t* s = (write_objects_t*)data;
if( s->is_ok ) {
s->is_ok = save_budget( s->be, inst );
}
}
static void
static gboolean
write_budgets( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_collection_foreach( qof_book_get_collection( be->primary_book, GNC_ID_BUDGET ),
(QofInstanceForeachCB)do_save_budget, be );
(QofInstanceForeachCB)do_save_budget, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -169,16 +169,16 @@ create_commodities_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
commit_commodity( GncSqlBackend* be, QofInstance* inst )
{
const GUID* guid;
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_COMMODITY(inst) );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_COMMODITY(inst), FALSE );
gnc_sql_commit_standard_item( be, inst, COMMODITIES_TABLE, GNC_ID_COMMODITY, col_table );
return gnc_sql_commit_standard_item( be, inst, COMMODITIES_TABLE, GNC_ID_COMMODITY, col_table );
}
static gboolean
@@ -191,15 +191,19 @@ is_commodity_in_db( GncSqlBackend* be, gnc_commodity* pCommodity )
pCommodity, col_table );
}
void
gboolean
gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity )
{
g_return_if_fail( be != NULL );
g_return_if_fail( pCommodity != NULL );
gboolean is_ok = TRUE;
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( pCommodity != NULL, FALSE );
if( !is_commodity_in_db( be, pCommodity ) ) {
commit_commodity( be, QOF_INSTANCE(pCommodity) );
is_ok = commit_commodity( be, QOF_INSTANCE(pCommodity) );
}
return is_ok;
}
/* ----------------------------------------------------------------- */

View File

@@ -33,6 +33,6 @@
#include <gmodule.h>
void gnc_sql_init_commodity_handler( void );
void gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity );
gboolean gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity );
#endif /* GNC_COMMODITY_SQL_H_ */

View File

@@ -187,29 +187,43 @@ create_lots_tables( GncSqlBackend* be )
/* ================================================================= */
static void
static gboolean
commit_lot( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_LOT(inst) );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_LOT(inst), FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_LOT, col_table );
return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_LOT, col_table );
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
do_save_lot( QofInstance* inst, gpointer data )
{
commit_lot( (GncSqlBackend*)data, inst );
write_objects_t* s = (write_objects_t*)data;
if( s->is_ok ) {
s->is_ok = commit_lot( s->be, inst );
}
}
static void
static gboolean
write_lots( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_collection_foreach( qof_book_get_collection( be->primary_book, GNC_ID_LOT ),
(QofInstanceForeachCB)do_save_lot, be );
(QofInstanceForeachCB)do_save_lot, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -132,16 +132,17 @@ create_prices_tables( GncSqlBackend* be )
/* ================================================================= */
static void
static gboolean
save_price( GncSqlBackend* be, QofInstance* inst )
{
GNCPrice* pPrice = GNC_PRICE(inst);
gint op;
gboolean is_infant;
gboolean is_ok;
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_PRICE(inst) );
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 ) ) {
@@ -155,35 +156,49 @@ save_price( GncSqlBackend* be, QofInstance* inst )
if( op != OP_DB_DELETE ) {
/* Ensure commodity and currency are in the db */
gnc_sql_save_commodity( be, gnc_price_get_commodity( pPrice ) );
gnc_sql_save_commodity( be, gnc_price_get_currency( pPrice ) );
is_ok = gnc_sql_save_commodity( be, gnc_price_get_currency( pPrice ) );
}
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table );
if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table );
}
return is_ok;
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static gboolean
write_price( GNCPrice* p, gpointer data )
{
GncSqlBackend* be = (GncSqlBackend*)data;
write_objects_t* s = (write_objects_t*)data;
g_return_val_if_fail( p != NULL, FALSE );
g_return_val_if_fail( data != NULL, FALSE );
save_price( be, QOF_INSTANCE(p) );
if( s->is_ok ) {
s->is_ok = save_price( s->be, QOF_INSTANCE(p) );
}
return TRUE;
return s->is_ok;
}
static void
static gboolean
write_prices( GncSqlBackend* be )
{
GNCPriceDB* priceDB;
write_objects_t data;
g_return_if_fail( be != NULL );
g_return_val_if_fail( be != NULL, FALSE );
priceDB = gnc_book_get_pricedb( be->primary_book );
gnc_pricedb_foreach_price( priceDB, write_price, be, TRUE );
data.be = be;
data.is_ok = TRUE;
return gnc_pricedb_foreach_price( priceDB, write_price, &data, TRUE );
}
/* ================================================================= */

View File

@@ -173,21 +173,21 @@ set_recurrence_period_start( gpointer pObject, gpointer pValue )
/* ================================================================= */
void
gboolean
gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* r )
{
recurrence_info_t recurrence_info;
g_return_if_fail( be != NULL );
g_return_if_fail( guid != NULL );
g_return_if_fail( r != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( guid != NULL, FALSE );
g_return_val_if_fail( r != NULL, FALSE );
gnc_sql_recurrence_delete( be, guid );
recurrence_info.be = be;
recurrence_info.guid = guid;
recurrence_info.pRecurrence = (Recurrence*)r;
(void)gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME,
return gnc_sql_do_db_operation( be, OP_DB_INSERT, TABLE_NAME,
TABLE_NAME, &recurrence_info, col_table );
}
@@ -211,17 +211,17 @@ gnc_sql_recurrence_save_list( GncSqlBackend* be, const GUID* guid, GList* schedu
}
}
void
gboolean
gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid )
{
recurrence_info_t recurrence_info;
g_return_if_fail( be != NULL );
g_return_if_fail( guid != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( guid != NULL, FALSE );
recurrence_info.be = be;
recurrence_info.guid = guid;
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
return gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
TABLE_NAME, &recurrence_info, guid_col_table );
}

View File

@@ -32,9 +32,9 @@
#include "qof.h"
#include <gmodule.h>
void gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* pRecurrence );
gboolean gnc_sql_recurrence_save( GncSqlBackend* be, const GUID* guid, const Recurrence* pRecurrence );
void gnc_sql_recurrence_save_list( GncSqlBackend* be, const GUID* guid, GList* schedule );
void gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid );
gboolean gnc_sql_recurrence_delete( GncSqlBackend* be, const GUID* guid );
void gnc_sql_recurrence_load( GncSqlBackend* be, const GUID* guid, Recurrence* pRecurrence );
void gnc_sql_recurrence_load_list( GncSqlBackend* be, const GUID* guid, GList** pSchedule );

View File

@@ -260,17 +260,18 @@ create_sx_tables( GncSqlBackend* be )
}
/* ================================================================= */
void
gboolean
gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst )
{
SchedXaction* pSx;
const GUID* guid;
gint op;
gboolean is_infant;
gboolean is_ok;
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_SX(inst) );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_SX(inst), FALSE );
pSx = GNC_SX(inst);
@@ -282,16 +283,20 @@ gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst )
} else {
op = OP_DB_UPDATE;
}
(void)gnc_sql_do_db_operation( be, op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx, col_table );
is_ok = gnc_sql_do_db_operation( be, op, SCHEDXACTION_TABLE, GNC_SX_ID, pSx, col_table );
guid = qof_instance_get_guid( inst );
gnc_sql_recurrence_save_list( be, guid, gnc_sx_get_schedule( pSx ) );
// Now, commit any slots
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else {
gnc_sql_slots_delete( be, guid );
}
if( is_ok ) {
// Now, commit any slots
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;
}
/* ================================================================= */

View File

@@ -33,6 +33,6 @@
#include <gmodule.h>
void gnc_sql_init_schedxaction_handler( void );
void gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst );
gboolean gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_SCHEDXACTION_SQL_H_ */

View File

@@ -45,6 +45,7 @@ static QofLogModule log_module = G_LOG_DOMAIN;
typedef struct {
GncSqlBackend* be;
const GUID* guid;
gboolean is_ok;
KvpFrame* pKvpFrame;
KvpValueType value_type;
KvpValue* pKvpValue;
@@ -324,11 +325,17 @@ save_slot( const gchar* key, KvpValue* value, gpointer data )
{
slot_info_t* pSlot_info = (slot_info_t*)data;
gint curlen;
gboolean is_ok = FALSE;
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 ) {
@@ -340,21 +347,23 @@ save_slot( const gchar* key, KvpValue* value, gpointer data )
KvpFrame* pKvpFrame = kvp_value_get_frame( value );
kvp_frame_for_each_slot( pKvpFrame, save_slot, pSlot_info );
} else {
(void)gnc_sql_do_db_operation( pSlot_info->be, OP_DB_INSERT, TABLE_NAME,
TABLE_NAME, pSlot_info, col_table );
pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
OP_DB_INSERT, TABLE_NAME,
TABLE_NAME, pSlot_info,
col_table );
}
g_string_truncate( pSlot_info->path, curlen );
}
void
gboolean
gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid, gboolean is_infant, KvpFrame* pFrame )
{
slot_info_t slot_info;
g_return_if_fail( be != NULL );
g_return_if_fail( guid != NULL );
g_return_if_fail( pFrame != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( guid != NULL, FALSE );
g_return_val_if_fail( pFrame != NULL, FALSE );
// If this is not saving into a new db, clear out the old saved slots first
if( !be->is_pristine_db && !is_infant ) {
@@ -364,22 +373,28 @@ gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid, gboolean is_infant, Kvp
slot_info.be = be;
slot_info.guid = guid;
slot_info.path = g_string_new( "" );
slot_info.is_ok = TRUE;
kvp_frame_for_each_slot( pFrame, save_slot, &slot_info );
g_string_free( slot_info.path, TRUE );
return slot_info.is_ok;
}
void
gboolean
gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid )
{
slot_info_t slot_info;
g_return_if_fail( be != NULL );
g_return_if_fail( guid != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( guid != NULL, FALSE );
slot_info.be = be;
slot_info.guid = guid;
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
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;
}
static void

View File

@@ -33,14 +33,15 @@
#include <gmodule.h>
/**
* gnc_sql_slots_save - Saves slots for an object to the db.
*
* @param be SQL backend
* @param guid Object guid
* @param is_infant Is this an infant object?
* @param pFrame Top-level KVP frame
*/
void gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
* gnc_sql_slots_save - Saves slots for an object to the db.
*
* @param be SQL backend
* @param guid Object guid
* @param is_infant Is this an infant object?
* @param pFrame Top-level KVP frame
* @return TRUE if successful, FALSE if error
*/
gboolean gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
gboolean is_infant, KvpFrame* pFrame );
/**
@@ -48,8 +49,9 @@ void gnc_sql_slots_save( GncSqlBackend* be, const GUID* guid,
*
* @param be SQL backend
* @param guid Object guid
* @return TRUE if successful, FALSE if error
*/
void gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid );
gboolean gnc_sql_slots_delete( GncSqlBackend* be, const GUID* guid );
/**
* gnc_sql_slots_load - Loads slots for an object from the db.

View File

@@ -57,6 +57,7 @@ static QofLogModule log_module = G_LOG_DOMAIN;
typedef struct {
GncSqlBackend* be;
const GUID* guid;
gboolean is_ok;
} split_info_t;
#define TX_MAX_NUM_LEN 2048
@@ -439,33 +440,41 @@ delete_split_slots_cb( gpointer data, gpointer user_data )
g_return_if_fail( GNC_IS_SPLIT(data) );
g_return_if_fail( user_data != NULL );
gnc_sql_slots_delete( split_info->be,
qof_instance_get_guid( QOF_INSTANCE(pSplit) ) );
if( split_info->is_ok ) {
split_info->is_ok = gnc_sql_slots_delete( split_info->be,
qof_instance_get_guid( QOF_INSTANCE(pSplit) ) );
}
}
static void
static gboolean
delete_splits( GncSqlBackend* be, Transaction* pTx )
{
split_info_t split_info;
g_return_if_fail( be != NULL );
g_return_if_fail( pTx != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( pTx != NULL, FALSE );
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE,
SPLIT_TABLE, pTx, guid_col_table );
if( !gnc_sql_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE,
SPLIT_TABLE, pTx, 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;
}
static void
static gboolean
commit_split( GncSqlBackend* be, QofInstance* inst )
{
gint op;
gboolean is_infant;
gboolean is_ok;
g_return_if_fail( inst != NULL );
g_return_if_fail( be != NULL );
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 ) ) {
@@ -475,11 +484,15 @@ commit_split( GncSqlBackend* be, QofInstance* inst )
} else {
op = OP_DB_UPDATE;
}
(void)gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT, inst, split_col_table );
gnc_sql_slots_save( be,
is_ok = gnc_sql_do_db_operation( be, op, SPLIT_TABLE, GNC_ID_SPLIT, inst, split_col_table );
if( is_ok ) {
is_ok = gnc_sql_slots_save( be,
qof_instance_get_guid( inst ),
is_infant,
qof_instance_get_slots( inst ) );
}
return is_ok;
}
static void
@@ -492,33 +505,39 @@ save_split_cb( gpointer data, gpointer user_data )
g_return_if_fail( GNC_IS_SPLIT(data) );
g_return_if_fail( user_data != NULL );
commit_split( split_info->be, QOF_INSTANCE(pSplit) );
if( split_info->is_ok ) {
split_info->is_ok = commit_split( split_info->be, QOF_INSTANCE(pSplit) );
}
}
static void
static gboolean
save_splits( GncSqlBackend* be, const GUID* tx_guid, SplitList* pSplitList )
{
split_info_t split_info;
g_return_if_fail( be != NULL );
g_return_if_fail( tx_guid != NULL );
g_return_if_fail( pSplitList != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( tx_guid != NULL, FALSE );
g_return_val_if_fail( pSplitList != NULL, FALSE );
split_info.be = be;
split_info.guid = tx_guid;
split_info.is_ok = TRUE;
g_list_foreach( pSplitList, save_split_cb, &split_info );
return split_info.is_ok;
}
static void
static gboolean
save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits )
{
const GUID* guid;
gint op;
gboolean is_infant;
QofInstance* inst;
gboolean is_ok = TRUE;
g_return_if_fail( be != NULL );
g_return_if_fail( pTx != 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 );
@@ -532,42 +551,50 @@ save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits )
if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db
gnc_sql_save_commodity( be, xaccTransGetCurrency( pTx ) );
is_ok = gnc_sql_save_commodity( be, xaccTransGetCurrency( pTx ) );
}
(void)gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table );
if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TRANSACTION_TABLE, GNC_ID_TRANS, pTx, tx_col_table );
}
// Commit slots and splits
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
if( do_save_splits ) {
save_splits( be, guid, xaccTransGetSplitList( pTx ) );
}
} else {
gnc_sql_slots_delete( be, guid );
delete_splits( be, pTx );
}
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 && do_save_splits ) {
is_ok = save_splits( be, guid, xaccTransGetSplitList( pTx ) );
}
} else {
is_ok = gnc_sql_slots_delete( be, guid );
if( is_ok ) {
is_ok = delete_splits( be, pTx );
}
}
}
return is_ok;
}
void
gboolean
gnc_sql_save_transaction( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_TRANS(inst) );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_TRANS(inst), FALSE );
save_transaction( be, GNC_TRANS(inst), TRUE );
return save_transaction( be, GNC_TRANS(inst), TRUE );
}
static void
static gboolean
commit_transaction( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( be != NULL );
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_TRANS(inst) );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_TRANS(inst), FALSE );
save_transaction( be, GNC_TRANS(inst), FALSE );
return save_transaction( be, GNC_TRANS(inst), FALSE );
}
/* ================================================================= */

View File

@@ -34,7 +34,7 @@
void gnc_sql_init_transaction_handler( void );
void gnc_sql_transaction_commit_splits( GncSqlBackend* be, Transaction* pTx );
void gnc_sql_save_transaction( GncSqlBackend* be, QofInstance* inst );
gboolean gnc_sql_save_transaction( GncSqlBackend* be, QofInstance* inst );
void gnc_sql_get_account_balances( GncSqlBackend* be, Account* pAccount,
gnc_numeric* start_balance,
gnc_numeric* cleared_balance,

View File

@@ -143,18 +143,32 @@ load_all_billterms( GncSqlBackend* be )
}
/* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_billterms_t;
static void
do_save_billterm( QofInstance* inst, gpointer p2 )
{
gnc_sql_save_billterm( (GncSqlBackend*)p2, inst );
write_billterms_t* data = (write_billterms_t*)p2;
if( data->is_ok ) {
data->is_ok = gnc_sql_save_billterm( data->be, inst );
}
}
static void
static gboolean
write_billterms( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_billterms_t data;
qof_object_foreach( GNC_ID_BILLTERM, be->primary_book, do_save_billterm, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_BILLTERM, be->primary_book, do_save_billterm, &data );
return data.is_ok;
}
/* ================================================================= */
@@ -172,14 +186,14 @@ create_billterm_tables( GncSqlBackend* be )
}
/* ================================================================= */
void
gboolean
gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_BILLTERM(inst) );
g_return_if_fail( be != NULL );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_BILLTERM(inst), FALSE );
g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_BILLTERM, col_table );
return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_BILLTERM, col_table );
}
/* ================================================================= */

View File

@@ -35,6 +35,6 @@
#define CT_BILLTERMREF "billterm"
void gnc_billterm_sql_initialize( void );
void gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst );
gboolean gnc_sql_save_billterm( GncSqlBackend* be, QofInstance* inst );
#endif /* GNC_BILLTERM_SQL_H */

View File

@@ -147,17 +147,22 @@ create_customer_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_customer( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_CUSTOMER(inst) );
g_return_if_fail( be != NULL );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_CUSTOMER(inst), FALSE );
g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_CUSTOMER, col_table );
return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_CUSTOMER, col_table );
}
/* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_customers_t;
static gboolean
customer_should_be_saved( GncCustomer *customer )
{
@@ -175,25 +180,30 @@ customer_should_be_saved( GncCustomer *customer )
}
static void
write_single_customer( QofInstance *term_p, gpointer be_p )
write_single_customer( QofInstance *term_p, gpointer data_p )
{
GncSqlBackend* be = (GncSqlBackend*)be_p;
write_customers_t* data = (write_customers_t*)data_p;
g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_CUSTOMER(term_p) );
g_return_if_fail( be_p != NULL );
g_return_if_fail( data_p != NULL );
if( customer_should_be_saved( GNC_CUSTOMER(term_p) ) ) {
save_customer( be, term_p );
if( customer_should_be_saved( GNC_CUSTOMER(term_p) ) && data->is_ok ) {
data->is_ok = save_customer( data->be, term_p );
}
}
static void
static gboolean
write_customers( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_customers_t data;
qof_object_foreach( GNC_ID_CUSTOMER, be->primary_book, write_single_customer, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_CUSTOMER, be->primary_book, write_single_customer, (gpointer)&data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -144,17 +144,18 @@ create_employee_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_employee( GncSqlBackend* be, QofInstance* inst )
{
GncEmployee* emp;
const GUID* guid;
gint op;
gboolean is_infant;
gboolean is_ok = TRUE;
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_EMPLOYEE(inst) );
g_return_if_fail( be != NULL );
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);
@@ -168,18 +169,24 @@ save_employee( GncSqlBackend* be, QofInstance* inst )
}
if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db
gnc_sql_save_commodity( be, gncEmployeeGetCurrency( emp ) );
is_ok = gnc_sql_save_commodity( be, gncEmployeeGetCurrency( emp ) );
}
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp, col_table );
if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_EMPLOYEE, emp, col_table );
}
// Now, commit or delete any slots
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else {
gnc_sql_slots_delete( be, guid );
}
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, qof_instance_get_slots( inst ) );
} else {
is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
}
/* ================================================================= */
@@ -198,26 +205,38 @@ employee_should_be_saved( GncEmployee *employee )
return TRUE;
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
write_single_employee( QofInstance *term_p, gpointer be_p )
write_single_employee( QofInstance *term_p, gpointer data_p )
{
GncSqlBackend* be = (GncSqlBackend*)be_p;
write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_EMPLOYEE(term_p) );
g_return_if_fail( be_p != NULL );
g_return_if_fail( data_p != NULL );
if( employee_should_be_saved( GNC_EMPLOYEE(term_p) ) ) {
save_employee( be, term_p );
if( s->is_ok && employee_should_be_saved( GNC_EMPLOYEE(term_p) ) ) {
s->is_ok = save_employee( s->be, term_p );
}
}
static void
static gboolean
write_employees( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
qof_object_foreach( GNC_ID_EMPLOYEE, be->primary_book, write_single_employee, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_EMPLOYEE, be->primary_book, write_single_employee, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -167,40 +167,51 @@ create_entry_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_entry( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_ENTRY(inst) );
g_return_if_fail( be != NULL );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_ENTRY(inst), FALSE );
g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ENTRY, col_table );
return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ENTRY, col_table );
}
/* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
write_single_entry( QofInstance *term_p, gpointer be_p )
write_single_entry( QofInstance *term_p, gpointer data_p )
{
GncSqlBackend* be = (GncSqlBackend*)be_p;
write_objects_t* s = (write_objects_t*)data_p;
GncEntry* entry = GNC_ENTRY(term_p);
g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_ENTRY(term_p) );
g_return_if_fail( be_p != NULL );
g_return_if_fail( data_p != NULL );
/* Only save if attached */
if( gncEntryGetOrder( entry ) != NULL || gncEntryGetInvoice( entry ) != NULL ||
gncEntryGetBill( entry ) != NULL ) {
save_entry( be, term_p );
if( s->is_ok && (gncEntryGetOrder( entry ) != NULL || gncEntryGetInvoice( entry ) != NULL ||
gncEntryGetBill( entry ) != NULL) ) {
s->is_ok = save_entry( s->be, term_p );
}
}
static void
static gboolean
write_entries( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
qof_object_foreach( GNC_ID_ENTRY, be->primary_book, write_single_entry, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_ENTRY, be->primary_book, write_single_entry, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -151,17 +151,18 @@ create_invoice_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_invoice( GncSqlBackend* be, QofInstance* inst )
{
const GUID* guid;
GncInvoice* invoice;
gint op;
gboolean is_infant;
gboolean is_ok = TRUE;
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_INVOICE(inst) );
g_return_if_fail( be != NULL );
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);
@@ -175,18 +176,24 @@ save_invoice( GncSqlBackend* be, QofInstance* inst )
}
if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db
gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) );
is_ok = gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) );
}
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table );
if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table );
}
// Now, commit or delete any slots
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else {
gnc_sql_slots_delete( be, guid );
}
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, qof_instance_get_slots( inst ) );
} else {
is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
}
/* ================================================================= */
@@ -206,26 +213,37 @@ invoice_should_be_saved( GncInvoice *invoice )
return TRUE;
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
write_single_invoice( QofInstance *term_p, gpointer be_p )
write_single_invoice( QofInstance *term_p, gpointer data_p )
{
GncSqlBackend* be = (GncSqlBackend*)be_p;
write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_INVOICE(term_p) );
g_return_if_fail( be_p != NULL );
g_return_if_fail( data_p != NULL );
if( invoice_should_be_saved( GNC_INVOICE(term_p) ) ) {
save_invoice( be, term_p );
if( s->is_ok && invoice_should_be_saved( GNC_INVOICE(term_p) ) ) {
s->is_ok = save_invoice( s->be, term_p );
}
}
static void
static gboolean
write_invoices( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
qof_object_foreach( GNC_ID_INVOICE, be->primary_book, write_single_invoice, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_INVOICE, be->primary_book, write_single_invoice, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -134,14 +134,14 @@ create_job_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_job( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_JOB(inst) );
g_return_if_fail( be != NULL );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_JOB(inst), FALSE );
g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_JOB, col_table );
return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_JOB, col_table );
}
/* ================================================================= */
@@ -161,26 +161,37 @@ job_should_be_saved( GncJob *job )
return TRUE;
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
write_single_job( QofInstance *term_p, gpointer be_p )
write_single_job( QofInstance *term_p, gpointer data_p )
{
GncSqlBackend* be = (GncSqlBackend*)be_p;
write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_JOB(term_p) );
g_return_if_fail( be_p != NULL );
g_return_if_fail( data_p != NULL );
if( job_should_be_saved( GNC_JOB(term_p) ) ) {
save_job( be, term_p );
if( s->is_ok && job_should_be_saved( GNC_JOB(term_p) ) ) {
s->is_ok = save_job( s->be, term_p );
}
}
static void
static gboolean
write_jobs( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
qof_object_foreach( GNC_ID_JOB, be->primary_book, write_single_job, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_JOB, be->primary_book, write_single_job, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -135,14 +135,14 @@ create_order_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_order( GncSqlBackend* be, QofInstance* inst )
{
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_ORDER(inst) );
g_return_if_fail( be != NULL );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_ORDER(inst), FALSE );
g_return_val_if_fail( be != NULL, FALSE );
gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ORDER, col_table );
return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ORDER, col_table );
}
/* ================================================================= */
@@ -162,26 +162,37 @@ order_should_be_saved( GncOrder *order )
return TRUE;
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
write_single_order( QofInstance *term_p, gpointer be_p )
write_single_order( QofInstance *term_p, gpointer data_p )
{
GncSqlBackend* be = (GncSqlBackend*)be_p;
write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_ORDER(term_p) );
g_return_if_fail( be_p != NULL );
g_return_if_fail( data_p != NULL );
if( order_should_be_saved( GNC_ORDER(term_p) ) ) {
save_order( be, term_p );
if( s->is_ok && order_should_be_saved( GNC_ORDER(term_p) ) ) {
s->is_ok = save_order( s->be, term_p );
}
}
static void
static gboolean
write_orders( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
qof_object_foreach( GNC_ID_ORDER, be->primary_book, write_single_order, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_ORDER, be->primary_book, write_single_order, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -268,52 +268,56 @@ create_taxtable_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
delete_all_tt_entries( GncSqlBackend* be, const GUID* guid )
{
guid_info_t guid_info;
g_return_if_fail( be != NULL );
g_return_if_fail( guid != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( guid != NULL, FALSE );
guid_info.be = be;
guid_info.guid = guid;
(void)gnc_sql_do_db_operation( be, OP_DB_DELETE, TTENTRIES_TABLE_NAME,
return gnc_sql_do_db_operation( be, OP_DB_DELETE, TTENTRIES_TABLE_NAME,
TTENTRIES_TABLE_NAME, &guid_info, guid_col_table );
}
static void
static gboolean
save_tt_entries( GncSqlBackend* be, const GUID* guid, GList* entries )
{
GList* entry;
gboolean is_ok;
g_return_if_fail( be != NULL );
g_return_if_fail( guid != NULL );
g_return_val_if_fail( be != NULL, FALSE );
g_return_val_if_fail( guid != NULL, FALSE );
/* First, delete the old entries for this object */
delete_all_tt_entries( be, guid );
is_ok = delete_all_tt_entries( be, guid );
for( entry = entries; entry != NULL; entry = entry->next ) {
for( entry = entries; entry != NULL && is_ok; entry = entry->next ) {
GncTaxTableEntry* e = (GncTaxTableEntry*)entry->data;
(void)gnc_sql_do_db_operation( be,
OP_DB_INSERT,
TTENTRIES_TABLE_NAME,
GNC_ID_TAXTABLE, e,
ttentries_col_table );
is_ok = gnc_sql_do_db_operation( be,
OP_DB_INSERT,
TTENTRIES_TABLE_NAME,
GNC_ID_TAXTABLE, e,
ttentries_col_table );
}
return is_ok;
}
static void
static gboolean
save_taxtable( GncSqlBackend* be, QofInstance* inst )
{
GncTaxTable* tt;
const GUID* guid;
gint op;
gboolean is_infant;
gboolean is_ok;
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_TAXTABLE(inst) );
g_return_if_fail( be != NULL );
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);
@@ -325,32 +329,55 @@ save_taxtable( GncSqlBackend* be, QofInstance* inst )
} else {
op = OP_DB_UPDATE;
}
(void)gnc_sql_do_db_operation( be, op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt, tt_col_table );
is_ok = gnc_sql_do_db_operation( be, op, TT_TABLE_NAME, GNC_ID_TAXTABLE, tt, tt_col_table );
// Now, commit or delete any slots and tax table entries
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
save_tt_entries( be, guid, gncTaxTableGetEntries( tt ) );
} else {
gnc_sql_slots_delete( be, guid );
delete_all_tt_entries( be, guid );
}
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;
}
/* ================================================================= */
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
save_next_taxtable( QofInstance* inst, gpointer p2 )
save_next_taxtable( QofInstance* inst, gpointer data )
{
save_taxtable( (GncSqlBackend*)p2, inst );
write_objects_t* s = (write_objects_t*)data;
if( s->is_ok ) {
s->is_ok = save_taxtable( s->be, inst );
}
}
static void
static gboolean
write_taxtables( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
qof_object_foreach( GNC_ID_TAXTABLE, be->primary_book, save_next_taxtable, be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_TAXTABLE, be->primary_book, save_next_taxtable, &data );
return data.is_ok;
}
/* ================================================================= */

View File

@@ -148,17 +148,18 @@ create_vendor_tables( GncSqlBackend* be )
}
/* ================================================================= */
static void
static gboolean
save_vendor( GncSqlBackend* be, QofInstance* inst )
{
GncVendor* v;
const GUID* guid;
gint op;
gboolean is_infant;
gboolean is_ok = TRUE;
g_return_if_fail( inst != NULL );
g_return_if_fail( GNC_IS_VENDOR(inst) );
g_return_if_fail( be != NULL );
g_return_val_if_fail( inst != NULL, FALSE );
g_return_val_if_fail( GNC_IS_VENDOR(inst), FALSE );
g_return_val_if_fail( be != NULL, FALSE );
v = GNC_VENDOR(inst);
@@ -172,17 +173,23 @@ save_vendor( GncSqlBackend* be, QofInstance* inst )
}
if( op != OP_DB_DELETE ) {
// Ensure the commodity is in the db
gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) );
is_ok = gnc_sql_save_commodity( be, gncVendorGetCurrency( v ) );
}
if( is_ok ) {
is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_VENDOR, v, col_table );
}
(void)gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_VENDOR, v, col_table );
// Now, commit or delete any slots
guid = qof_instance_get_guid( inst );
if( !qof_instance_get_destroying(inst) ) {
gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
} else {
gnc_sql_slots_delete( be, guid );
}
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, qof_instance_get_slots( inst ) );
} else {
is_ok = gnc_sql_slots_delete( be, guid );
}
}
return is_ok;
}
/* ================================================================= */
@@ -202,26 +209,37 @@ vendor_should_be_saved( GncVendor *vendor )
return TRUE;
}
typedef struct {
GncSqlBackend* be;
gboolean is_ok;
} write_objects_t;
static void
write_single_vendor( QofInstance *term_p, gpointer be_p )
write_single_vendor( QofInstance *term_p, gpointer data_p )
{
GncSqlBackend* be = (GncSqlBackend*)be_p;
write_objects_t* s = (write_objects_t*)data_p;
g_return_if_fail( term_p != NULL );
g_return_if_fail( GNC_IS_VENDOR(term_p) );
g_return_if_fail( be_p != NULL );
g_return_if_fail( data_p != NULL );
if( vendor_should_be_saved( GNC_VENDOR(term_p) ) ) {
save_vendor( be, term_p );
if( s->is_ok && vendor_should_be_saved( GNC_VENDOR(term_p) ) ) {
s->is_ok = save_vendor( s->be, term_p );
}
}
static void
static gboolean
write_vendors( GncSqlBackend* be )
{
g_return_if_fail( be != NULL );
write_objects_t data;
qof_object_foreach( GNC_ID_VENDOR, be->primary_book, write_single_vendor, (gpointer)be );
g_return_val_if_fail( be != NULL, FALSE );
data.be = be;
data.is_ok = TRUE;
qof_object_foreach( GNC_ID_VENDOR, be->primary_book, write_single_vendor, &data );
return data.is_ok;
}
/* ================================================================= */