GnuCash 2.4.99
gnc-lots-sql.c
Go to the documentation of this file.
00001 /********************************************************************
00002  * gnc-lots-sql.c: load and save data to SQL                        *
00003  *                                                                  *
00004  * This program is free software; you can redistribute it and/or    *
00005  * modify it under the terms of the GNU General Public License as   *
00006  * published by the Free Software Foundation; either version 2 of   *
00007  * the License, or (at your option) any later version.              *
00008  *                                                                  *
00009  * This program is distributed in the hope that it will be useful,  *
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00012  * GNU General Public License for more details.                     *
00013  *                                                                  *
00014  * You should have received a copy of the GNU General Public License*
00015  * along with this program; if not, contact:                        *
00016  *                                                                  *
00017  * Free Software Foundation           Voice:  +1-617-542-5942       *
00018  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00019  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00020 \********************************************************************/
00029 #include "config.h"
00030 
00031 #include <glib.h>
00032 
00033 #include "qof.h"
00034 #include "Account.h"
00035 #include "gnc-lot.h"
00036 
00037 #include "gnc-backend-sql.h"
00038 #include "gnc-slots-sql.h"
00039 
00040 #include "gnc-lots-sql.h"
00041 
00042 #if defined( S_SPLINT_S )
00043 #include "splint-defs.h"
00044 #endif
00045 
00046 /*@ unused @*/ static QofLogModule log_module = G_LOG_DOMAIN;
00047 
00048 #define TABLE_NAME "lots"
00049 #define TABLE_VERSION 2
00050 
00051 static /*@ dependent @*//*@ null @*/ gpointer get_lot_account( gpointer pObject );
00052 static void set_lot_account( gpointer pObject, /*@ null @*/ gpointer pValue );
00053 
00054 static const GncSqlColumnTableEntry col_table[] =
00055 {
00056     /*@ -full_init_block @*/
00057     { "guid",         CT_GUID,       0, COL_NNUL | COL_PKEY, "guid" },
00058     {
00059         "account_guid", CT_ACCOUNTREF, 0, 0,                 NULL, NULL,
00060         (QofAccessFunc)get_lot_account,   set_lot_account
00061     },
00062     { "is_closed",    CT_BOOLEAN,    0, COL_NNUL,          "is-closed" },
00063     { NULL }
00064     /*@ +full_init_block @*/
00065 };
00066 
00067 /* ================================================================= */
00068 static /*@ dependent @*//*@ null @*/ gpointer
00069 get_lot_account( gpointer pObject )
00070 {
00071     const GNCLot* lot;
00072     Account* pAccount;
00073 
00074     g_return_val_if_fail( pObject != NULL, NULL );
00075     g_return_val_if_fail( GNC_IS_LOT(pObject), NULL );
00076 
00077     lot = GNC_LOT(pObject);
00078     pAccount = gnc_lot_get_account( lot );
00079     return pAccount;
00080 }
00081 
00082 static void
00083 set_lot_account( gpointer pObject, /*@ null @*/ gpointer pValue )
00084 {
00085     GNCLot* lot;
00086     Account* pAccount;
00087 
00088     g_return_if_fail( pObject != NULL && GNC_IS_LOT(pObject) );
00089     g_return_if_fail( pValue == NULL || GNC_IS_ACCOUNT(pValue) );
00090 
00091     lot = GNC_LOT(pObject);
00092     pAccount = GNC_ACCOUNT(pValue);
00093     if ( pAccount != NULL )
00094     {
00095         xaccAccountInsertLot( pAccount, lot );
00096     }
00097 }
00098 
00099 static /*@ dependent @*//*@ null @*/ GNCLot*
00100 load_single_lot( GncSqlBackend* be, GncSqlRow* row )
00101 {
00102     GNCLot* lot;
00103 
00104     g_return_val_if_fail( be != NULL, NULL );
00105     g_return_val_if_fail( row != NULL, NULL );
00106 
00107     lot = gnc_lot_new( be->book );
00108 
00109     gnc_lot_begin_edit( lot );
00110     gnc_sql_load_object( be, row, GNC_ID_LOT, lot, col_table );
00111     gnc_lot_commit_edit( lot );
00112 
00113     return lot;
00114 }
00115 
00116 static void
00117 load_all_lots( GncSqlBackend* be )
00118 {
00119     GncSqlStatement* stmt;
00120     GncSqlResult* result;
00121 
00122     g_return_if_fail( be != NULL );
00123 
00124     stmt = gnc_sql_create_select_statement( be, TABLE_NAME );
00125     if ( stmt != NULL )
00126     {
00127         result = gnc_sql_execute_select_statement( be, stmt );
00128         gnc_sql_statement_dispose( stmt );
00129         if ( result != NULL )
00130         {
00131             GncSqlRow* row = gnc_sql_result_get_first_row( result );
00132             GNCLot* lot;
00133             gchar* sql;
00134 
00135             while ( row != NULL )
00136             {
00137                 lot = load_single_lot( be, row );
00138                 row = gnc_sql_result_get_next_row( result );
00139             }
00140             gnc_sql_result_dispose( result );
00141 
00142             sql = g_strdup_printf( "SELECT DISTINCT guid FROM %s", TABLE_NAME );
00143             gnc_sql_slots_load_for_sql_subquery( be, sql, (BookLookupFn)gnc_lot_lookup );
00144             g_free( sql );
00145         }
00146     }
00147 }
00148 
00149 /* ================================================================= */
00150 static void
00151 create_lots_tables( GncSqlBackend* be )
00152 {
00153     gint version;
00154 
00155     g_return_if_fail( be != NULL );
00156 
00157     version = gnc_sql_get_table_version( be, TABLE_NAME );
00158     if ( version == 0 )
00159     {
00160         /* The table doesn't exist, so create it */
00161         (void)gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
00162     }
00163     else if ( version == 1 )
00164     {
00165         /* Version 1 -> 2 removes the 'NOT NULL' constraint on the account_guid
00166         field.
00167 
00168         Create a temporary table, copy the data from the old table, delete the
00169         old table, then rename the new one. */
00170 
00171         gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
00172         (void)gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
00173 
00174         PINFO("Lots table upgraded from version 1 to version %d\n", TABLE_VERSION);
00175     }
00176 }
00177 
00178 /* ================================================================= */
00179 
00180 static gboolean
00181 commit_lot( GncSqlBackend* be, QofInstance* inst )
00182 {
00183     g_return_val_if_fail( be != NULL, FALSE );
00184     g_return_val_if_fail( inst != NULL, FALSE );
00185     g_return_val_if_fail( GNC_IS_LOT(inst), FALSE );
00186 
00187     return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_LOT, col_table );
00188 }
00189 
00190 static void
00191 do_save_lot( QofInstance* inst, gpointer data )
00192 {
00193     write_objects_t* s = (write_objects_t*)data;
00194 
00195     if ( s->is_ok )
00196     {
00197         s->is_ok = commit_lot( s->be, inst );
00198     }
00199 }
00200 
00201 static gboolean
00202 write_lots( GncSqlBackend* be )
00203 {
00204     write_objects_t data;
00205 
00206     g_return_val_if_fail( be != NULL, FALSE );
00207 
00208     data.be = be;
00209     data.is_ok = TRUE;
00210     qof_collection_foreach( qof_book_get_collection( be->book, GNC_ID_LOT ),
00211                             (QofInstanceForeachCB)do_save_lot, &data );
00212     return data.is_ok;
00213 }
00214 
00215 /* ================================================================= */
00216 static void
00217 load_lot_guid( const GncSqlBackend* be, GncSqlRow* row,
00218                /*@ null @*/ QofSetterFunc setter, gpointer pObject,
00219                const GncSqlColumnTableEntry* table_row )
00220 {
00221     const GValue* val;
00222     GncGUID guid;
00223     GNCLot* lot;
00224 
00225     g_return_if_fail( be != NULL );
00226     g_return_if_fail( row != NULL );
00227     g_return_if_fail( pObject != NULL );
00228     g_return_if_fail( table_row != NULL );
00229 
00230     val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
00231     if ( val != NULL && G_VALUE_HOLDS_STRING( val ) && g_value_get_string( val ) != NULL )
00232     {
00233         (void)string_to_guid( g_value_get_string( val ), &guid );
00234         lot = gnc_lot_lookup( &guid, be->book );
00235         if ( lot != NULL )
00236         {
00237             if ( table_row->gobj_param_name != NULL )
00238             {
00239                 g_object_set( pObject, table_row->gobj_param_name, lot, NULL );
00240             }
00241             else
00242             {
00243                 g_return_if_fail( setter != NULL );
00244                 (*setter)( pObject, (const gpointer)lot );
00245             }
00246         }
00247         else
00248         {
00249             PWARN( "Lot ref '%s' not found", g_value_get_string( val ) );
00250         }
00251     }
00252 }
00253 
00254 static GncSqlColumnTypeHandler lot_guid_handler
00255 = { load_lot_guid,
00256     gnc_sql_add_objectref_guid_col_info_to_list,
00257     gnc_sql_add_colname_to_list,
00258     gnc_sql_add_gvalue_objectref_guid_to_slist
00259   };
00260 /* ================================================================= */
00261 void
00262 gnc_sql_init_lot_handler( void )
00263 {
00264     static GncSqlObjectBackend be_data =
00265     {
00266         GNC_SQL_BACKEND_VERSION,
00267         GNC_ID_LOT,
00268         commit_lot,            /* commit */
00269         load_all_lots,         /* initial_load */
00270         create_lots_tables,    /* create tables */
00271         NULL, NULL, NULL,
00272         write_lots             /* save all */
00273     };
00274 
00275     (void)qof_object_register_backend( GNC_ID_LOT, GNC_SQL_BACKEND, &be_data );
00276 
00277     gnc_sql_register_col_type_handler( CT_LOTREF, &lot_guid_handler );
00278 }
00279 
00280 /* ========================== END OF FILE ===================== */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines