GnuCash 2.4.99
gnc-commodity-sql.c
Go to the documentation of this file.
00001 /********************************************************************
00002  * gnc-commodity-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 
00035 #include "gnc-backend-sql.h"
00036 #include "gnc-commodity.h"
00037 
00038 #include "gnc-commodity-sql.h"
00039 #include "gnc-slots-sql.h"
00040 
00041 #if defined( S_SPLINT_S )
00042 #include "splint-defs.h"
00043 #endif
00044 
00045 /*@ unused @*/ static QofLogModule log_module = G_LOG_DOMAIN;
00046 
00047 static /*@ dependent @*//*@ null @*/ gpointer get_quote_source_name( gpointer pObject );
00048 static void set_quote_source_name( gpointer pObject, /*@ null @*/ gpointer pValue );
00049 
00050 #define COMMODITIES_TABLE "commodities"
00051 #define TABLE_VERSION 1
00052 
00053 #define COMMODITY_MAX_NAMESPACE_LEN 2048
00054 #define COMMODITY_MAX_MNEMONIC_LEN 2048
00055 #define COMMODITY_MAX_FULLNAME_LEN 2048
00056 #define COMMODITY_MAX_CUSIP_LEN 2048
00057 #define COMMODITY_MAX_QUOTESOURCE_LEN 2048
00058 #define COMMODITY_MAX_QUOTE_TZ_LEN 2048
00059 
00060 static const GncSqlColumnTableEntry col_table[] =
00061 {
00062     /*@ -full_init_block @*/
00063     { "guid",         CT_GUID,    0,                             COL_NNUL | COL_PKEY, "guid" },
00064     {
00065         "namespace",    CT_STRING,  COMMODITY_MAX_NAMESPACE_LEN,   COL_NNUL,          NULL, NULL,
00066         (QofAccessFunc)gnc_commodity_get_namespace,
00067         (QofSetterFunc)gnc_commodity_set_namespace
00068     },
00069     { "mnemonic",     CT_STRING,  COMMODITY_MAX_MNEMONIC_LEN,    COL_NNUL,          "mnemonic" },
00070     { "fullname",     CT_STRING,  COMMODITY_MAX_FULLNAME_LEN,    0,                 "fullname" },
00071     { "cusip",        CT_STRING,  COMMODITY_MAX_CUSIP_LEN,       0,                 "cusip" },
00072     { "fraction",     CT_INT,     0,                             COL_NNUL,          "fraction" },
00073     { "quote_flag",   CT_BOOLEAN, 0,                             COL_NNUL,          "quote_flag" },
00074     {
00075         "quote_source", CT_STRING,  COMMODITY_MAX_QUOTESOURCE_LEN, 0,                 NULL, NULL,
00076         (QofAccessFunc)get_quote_source_name, set_quote_source_name
00077     },
00078     { "quote_tz",     CT_STRING,  COMMODITY_MAX_QUOTE_TZ_LEN,    0,                 "quote-tz" },
00079     { NULL }
00080     /*@ +full_init_block @*/
00081 };
00082 
00083 /* ================================================================= */
00084 
00085 static /*@ dependent @*//*@ null @*/ gpointer
00086 get_quote_source_name( gpointer pObject )
00087 {
00088     const gnc_commodity* pCommodity;
00089 
00090     g_return_val_if_fail( pObject != NULL, NULL );
00091     g_return_val_if_fail( GNC_IS_COMMODITY(pObject), NULL );
00092 
00093     pCommodity = GNC_COMMODITY(pObject);
00094     return (gpointer)gnc_quote_source_get_internal_name(
00095                gnc_commodity_get_quote_source(pCommodity));
00096 }
00097 
00098 static void
00099 set_quote_source_name( gpointer pObject, gpointer pValue )
00100 {
00101     gnc_commodity* pCommodity;
00102     const gchar* quote_source_name = (const gchar*)pValue;
00103     gnc_quote_source* quote_source;
00104 
00105     g_return_if_fail( pObject != NULL );
00106     g_return_if_fail( GNC_IS_COMMODITY(pObject) );
00107 
00108     if ( pValue == NULL ) return;
00109 
00110     pCommodity = GNC_COMMODITY(pObject);
00111     quote_source = gnc_quote_source_lookup_by_internal( quote_source_name );
00112     gnc_commodity_set_quote_source( pCommodity, quote_source );
00113 }
00114 
00115 static /*@ dependent @*/ gnc_commodity*
00116 load_single_commodity( GncSqlBackend* be, GncSqlRow* row )
00117 {
00118     QofBook* pBook = be->book;
00119     gnc_commodity* pCommodity;
00120 
00121     pCommodity = gnc_commodity_new( pBook, NULL, NULL, NULL, NULL, 100 );
00122     gnc_commodity_begin_edit( pCommodity );
00123     gnc_sql_load_object( be, row, GNC_ID_COMMODITY, pCommodity, col_table );
00124     gnc_commodity_commit_edit( pCommodity );
00125 
00126     return pCommodity;
00127 }
00128 
00129 static void
00130 load_all_commodities( GncSqlBackend* be )
00131 {
00132     GncSqlStatement* stmt;
00133     GncSqlResult* result;
00134     gnc_commodity_table* pTable;
00135 
00136     pTable = gnc_commodity_table_get_table( be->book );
00137     stmt = gnc_sql_create_select_statement( be, COMMODITIES_TABLE );
00138     if ( stmt == NULL ) return;
00139     result = gnc_sql_execute_select_statement( be, stmt );
00140     gnc_sql_statement_dispose( stmt );
00141     if ( result != NULL )
00142     {
00143         gnc_commodity* pCommodity;
00144         GncSqlRow* row = gnc_sql_result_get_first_row( result );
00145         gchar* sql;
00146 
00147         while ( row != NULL )
00148         {
00149             pCommodity = load_single_commodity( be, row );
00150 
00151             if ( pCommodity != NULL )
00152             {
00153                 GncGUID guid;
00154 
00155                 guid = *qof_instance_get_guid( QOF_INSTANCE(pCommodity) );
00156                 pCommodity = gnc_commodity_table_insert( pTable, pCommodity );
00157                 qof_instance_set_guid( QOF_INSTANCE(pCommodity), &guid );
00158             }
00159             row = gnc_sql_result_get_next_row( result );
00160         }
00161         gnc_sql_result_dispose( result );
00162 
00163         sql = g_strdup_printf( "SELECT DISTINCT guid FROM %s", COMMODITIES_TABLE );
00164         gnc_sql_slots_load_for_sql_subquery( be, sql,
00165                                              (BookLookupFn)gnc_commodity_find_commodity_by_guid );
00166         g_free( sql );
00167     }
00168 }
00169 /* ================================================================= */
00170 static void
00171 create_commodities_tables( GncSqlBackend* be )
00172 {
00173     gint version;
00174 
00175     g_return_if_fail( be != NULL );
00176 
00177     version = gnc_sql_get_table_version( be, COMMODITIES_TABLE );
00178     if ( version == 0 )
00179     {
00180         (void)gnc_sql_create_table( be, COMMODITIES_TABLE, TABLE_VERSION, col_table );
00181     }
00182 }
00183 
00184 /* ================================================================= */
00185 static gboolean
00186 do_commit_commodity( GncSqlBackend* be, QofInstance* inst, gboolean force_insert )
00187 {
00188     const GncGUID* guid;
00189     gboolean is_infant;
00190     gint op;
00191     gboolean is_ok;
00192 
00193     is_infant = qof_instance_get_infant( inst );
00194     if ( qof_instance_get_destroying( inst ) )
00195     {
00196         op = OP_DB_DELETE;
00197     }
00198     else if ( be->is_pristine_db || is_infant || force_insert )
00199     {
00200         op = OP_DB_INSERT;
00201     }
00202     else
00203     {
00204         op = OP_DB_UPDATE;
00205     }
00206     is_ok = gnc_sql_do_db_operation( be, op, COMMODITIES_TABLE, GNC_ID_COMMODITY, inst, col_table );
00207 
00208     if ( is_ok )
00209     {
00210         // Now, commit any slots
00211         guid = qof_instance_get_guid( inst );
00212         if ( !qof_instance_get_destroying(inst) )
00213         {
00214             is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
00215         }
00216         else
00217         {
00218             is_ok = gnc_sql_slots_delete( be, guid );
00219         }
00220     }
00221 
00222     return is_ok;
00223 }
00224 
00225 static gboolean
00226 commit_commodity( GncSqlBackend* be, QofInstance* inst )
00227 {
00228     g_return_val_if_fail( be != NULL, FALSE );
00229     g_return_val_if_fail( inst != NULL, FALSE );
00230     g_return_val_if_fail( GNC_IS_COMMODITY(inst), FALSE );
00231 
00232     return do_commit_commodity( be, inst, FALSE );
00233 }
00234 
00235 static gboolean
00236 is_commodity_in_db( GncSqlBackend* be, gnc_commodity* pCommodity )
00237 {
00238     g_return_val_if_fail( be != NULL, FALSE );
00239     g_return_val_if_fail( pCommodity != NULL, FALSE );
00240 
00241     return gnc_sql_object_is_it_in_db( be, COMMODITIES_TABLE, GNC_ID_COMMODITY,
00242                                        pCommodity, col_table );
00243 }
00244 
00245 gboolean
00246 gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity )
00247 {
00248     gboolean is_ok = TRUE;
00249 
00250     g_return_val_if_fail( be != NULL, FALSE );
00251     g_return_val_if_fail( pCommodity != NULL, FALSE );
00252 
00253     if ( !is_commodity_in_db( be, pCommodity ) )
00254     {
00255         is_ok = do_commit_commodity( be, QOF_INSTANCE(pCommodity), TRUE );
00256     }
00257 
00258     return is_ok;
00259 }
00260 
00261 /* ----------------------------------------------------------------- */
00262 
00263 static void
00264 load_commodity_guid( const GncSqlBackend* be, GncSqlRow* row,
00265                      /*@ null @*/ QofSetterFunc setter, gpointer pObject,
00266                      const GncSqlColumnTableEntry* table_row )
00267 {
00268     const GValue* val;
00269     GncGUID guid;
00270     gnc_commodity* commodity = NULL;
00271 
00272     g_return_if_fail( be != NULL );
00273     g_return_if_fail( row != NULL );
00274     g_return_if_fail( pObject != NULL );
00275     g_return_if_fail( table_row != NULL );
00276 
00277     val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
00278     if ( val != NULL && G_VALUE_HOLDS_STRING( val ) && g_value_get_string( val ) != NULL )
00279     {
00280         (void)string_to_guid( g_value_get_string( val ), &guid );
00281         commodity = gnc_commodity_find_commodity_by_guid( &guid, be->book );
00282         if ( commodity != NULL )
00283         {
00284             if ( table_row->gobj_param_name != NULL )
00285             {
00286                 g_object_set( pObject, table_row->gobj_param_name, commodity, NULL );
00287             }
00288             else if ( setter != NULL )
00289             {
00290                 (*setter)( pObject, (const gpointer)commodity );
00291             }
00292         }
00293         else
00294         {
00295             PWARN( "Commodity ref '%s' not found", g_value_get_string( val ) );
00296         }
00297     }
00298 }
00299 
00300 static GncSqlColumnTypeHandler commodity_guid_handler
00301 = { load_commodity_guid,
00302     gnc_sql_add_objectref_guid_col_info_to_list,
00303     gnc_sql_add_colname_to_list,
00304     gnc_sql_add_gvalue_objectref_guid_to_slist
00305   };
00306 /* ================================================================= */
00307 void
00308 gnc_sql_init_commodity_handler( void )
00309 {
00310     static GncSqlObjectBackend be_data =
00311     {
00312         GNC_SQL_BACKEND_VERSION,
00313         GNC_ID_COMMODITY,
00314         commit_commodity,            /* commit */
00315         load_all_commodities,        /* initial_load */
00316         create_commodities_tables,   /* create_tables */
00317         NULL,                        /* compile_query */
00318         NULL,                        /* run_query */
00319         NULL,                        /* free_query */
00320         NULL                         /* write */
00321     };
00322 
00323     (void)qof_object_register_backend( GNC_ID_COMMODITY, GNC_SQL_BACKEND, &be_data );
00324 
00325     gnc_sql_register_col_type_handler( CT_COMMODITYREF, &commodity_guid_handler );
00326 }
00327 /* ========================== END OF FILE ===================== */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines