GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-price-sql.c
Go to the documentation of this file.
1 /********************************************************************
2  * gnc-price-sql.c: load and save data to SQL *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA [email protected] *
20 \********************************************************************/
29 #include "config.h"
30 
31 #include <glib.h>
32 
33 #include "qof.h"
34 #include "gnc-pricedb.h"
35 
36 #include "gnc-backend-sql.h"
37 
38 #include "gnc-commodity-sql.h"
39 #include "gnc-price-sql.h"
40 #include "gnc-slots-sql.h"
41 
42 #if defined( S_SPLINT_S )
43 #include "splint-defs.h"
44 #endif
45 
46 /*@ unused @*/ static QofLogModule log_module = G_LOG_DOMAIN;
47 
48 #define TABLE_NAME "prices"
49 #define TABLE_VERSION 2
50 
51 #define PRICE_MAX_SOURCE_LEN 2048
52 #define PRICE_MAX_TYPE_LEN 2048
53 
54 static const GncSqlColumnTableEntry col_table[] =
55 {
56  /*@ -full_init_block @*/
57  { "guid", CT_GUID, 0, COL_NNUL | COL_PKEY, "guid" },
58  { "commodity_guid", CT_COMMODITYREF, 0, COL_NNUL, "commodity" },
59  { "currency_guid", CT_COMMODITYREF, 0, COL_NNUL, "currency" },
60  { "date", CT_TIMESPEC, 0, COL_NNUL, "date" },
61  { "source", CT_STRING, PRICE_MAX_SOURCE_LEN, 0, "source" },
62  { "type", CT_STRING, PRICE_MAX_TYPE_LEN, 0, "type" },
63  { "value", CT_NUMERIC, 0, COL_NNUL, "value" },
64  { NULL }
65  /*@ +full_init_block @*/
66 };
67 
68 /* ================================================================= */
69 
70 static /*@ null @*//*@ dependent @*/ GNCPrice*
71 load_single_price( GncSqlBackend* be, GncSqlRow* row )
72 {
73  GNCPrice* pPrice;
74 
75  g_return_val_if_fail( be != NULL, NULL );
76  g_return_val_if_fail( row != NULL, NULL );
77 
78  pPrice = gnc_price_create( be->book );
79 
80  gnc_price_begin_edit( pPrice );
81  gnc_sql_load_object( be, row, GNC_ID_PRICE, pPrice, col_table );
82  gnc_price_commit_edit( pPrice );
83 
84  return pPrice;
85 }
86 
87 static void
88 load_all_prices( GncSqlBackend* be )
89 {
90  GncSqlStatement* stmt;
91  GncSqlResult* result;
92  QofBook* pBook;
93  GNCPriceDB* pPriceDB;
94 
95  g_return_if_fail( be != NULL );
96 
97  pBook = be->book;
98  pPriceDB = gnc_pricedb_get_db( pBook );
99  stmt = gnc_sql_create_select_statement( be, TABLE_NAME );
100  if ( stmt != NULL )
101  {
102  result = gnc_sql_execute_select_statement( be, stmt );
103  gnc_sql_statement_dispose( stmt );
104  if ( result != NULL )
105  {
106  GNCPrice* pPrice;
107  GncSqlRow* row = gnc_sql_result_get_first_row( result );
108  gchar* sql;
109 
110  gnc_pricedb_set_bulk_update( pPriceDB, TRUE );
111  while ( row != NULL )
112  {
113  pPrice = load_single_price( be, row );
114 
115  if ( pPrice != NULL )
116  {
117  (void)gnc_pricedb_add_price( pPriceDB, pPrice );
118  gnc_price_unref( pPrice );
119  }
120  row = gnc_sql_result_get_next_row( result );
121  }
122  gnc_sql_result_dispose( result );
123  gnc_pricedb_set_bulk_update( pPriceDB, FALSE );
124 
125  sql = g_strdup_printf( "SELECT DISTINCT guid FROM %s", TABLE_NAME );
126  gnc_sql_slots_load_for_sql_subquery( be, sql, (BookLookupFn)gnc_price_lookup );
127  g_free( sql );
128  }
129  }
130 }
131 
132 /* ================================================================= */
133 static void
134 create_prices_tables( GncSqlBackend* be )
135 {
136  gint version;
137 
138  g_return_if_fail( be != NULL );
139 
140  version = gnc_sql_get_table_version( be, TABLE_NAME );
141  if ( version == 0 )
142  {
143  (void)gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
144  }
145  else if ( version == 1 )
146  {
147  /* Upgrade 64 bit int handling */
148  gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
149  (void)gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
150 
151  PINFO("Prices table upgraded from version 1 to version %d\n", TABLE_VERSION);
152  }
153 }
154 
155 /* ================================================================= */
156 
157 static gboolean
158 save_price( GncSqlBackend* be, QofInstance* inst )
159 {
160  GNCPrice* pPrice = GNC_PRICE(inst);
161  gint op;
162  gboolean is_infant;
163  gboolean is_ok = TRUE;
164 
165  g_return_val_if_fail( be != NULL, FALSE );
166  g_return_val_if_fail( inst != NULL, FALSE );
167  g_return_val_if_fail( GNC_IS_PRICE(inst), FALSE );
168 
169  is_infant = qof_instance_get_infant( inst );
170  if ( qof_instance_get_destroying( inst ) )
171  {
172  op = OP_DB_DELETE;
173  }
174  else if ( be->is_pristine_db || is_infant )
175  {
176  op = OP_DB_INSERT;
177  }
178  else
179  {
180  op = OP_DB_UPDATE;
181  }
182 
183  if ( op != OP_DB_DELETE )
184  {
185  /* Ensure commodity and currency are in the db */
186  (void)gnc_sql_save_commodity( be, gnc_price_get_commodity( pPrice ) );
187  is_ok = gnc_sql_save_commodity( be, gnc_price_get_currency( pPrice ) );
188  }
189 
190  if ( is_ok )
191  {
192  is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_PRICE, pPrice, col_table );
193  }
194 
195  return is_ok;
196 }
197 
198 static gboolean
199 write_price( GNCPrice* p, gpointer data )
200 {
201  write_objects_t* s = (write_objects_t*)data;
202 
203  g_return_val_if_fail( p != NULL, FALSE );
204  g_return_val_if_fail( data != NULL, FALSE );
205 
206  if ( s->is_ok )
207  {
208  s->is_ok = save_price( s->be, QOF_INSTANCE(p) );
209  }
210 
211  return s->is_ok;
212 }
213 
214 static gboolean
215 write_prices( GncSqlBackend* be )
216 {
217  GNCPriceDB* priceDB;
218  write_objects_t data;
219 
220  g_return_val_if_fail( be != NULL, FALSE );
221 
222  priceDB = gnc_pricedb_get_db( be->book );
223 
224  data.be = be;
225  data.is_ok = TRUE;
226  return gnc_pricedb_foreach_price( priceDB, write_price, &data, TRUE );
227 }
228 
229 /* ================================================================= */
230 void
231 gnc_sql_init_price_handler( void )
232 {
233  static GncSqlObjectBackend be_data =
234  {
235  GNC_SQL_BACKEND_VERSION,
236  GNC_ID_PRICE,
237  save_price, /* commit */
238  load_all_prices, /* initial_load */
239  create_prices_tables, /* create tables */
240  NULL, NULL, NULL,
241  write_prices /* write */
242  };
243 
244  (void)qof_object_register_backend( GNC_ID_PRICE, GNC_SQL_BACKEND, &be_data );
245 }
246 
247 /* ========================== END OF FILE ===================== */
GNCPrice * gnc_price_create(QofBook *book)
Definition: gnc-pricedb.c:236
gboolean qof_object_register_backend(QofIdTypeConst type_name, const char *backend_name, gpointer be_data)
gint gnc_sql_get_table_version(const GncSqlBackend *be, const gchar *table_name)
void gnc_sql_upgrade_table(GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
a simple price database for gnucash
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
#define PINFO(format, args...)
Definition: qoflog.h:249
load and save data to SQL
load and save accounts data to SQL
GncSqlStatement * gnc_sql_create_select_statement(GncSqlBackend *be, const gchar *table_name)
#define COL_NNUL
void gnc_price_unref(GNCPrice *p)
Definition: gnc-pricedb.c:272
gboolean qof_instance_get_destroying(gconstpointer ptr)
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Definition: gnc-pricedb.c:1053
gboolean gnc_sql_create_table(GncSqlBackend *be, const gchar *table_name, gint table_version, const GncSqlColumnTableEntry *col_table)
load and save data to SQL
load and save data to SQL
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Definition: gnc-pricedb.c:872
QofBook * book
#define COL_PKEY
void gnc_sql_slots_load_for_sql_subquery(GncSqlBackend *be, const gchar *subquery, BookLookupFn lookup_fn)
gboolean gnc_sql_set_table_version(GncSqlBackend *be, const gchar *table_name, gint version)
gboolean gnc_pricedb_foreach_price(GNCPriceDB *db, gboolean(*f)(GNCPrice *p, gpointer user_data), gpointer user_data, gboolean stable_order)
Definition: gnc-pricedb.c:2344
GncSqlResult * gnc_sql_execute_select_statement(GncSqlBackend *be, GncSqlStatement *stmt)
void gnc_sql_load_object(const GncSqlBackend *be, GncSqlRow *row, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
gboolean is_pristine_db
void gnc_pricedb_set_bulk_update(GNCPriceDB *db, gboolean bulk_update)
Definition: gnc-pricedb.c:844
gboolean gnc_sql_do_db_operation(GncSqlBackend *be, E_DB_OPERATION op, const gchar *table_name, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
const gchar * QofLogModule
Definition: qofid.h:89