GnuCash 2.4.99
gnc-price-sql.c
Go to the documentation of this file.
00001 /********************************************************************
00002  * gnc-price-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 "gnc-pricedb.h"
00035 
00036 #include "gnc-backend-sql.h"
00037 
00038 #include "gnc-commodity-sql.h"
00039 #include "gnc-price-sql.h"
00040 #include "gnc-slots-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 "prices"
00049 #define TABLE_VERSION 2
00050 
00051 #define PRICE_MAX_SOURCE_LEN 2048
00052 #define PRICE_MAX_TYPE_LEN 2048
00053 
00054 static const GncSqlColumnTableEntry col_table[] =
00055 {
00056     /*@ -full_init_block @*/
00057     { "guid",           CT_GUID,           0,                    COL_NNUL | COL_PKEY, "guid" },
00058     { "commodity_guid", CT_COMMODITYREF,   0,                    COL_NNUL,          "commodity" },
00059     { "currency_guid",  CT_COMMODITYREF,   0,                    COL_NNUL,          "currency" },
00060     { "date",           CT_TIMESPEC,       0,                    COL_NNUL,          "date" },
00061     { "source",         CT_STRING,         PRICE_MAX_SOURCE_LEN, 0,                 "source" },
00062     { "type",           CT_STRING,         PRICE_MAX_TYPE_LEN,   0,                 "type" },
00063     { "value",          CT_NUMERIC,        0,                    COL_NNUL,          "value" },
00064     { NULL }
00065     /*@ +full_init_block @*/
00066 };
00067 
00068 /* ================================================================= */
00069 
00070 static /*@ null @*//*@ dependent @*/ GNCPrice*
00071 load_single_price( GncSqlBackend* be, GncSqlRow* row )
00072 {
00073     GNCPrice* pPrice;
00074 
00075     g_return_val_if_fail( be != NULL, NULL );
00076     g_return_val_if_fail( row != NULL, NULL );
00077 
00078     pPrice = gnc_price_create( be->book );
00079 
00080     gnc_price_begin_edit( pPrice );
00081     gnc_sql_load_object( be, row, GNC_ID_PRICE, pPrice, col_table );
00082     gnc_price_commit_edit( pPrice );
00083 
00084     return pPrice;
00085 }
00086 
00087 static void
00088 load_all_prices( GncSqlBackend* be )
00089 {
00090     GncSqlStatement* stmt;
00091     GncSqlResult* result;
00092     QofBook* pBook;
00093     GNCPriceDB* pPriceDB;
00094 
00095     g_return_if_fail( be != NULL );
00096 
00097     pBook = be->book;
00098     pPriceDB = gnc_pricedb_get_db( pBook );
00099     stmt = gnc_sql_create_select_statement( be, TABLE_NAME );
00100     if ( stmt != NULL )
00101     {
00102         result = gnc_sql_execute_select_statement( be, stmt );
00103         gnc_sql_statement_dispose( stmt );
00104         if ( result != NULL )
00105         {
00106             GNCPrice* pPrice;
00107             GncSqlRow* row = gnc_sql_result_get_first_row( result );
00108             gchar* sql;
00109 
00110             gnc_pricedb_set_bulk_update( pPriceDB, TRUE );
00111             while ( row != NULL )
00112             {
00113                 pPrice = load_single_price( be, row );
00114 
00115                 if ( pPrice != NULL )
00116                 {
00117                     (void)gnc_pricedb_add_price( pPriceDB, pPrice );
00118                     gnc_price_unref( pPrice );
00119                 }
00120                 row = gnc_sql_result_get_next_row( result );
00121             }
00122             gnc_sql_result_dispose( result );
00123             gnc_pricedb_set_bulk_update( pPriceDB, FALSE );
00124 
00125             sql = g_strdup_printf( "SELECT DISTINCT guid FROM %s", TABLE_NAME );
00126             gnc_sql_slots_load_for_sql_subquery( be, sql, (BookLookupFn)gnc_price_lookup );
00127             g_free( sql );
00128         }
00129     }
00130 }
00131 
00132 /* ================================================================= */
00133 static void
00134 create_prices_tables( GncSqlBackend* be )
00135 {
00136     gint version;
00137 
00138     g_return_if_fail( be != NULL );
00139 
00140     version = gnc_sql_get_table_version( be, TABLE_NAME );
00141     if ( version == 0 )
00142     {
00143         (void)gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
00144     }
00145     else if ( version == 1 )
00146     {
00147         /* Upgrade 64 bit int handling */
00148         gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
00149         (void)gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
00150 
00151         PINFO("Prices table upgraded from version 1 to version %d\n", TABLE_VERSION);
00152     }
00153 }
00154 
00155 /* ================================================================= */
00156 
00157 static gboolean
00158 save_price( GncSqlBackend* be, QofInstance* inst )
00159 {
00160     GNCPrice* pPrice = GNC_PRICE(inst);
00161     gint op;
00162     gboolean is_infant;
00163     gboolean is_ok = TRUE;
00164 
00165     g_return_val_if_fail( be != NULL, FALSE );
00166     g_return_val_if_fail( inst != NULL, FALSE );
00167     g_return_val_if_fail( GNC_IS_PRICE(inst), FALSE );
00168 
00169     is_infant = qof_instance_get_infant( inst );
00170     if ( qof_instance_get_destroying( inst ) )
00171     {
00172         op = OP_DB_DELETE;
00173     }
00174     else if ( be->is_pristine_db || is_infant )
00175     {
00176         op = OP_DB_INSERT;
00177     }
00178     else
00179     {
00180         op = OP_DB_UPDATE;
00181     }
00182 
00183     if ( op != OP_DB_DELETE )
00184     {
00185         /* Ensure commodity and currency are in the db */
00186         (void)gnc_sql_save_commodity( be, gnc_price_get_commodity( pPrice ) );
00187         is_ok = gnc_sql_save_commodity( be, gnc_price_get_currency( pPrice ) );
00188     }
00189 
00190     if ( is_ok )
00191     {
00192         is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table );
00193     }
00194 
00195     return is_ok;
00196 }
00197 
00198 static gboolean
00199 write_price( GNCPrice* p, gpointer data )
00200 {
00201     write_objects_t* s = (write_objects_t*)data;
00202 
00203     g_return_val_if_fail( p != NULL, FALSE );
00204     g_return_val_if_fail( data != NULL, FALSE );
00205 
00206     if ( s->is_ok )
00207     {
00208         s->is_ok = save_price( s->be, QOF_INSTANCE(p) );
00209     }
00210 
00211     return s->is_ok;
00212 }
00213 
00214 static gboolean
00215 write_prices( GncSqlBackend* be )
00216 {
00217     GNCPriceDB* priceDB;
00218     write_objects_t data;
00219 
00220     g_return_val_if_fail( be != NULL, FALSE );
00221 
00222     priceDB = gnc_pricedb_get_db( be->book );
00223 
00224     data.be = be;
00225     data.is_ok = TRUE;
00226     return gnc_pricedb_foreach_price( priceDB, write_price, &data, TRUE );
00227 }
00228 
00229 /* ================================================================= */
00230 void
00231 gnc_sql_init_price_handler( void )
00232 {
00233     static GncSqlObjectBackend be_data =
00234     {
00235         GNC_SQL_BACKEND_VERSION,
00236         GNC_ID_PRICE,
00237         save_price,                     /* commit */
00238         load_all_prices,            /* initial_load */
00239         create_prices_tables,           /* create tables */
00240         NULL, NULL, NULL,
00241         write_prices                            /* write */
00242     };
00243 
00244     (void)qof_object_register_backend( GNC_ID_PRICE, GNC_SQL_BACKEND, &be_data );
00245 }
00246 
00247 /* ========================== END OF FILE ===================== */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines