GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-commodity-sql.c
Go to the documentation of this file.
1 /********************************************************************
2  * gnc-commodity-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 
35 #include "gnc-backend-sql.h"
36 #include "gnc-commodity.h"
37 
38 #include "gnc-commodity-sql.h"
39 #include "gnc-slots-sql.h"
40 
41 #if defined( S_SPLINT_S )
42 #include "splint-defs.h"
43 #endif
44 
45 /*@ unused @*/ static QofLogModule log_module = G_LOG_DOMAIN;
46 
47 static /*@ dependent @*//*@ null @*/ gpointer get_quote_source_name( gpointer pObject );
48 static void set_quote_source_name( gpointer pObject, /*@ null @*/ gpointer pValue );
49 
50 #define COMMODITIES_TABLE "commodities"
51 #define TABLE_VERSION 1
52 
53 #define COMMODITY_MAX_NAMESPACE_LEN 2048
54 #define COMMODITY_MAX_MNEMONIC_LEN 2048
55 #define COMMODITY_MAX_FULLNAME_LEN 2048
56 #define COMMODITY_MAX_CUSIP_LEN 2048
57 #define COMMODITY_MAX_QUOTESOURCE_LEN 2048
58 #define COMMODITY_MAX_QUOTE_TZ_LEN 2048
59 
60 static const GncSqlColumnTableEntry col_table[] =
61 {
62  /*@ -full_init_block @*/
63  { "guid", CT_GUID, 0, COL_NNUL | COL_PKEY, "guid" },
64  {
65  "namespace", CT_STRING, COMMODITY_MAX_NAMESPACE_LEN, COL_NNUL, NULL, NULL,
68  },
69  { "mnemonic", CT_STRING, COMMODITY_MAX_MNEMONIC_LEN, COL_NNUL, "mnemonic" },
70  { "fullname", CT_STRING, COMMODITY_MAX_FULLNAME_LEN, 0, "fullname" },
71  { "cusip", CT_STRING, COMMODITY_MAX_CUSIP_LEN, 0, "cusip" },
72  { "fraction", CT_INT, 0, COL_NNUL, "fraction" },
73  { "quote_flag", CT_BOOLEAN, 0, COL_NNUL, "quote_flag" },
74  {
75  "quote_source", CT_STRING, COMMODITY_MAX_QUOTESOURCE_LEN, 0, NULL, NULL,
76  (QofAccessFunc)get_quote_source_name, set_quote_source_name
77  },
78  { "quote_tz", CT_STRING, COMMODITY_MAX_QUOTE_TZ_LEN, 0, "quote-tz" },
79  { NULL }
80  /*@ +full_init_block @*/
81 };
82 
83 /* ================================================================= */
84 
85 static /*@ dependent @*//*@ null @*/ gpointer
86 get_quote_source_name( gpointer pObject )
87 {
88  const gnc_commodity* pCommodity;
89 
90  g_return_val_if_fail( pObject != NULL, NULL );
91  g_return_val_if_fail( GNC_IS_COMMODITY(pObject), NULL );
92 
93  pCommodity = GNC_COMMODITY(pObject);
94  return (gpointer)gnc_quote_source_get_internal_name(
95  gnc_commodity_get_quote_source(pCommodity));
96 }
97 
98 static void
99 set_quote_source_name( gpointer pObject, gpointer pValue )
100 {
101  gnc_commodity* pCommodity;
102  const gchar* quote_source_name = (const gchar*)pValue;
103  gnc_quote_source* quote_source;
104 
105  g_return_if_fail( pObject != NULL );
106  g_return_if_fail( GNC_IS_COMMODITY(pObject) );
107 
108  if ( pValue == NULL ) return;
109 
110  pCommodity = GNC_COMMODITY(pObject);
111  quote_source = gnc_quote_source_lookup_by_internal( quote_source_name );
112  gnc_commodity_set_quote_source( pCommodity, quote_source );
113 }
114 
115 static /*@ dependent @*/ gnc_commodity*
116 load_single_commodity( GncSqlBackend* be, GncSqlRow* row )
117 {
118  QofBook* pBook = be->book;
119  gnc_commodity* pCommodity;
120 
121  pCommodity = gnc_commodity_new( pBook, NULL, NULL, NULL, NULL, 100 );
122  gnc_commodity_begin_edit( pCommodity );
123  gnc_sql_load_object( be, row, GNC_ID_COMMODITY, pCommodity, col_table );
124  gnc_commodity_commit_edit( pCommodity );
125 
126  return pCommodity;
127 }
128 
129 static void
130 load_all_commodities( GncSqlBackend* be )
131 {
132  GncSqlStatement* stmt;
133  GncSqlResult* result;
134  gnc_commodity_table* pTable;
135 
136  pTable = gnc_commodity_table_get_table( be->book );
137  stmt = gnc_sql_create_select_statement( be, COMMODITIES_TABLE );
138  if ( stmt == NULL ) return;
139  result = gnc_sql_execute_select_statement( be, stmt );
140  gnc_sql_statement_dispose( stmt );
141  if ( result != NULL )
142  {
143  gnc_commodity* pCommodity;
144  GncSqlRow* row = gnc_sql_result_get_first_row( result );
145  gchar* sql;
146 
147  while ( row != NULL )
148  {
149  pCommodity = load_single_commodity( be, row );
150 
151  if ( pCommodity != NULL )
152  {
153  GncGUID guid;
154 
155  guid = *qof_instance_get_guid( QOF_INSTANCE(pCommodity) );
156  pCommodity = gnc_commodity_table_insert( pTable, pCommodity );
157  if (qof_instance_is_dirty (QOF_INSTANCE (pCommodity)))
158  gnc_sql_push_commodity_for_postload_processing (be, (gpointer)pCommodity);
159  qof_instance_set_guid( QOF_INSTANCE(pCommodity), &guid );
160  }
161  row = gnc_sql_result_get_next_row( result );
162  }
163  gnc_sql_result_dispose( result );
164 
165  sql = g_strdup_printf( "SELECT DISTINCT guid FROM %s", COMMODITIES_TABLE );
167  (BookLookupFn)gnc_commodity_find_commodity_by_guid );
168  g_free( sql );
169  }
170 }
171 /* ================================================================= */
172 static void
173 create_commodities_tables( GncSqlBackend* be )
174 {
175  gint version;
176 
177  g_return_if_fail( be != NULL );
178 
179  version = gnc_sql_get_table_version( be, COMMODITIES_TABLE );
180  if ( version == 0 )
181  {
182  (void)gnc_sql_create_table( be, COMMODITIES_TABLE, TABLE_VERSION, col_table );
183  }
184 }
185 
186 /* ================================================================= */
187 static gboolean
188 do_commit_commodity( GncSqlBackend* be, QofInstance* inst, gboolean force_insert )
189 {
190  const GncGUID* guid;
191  gboolean is_infant;
192  gint op;
193  gboolean is_ok;
194 
195  is_infant = qof_instance_get_infant( inst );
196  if ( qof_instance_get_destroying( inst ) )
197  {
198  op = OP_DB_DELETE;
199  }
200  else if ( be->is_pristine_db || is_infant || force_insert )
201  {
202  op = OP_DB_INSERT;
203  }
204  else
205  {
206  op = OP_DB_UPDATE;
207  }
208  is_ok = gnc_sql_do_db_operation( be, op, COMMODITIES_TABLE, GNC_ID_COMMODITY, inst, col_table );
209 
210  if ( is_ok )
211  {
212  // Now, commit any slots
213  guid = qof_instance_get_guid( inst );
214  if ( !qof_instance_get_destroying(inst) )
215  {
216  is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
217  }
218  else
219  {
220  is_ok = gnc_sql_slots_delete( be, guid );
221  }
222  }
223 
224  return is_ok;
225 }
226 
227 static gboolean
228 commit_commodity( GncSqlBackend* be, QofInstance* inst )
229 {
230  g_return_val_if_fail( be != NULL, FALSE );
231  g_return_val_if_fail( inst != NULL, FALSE );
232  g_return_val_if_fail( GNC_IS_COMMODITY(inst), FALSE );
233 
234  return do_commit_commodity( be, inst, FALSE );
235 }
236 
237 static gboolean
238 is_commodity_in_db( GncSqlBackend* be, gnc_commodity* pCommodity )
239 {
240  g_return_val_if_fail( be != NULL, FALSE );
241  g_return_val_if_fail( pCommodity != NULL, FALSE );
242 
243  return gnc_sql_object_is_it_in_db( be, COMMODITIES_TABLE, GNC_ID_COMMODITY,
244  pCommodity, col_table );
245 }
246 
247 gboolean
248 gnc_sql_save_commodity( GncSqlBackend* be, gnc_commodity* pCommodity )
249 {
250  gboolean is_ok = TRUE;
251 
252  g_return_val_if_fail( be != NULL, FALSE );
253  g_return_val_if_fail( pCommodity != NULL, FALSE );
254 
255  if ( !is_commodity_in_db( be, pCommodity ) )
256  {
257  is_ok = do_commit_commodity( be, QOF_INSTANCE(pCommodity), TRUE );
258  }
259 
260  return is_ok;
261 }
262 
263 void
264 gnc_sql_commit_commodity (gnc_commodity *pCommodity)
265 {
266  g_return_if_fail (pCommodity != NULL);
267  g_return_if_fail (GNC_IS_COMMODITY (pCommodity));
268  gnc_commodity_begin_edit (pCommodity);
269  gnc_commodity_commit_edit (pCommodity);
270 }
271 
272 /* ----------------------------------------------------------------- */
273 
274 static void
275 load_commodity_guid( const GncSqlBackend* be, GncSqlRow* row,
276  /*@ null @*/ QofSetterFunc setter, gpointer pObject,
277  const GncSqlColumnTableEntry* table_row )
278 {
279  const GValue* val;
280  GncGUID guid;
281  gnc_commodity* commodity = NULL;
282 
283  g_return_if_fail( be != NULL );
284  g_return_if_fail( row != NULL );
285  g_return_if_fail( pObject != NULL );
286  g_return_if_fail( table_row != NULL );
287 
288  val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
289  if ( val != NULL && G_VALUE_HOLDS_STRING( val ) && g_value_get_string( val ) != NULL )
290  {
291  (void)string_to_guid( g_value_get_string( val ), &guid );
292  commodity = gnc_commodity_find_commodity_by_guid( &guid, be->book );
293  if ( commodity != NULL )
294  {
295  if ( table_row->gobj_param_name != NULL )
296  {
297  qof_instance_increase_editlevel (pObject);
298  g_object_set( pObject, table_row->gobj_param_name, commodity, NULL );
299  qof_instance_decrease_editlevel (pObject);
300  }
301  else if ( setter != NULL )
302  {
303  (*setter)( pObject, (const gpointer)commodity );
304  }
305  }
306  else
307  {
308  PWARN( "Commodity ref '%s' not found", g_value_get_string( val ) );
309  }
310  }
311 }
312 
313 static GncSqlColumnTypeHandler commodity_guid_handler
314 = { load_commodity_guid,
318  };
319 /* ================================================================= */
320 void
321 gnc_sql_init_commodity_handler( void )
322 {
323  static GncSqlObjectBackend be_data =
324  {
325  GNC_SQL_BACKEND_VERSION,
326  GNC_ID_COMMODITY,
327  commit_commodity, /* commit */
328  load_all_commodities, /* initial_load */
329  create_commodities_tables, /* create_tables */
330  NULL, /* compile_query */
331  NULL, /* run_query */
332  NULL, /* free_query */
333  NULL /* write */
334  };
335 
336  (void)qof_object_register_backend( GNC_ID_COMMODITY, GNC_SQL_BACKEND, &be_data );
337 
338  gnc_sql_register_col_type_handler( CT_COMMODITYREF, &commodity_guid_handler );
339 }
340 /* ========================== END OF FILE ===================== */
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table *table, gnc_commodity *comm)
gboolean qof_object_register_backend(QofIdTypeConst type_name, const char *backend_name, gpointer be_data)
gboolean gnc_sql_object_is_it_in_db(GncSqlBackend *be, const gchar *table_name, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
const GncGUID * qof_instance_get_guid(gconstpointer)
gint gnc_sql_get_table_version(const GncSqlBackend *be, const gchar *table_name)
#define qof_instance_is_dirty
Definition: qofinstance.h:165
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
load and save data to SQL
void gnc_sql_add_colname_to_list(const GncSqlColumnTableEntry *table_row, GList **pList)
load and save accounts data to SQL
GncSqlStatement * gnc_sql_create_select_statement(GncSqlBackend *be, const gchar *table_name)
#define COL_NNUL
gboolean qof_instance_get_destroying(gconstpointer ptr)
gboolean string_to_guid(const gchar *string, GncGUID *guid)
gboolean gnc_sql_create_table(GncSqlBackend *be, const gchar *table_name, gint table_version, const GncSqlColumnTableEntry *col_table)
load and save data to SQL
void gnc_sql_register_col_type_handler(const gchar *colType, const GncSqlColumnTypeHandler *handler)
void gnc_sql_add_objectref_guid_col_info_to_list(const GncSqlBackend *be, const GncSqlColumnTableEntry *table_row, GList **pList)
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:177
QofBook * book
Definition: guid.h:65
#define COL_PKEY
#define PWARN(format, args...)
Definition: qoflog.h:243
void gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
void gnc_sql_slots_load_for_sql_subquery(GncSqlBackend *be, const gchar *subquery, BookLookupFn lookup_fn)
void gnc_sql_add_gvalue_objectref_guid_to_slist(const GncSqlBackend *be, QofIdTypeConst obj_name, const gpointer pObject, const GncSqlColumnTableEntry *table_row, GSList **pList)
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
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)
const gchar * gobj_param_name
void gnc_sql_push_commodity_for_postload_processing(GncSqlBackend *be, gpointer *comm)
gnc_quote_source * gnc_quote_source_lookup_by_internal(const char *name)
gboolean gnc_sql_slots_delete(GncSqlBackend *be, const GncGUID *guid)
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
gboolean is_pristine_db
void(* QofSetterFunc)(gpointer, gpointer)
Definition: qofclass.h:184
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
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 char * gnc_quote_source_get_internal_name(const gnc_quote_source *source)
Commodity handling public routines.
gboolean gnc_sql_slots_save(GncSqlBackend *be, const GncGUID *guid, gboolean is_infant, KvpFrame *pFrame)
const gchar * QofLogModule
Definition: qofid.h:89