|
GnuCash 2.4.99
|
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 ===================== */
1.7.4