34 #include <glib/gi18n.h>
35 #include <glib/gstdio.h>
38 #include "qofquery-p.h"
39 #include "qofquerycore-p.h"
44 #include "Recurrence.h"
59 #include "gnc-schedxaction-sql.h"
77 #if defined( S_SPLINT_S )
78 #include "splint-defs.h"
81 static void gnc_sql_init_object_handlers(
void );
84 static void register_standard_col_type_handlers(
void );
88 const gchar* table_name,
93 const gchar* table_name,
98 const gchar* table_name,
102 static GList *post_load_commodities = NULL;
104 #define TRANSACTION_NAME "trans"
110 gpointer pCompiledQuery;
125 gpointer pCompiledQuery;
132 #define SQLITE_PROVIDER_NAME "SQLite"
139 static gboolean initialized = FALSE;
143 register_standard_col_type_handlers();
144 gnc_sql_init_object_handlers();
152 create_tables_cb(
const gchar* type, gpointer data_p, gpointer be_p )
157 g_return_if_fail( type != NULL && data_p != NULL && be_p != NULL );
158 g_return_if_fail( pData->
version == GNC_SQL_BACKEND_VERSION );
162 update_progress( be );
170 static const gchar* fixed_load_order[] =
171 { GNC_ID_BOOK, GNC_ID_COMMODITY, GNC_ID_ACCOUNT, GNC_ID_LOT, NULL };
174 static const gchar** other_load_order = NULL;
179 other_load_order = load_order;
183 initial_load_cb(
const gchar* type, gpointer data_p, gpointer be_p )
189 g_return_if_fail( type != NULL && data_p != NULL && be_p != NULL );
190 g_return_if_fail( pData->
version == GNC_SQL_BACKEND_VERSION );
193 for ( i = 0; fixed_load_order[i] != NULL; i++ )
195 update_progress( be );
196 if ( g_ascii_strcasecmp( type, fixed_load_order[i] ) == 0 )
return;
198 if ( other_load_order != NULL )
200 for ( i = 0; other_load_order[i] != NULL; i++ )
202 update_progress( be );
203 if ( g_ascii_strcasecmp( type, other_load_order[i] ) == 0 )
return;
217 post_load_commodities = g_list_prepend(post_load_commodities, comm);
221 commit_commodity (gpointer data)
224 gnc_sql_commit_commodity (comm);
234 g_return_if_fail( be != NULL );
235 g_return_if_fail( book != NULL );
237 ENTER(
"be=%p, book=%p", be, book );
241 if ( loadType == LOAD_TYPE_INITIAL_LOAD )
243 g_assert( be->
book == NULL );
247 for ( i = 0; fixed_load_order[i] != NULL; i++ )
249 pData = qof_object_lookup_backend( fixed_load_order[i], GNC_SQL_BACKEND );
252 update_progress( be );
256 if ( other_load_order != NULL )
258 for ( i = 0; other_load_order[i] != NULL; i++ )
260 pData = qof_object_lookup_backend( other_load_order[i], GNC_SQL_BACKEND );
263 update_progress( be );
269 root = gnc_book_get_root_account( book );
272 qof_object_foreach_backend( GNC_SQL_BACKEND, initial_load_cb, be );
276 else if ( loadType == LOAD_TYPE_LOAD_ALL )
283 g_list_free_full (post_load_commodities, commit_commodity);
284 post_load_commodities = NULL;
290 finish_progress( be );
303 gboolean is_ok = TRUE;
305 g_return_val_if_fail( be != NULL, FALSE );
306 g_return_val_if_fail( root != NULL, FALSE );
308 is_ok = gnc_sql_save_account( be, QOF_INSTANCE(root) );
312 for ( node = descendants; node != NULL && is_ok; node = g_list_next(node) )
314 is_ok = gnc_sql_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) );
317 g_list_free( descendants );
319 update_progress( be );
329 g_return_val_if_fail( be != NULL, FALSE );
331 update_progress( be );
332 is_ok = write_account_tree( be, gnc_book_get_root_account( be->
book ) );
335 update_progress( be );
347 g_return_val_if_fail( tx != NULL, 0 );
348 g_return_val_if_fail( data != NULL, 0 );
351 update_progress( s->be );
368 g_return_val_if_fail( be != NULL, FALSE );
373 gnc_book_get_root_account( be->
book ), write_tx, &data );
374 update_progress( be );
384 g_return_val_if_fail( be != NULL, FALSE );
392 update_progress( be );
401 GList* schedXactions;
403 gboolean is_ok = TRUE;
405 g_return_val_if_fail( be != NULL, FALSE );
407 schedXactions = gnc_book_get_schedxactions( be->
book )->sx_list;
409 for ( ; schedXactions != NULL && is_ok; schedXactions = schedXactions->next )
411 tmpSX = schedXactions->data;
412 is_ok = gnc_sql_save_schedxaction( be, QOF_INSTANCE( tmpSX ) );
414 update_progress( be );
420 write_cb(
const gchar* type, gpointer data_p, gpointer be_p )
425 g_return_if_fail( type != NULL && data_p != NULL && be_p != NULL );
426 g_return_if_fail( pData->
version == GNC_SQL_BACKEND_VERSION );
428 if ( pData->
write != NULL )
430 (void)(pData->
write)( be );
431 update_progress( be );
438 if ( be->
be.percentage != NULL )
439 (be->
be.percentage)( NULL, 101.0 );
445 if ( be->
be.percentage != NULL )
446 (be->
be.percentage)( NULL, -1.0 );
454 g_return_if_fail( be != NULL );
455 g_return_if_fail( book != NULL );
457 ENTER(
"book=%p, be->book=%p", book, be->
book );
458 update_progress( be );
459 (void)reset_version_info( be );
463 qof_object_foreach_backend( GNC_SQL_BACKEND, create_tables_cb, be );
472 is_ok = gnc_sql_connection_begin_transaction( be->
conn );
478 is_ok = gnc_sql_save_book( be, QOF_INSTANCE(book) );
482 is_ok = write_accounts( be );
486 is_ok = write_transactions( be );
490 is_ok = write_template_transactions( be );
494 is_ok = write_schedXactions( be );
498 qof_object_foreach_backend( GNC_SQL_BACKEND, write_cb, be );
502 is_ok = gnc_sql_connection_commit_transaction( be->
conn );
516 is_ok = gnc_sql_connection_rollback_transaction( be->
conn );
518 finish_progress( be );
519 LEAVE(
"book=%p", book );
528 g_return_if_fail( be != NULL );
529 g_return_if_fail( inst != NULL );
538 g_return_if_fail( be != NULL );
539 g_return_if_fail( inst != NULL );
546 commit_cb(
const gchar* type, gpointer data_p, gpointer be_data_p )
551 g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
552 g_return_if_fail( pData->
version == GNC_SQL_BACKEND_VERSION );
556 if ( be_data->is_known )
return;
558 if ( pData->
commit != NULL )
560 be_data->is_ok = (pData->
commit)( be_data->be, be_data->inst );
561 be_data->is_known = TRUE;
573 gboolean is_destroying;
576 g_return_if_fail( be != NULL );
577 g_return_if_fail( inst != NULL );
582 (void)gnc_sql_connection_rollback_transaction( be->
conn );
589 qof_instance_mark_clean( inst );
594 if ( strcmp( inst->
e_type,
"PriceDB" ) == 0 )
596 qof_instance_mark_clean( inst );
605 is_infant = qof_instance_get_infant( inst );
607 DEBUG(
"%s dirty = %d, do_free = %d, infant = %d\n",
609 is_dirty, is_destroying, is_infant );
611 if ( !is_dirty && !is_destroying )
613 LEAVE(
"!dirty OR !destroying" );
617 if ( !gnc_sql_connection_begin_transaction( be->
conn ) )
619 PERR(
"gnc_sql_commit_edit(): begin_transaction failed\n" );
620 LEAVE(
"Rolled back - database transaction begin error" );
624 be_data.is_known = FALSE;
627 be_data.is_ok = TRUE;
629 qof_object_foreach_backend( GNC_SQL_BACKEND, commit_cb, &be_data );
631 if ( !be_data.is_known )
633 PERR(
"gnc_sql_commit_edit(): Unknown object type '%s'\n", inst->
e_type );
634 (void)gnc_sql_connection_rollback_transaction( be->
conn );
638 qof_instance_mark_clean(inst);
639 LEAVE(
"Rolled back - unknown object type" );
642 if ( !be_data.is_ok )
645 (void)gnc_sql_connection_rollback_transaction( be->
conn );
648 LEAVE(
"Rolled back - database error" );
652 (void)gnc_sql_connection_commit_transaction( be->
conn );
655 qof_instance_mark_clean(inst);
663 handle_and_term( QofQueryTerm* pTerm, GString* sql )
669 gchar val[G_ASCII_DTOSTR_BUF_SIZE];
671 g_return_if_fail( pTerm != NULL );
672 g_return_if_fail( sql != NULL );
674 pParamPath = qof_query_term_get_param_path( pTerm );
675 pPredData = qof_query_term_get_pred_data( pTerm );
676 isInverted = qof_query_term_is_inverted( pTerm );
678 if ( strcmp( pPredData->type_name, QOF_TYPE_GUID ) == 0 )
683 for ( name = pParamPath; name != NULL; name = name->next )
685 if ( name != pParamPath ) g_string_append( sql,
"." );
686 g_string_append( sql, name->data );
691 if ( isInverted ) g_string_append( sql,
" NOT " );
692 g_string_append( sql,
" IN (" );
694 for ( guid_entry = guid_data->guids; guid_entry != NULL; guid_entry = guid_entry->next )
696 if ( guid_entry != guid_data->guids ) g_string_append( sql,
"." );
698 g_string_append( sql,
"'" );
699 g_string_append( sql, val );
700 g_string_append( sql,
"'" );
704 g_string_append( sql,
")" );
708 g_string_append( sql,
"(" );
711 g_string_append( sql,
"!" );
714 for ( name = pParamPath; name != NULL; name = name->next )
716 if ( name != pParamPath ) g_string_append( sql,
"." );
717 g_string_append( sql, name->data );
720 if ( pPredData->how == QOF_COMPARE_LT )
722 g_string_append( sql,
"<" );
724 else if ( pPredData->how == QOF_COMPARE_LTE )
726 g_string_append( sql,
"<=" );
728 else if ( pPredData->how == QOF_COMPARE_EQUAL )
730 g_string_append( sql,
"=" );
732 else if ( pPredData->how == QOF_COMPARE_GT )
734 g_string_append( sql,
">" );
736 else if ( pPredData->how == QOF_COMPARE_GTE )
738 g_string_append( sql,
">=" );
740 else if ( pPredData->how == QOF_COMPARE_NEQ )
742 g_string_append( sql,
"~=" );
746 g_string_append( sql,
"??" );
749 if ( strcmp( pPredData->type_name,
"string" ) == 0 )
752 g_string_append( sql,
"'" );
753 g_string_append( sql, pData->matchstring );
754 g_string_append( sql,
"'" );
756 else if ( strcmp( pPredData->type_name,
"date" ) == 0 )
761 g_string_append( sql,
"'" );
763 g_string_append( sql,
"'" );
765 else if ( strcmp( pPredData->type_name,
"numeric" ) == 0 )
769 g_string_append( sql,
"numeric" );
771 else if ( strcmp( pPredData->type_name, QOF_TYPE_GUID ) == 0 )
774 else if ( strcmp( pPredData->type_name,
"gint32" ) == 0 )
778 sprintf( val,
"%d", pData->val );
779 g_string_append( sql, val );
781 else if ( strcmp( pPredData->type_name,
"gint64" ) == 0 )
785 sprintf( val,
"%" G_GINT64_FORMAT, pData->val );
786 g_string_append( sql, val );
788 else if ( strcmp( pPredData->type_name,
"double" ) == 0 )
792 g_ascii_dtostr( val,
sizeof(val), pData->val );
793 g_string_append( sql, val );
795 else if ( strcmp( pPredData->type_name,
"boolean" ) == 0 )
799 sprintf( val,
"%d", pData->val );
800 g_string_append( sql, val );
807 g_string_append( sql,
")" );
811 compile_query_cb(
const gchar* type, gpointer data_p, gpointer be_data_p )
816 g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
817 g_return_if_fail( pData->
version == GNC_SQL_BACKEND_VERSION );
820 if ( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 )
return;
821 if ( be_data->is_ok )
return;
825 be_data->pQueryInfo->pCompiledQuery = (pData->
compile_query)(
828 be_data->is_ok = TRUE;
843 g_return_val_if_fail( pBEnd != NULL, NULL );
844 g_return_val_if_fail( pQuery != NULL, NULL );
852 g_assert( pQueryInfo != NULL );
853 pQueryInfo->pCompiledQuery = NULL;
854 pQueryInfo->searchObj = searchObj;
857 be_data.is_ok = FALSE;
859 be_data.pQuery = pQuery;
860 be_data.pQueryInfo = pQueryInfo;
862 qof_object_foreach_backend( GNC_SQL_BACKEND, compile_query_cb, &be_data );
866 return be_data.pQueryInfo;
877 return (gchar*)objType;
886 g_return_val_if_fail( be != NULL, NULL );
887 g_return_val_if_fail( query != NULL, NULL );
892 sql = g_string_new(
"" );
893 g_string_append( sql,
"SELECT * FROM " );
894 g_string_append( sql, convert_search_obj( searchObj ) );
897 g_string_append( sql,
";" );
901 GList* orterms = qof_query_get_terms( query );
904 g_string_append( sql,
" WHERE " );
906 for ( orTerm = orterms; orTerm != NULL; orTerm = orTerm->next )
908 GList* andterms = (GList*)orTerm->data;
911 if ( orTerm != orterms ) g_string_append( sql,
" OR " );
912 g_string_append( sql,
"(" );
913 for ( andTerm = andterms; andTerm != NULL; andTerm = andTerm->next )
915 if ( andTerm != andterms ) g_string_append( sql,
" AND " );
916 handle_and_term( (QofQueryTerm*)andTerm->data, sql );
918 g_string_append( sql,
")" );
922 DEBUG(
"Compiled: %s\n", sql->str );
923 return g_string_free( sql, FALSE );
927 free_query_cb(
const gchar* type, gpointer data_p, gpointer be_data_p )
932 g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
933 g_return_if_fail( pData->
version == GNC_SQL_BACKEND_VERSION );
934 if ( be_data->is_ok )
return;
935 if ( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 )
return;
939 (pData->
free_query)( be_data->be, be_data->pCompiledQuery );
940 be_data->is_ok = TRUE;
945 gnc_sql_free_query(
QofBackend* pBEnd, gpointer pQuery )
951 g_return_if_fail( pBEnd != NULL );
952 g_return_if_fail( pQuery != NULL );
957 be_data.is_ok = FALSE;
959 be_data.pCompiledQuery = pQuery;
960 be_data.pQueryInfo = pQueryInfo;
962 qof_object_foreach_backend( GNC_SQL_BACKEND, free_query_cb, &be_data );
969 if ( pQueryInfo->pCompiledQuery != NULL )
971 DEBUG(
"%s\n", (gchar*)pQueryInfo->pCompiledQuery );
972 g_free( pQueryInfo->pCompiledQuery );
974 g_free( pQueryInfo );
980 run_query_cb(
const gchar* type, gpointer data_p, gpointer be_data_p )
985 g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
986 g_return_if_fail( pData->
version == GNC_SQL_BACKEND_VERSION );
987 if ( be_data->is_ok )
return;
990 if ( strcmp( type, be_data->pQueryInfo->searchObj ) != 0 )
return;
994 (pData->
run_query)( be_data->be, be_data->pCompiledQuery );
995 be_data->is_ok = TRUE;
1000 gnc_sql_run_query(
QofBackend* pBEnd, gpointer pQuery )
1006 g_return_if_fail( pBEnd != NULL );
1007 g_return_if_fail( pQuery != NULL );
1018 be_data.is_ok = FALSE;
1020 be_data.pCompiledQuery = pQueryInfo->pCompiledQuery;
1021 be_data.pQueryInfo = pQueryInfo;
1023 qof_object_foreach_backend( GNC_SQL_BACKEND, run_query_cb, &be_data );
1033 qof_instance_mark_clean( QOF_INSTANCE(be->
book) );
1042 static const gchar* business_fixed_load_order[] =
1043 { GNC_ID_BILLTERM, GNC_ID_TAXTABLE, GNC_ID_INVOICE, NULL };
1046 business_core_sql_init(
void)
1049 gnc_address_sql_initialize();
1050 gnc_billterm_sql_initialize();
1051 gnc_customer_sql_initialize();
1052 gnc_employee_sql_initialize();
1053 gnc_entry_sql_initialize();
1054 gnc_invoice_sql_initialize();
1055 gnc_job_sql_initialize();
1056 gnc_order_sql_initialize();
1057 gnc_owner_sql_initialize();
1058 gnc_taxtable_sql_initialize();
1059 gnc_vendor_sql_initialize();
1065 gnc_sql_init_object_handlers(
void )
1067 gnc_sql_init_book_handler();
1068 gnc_sql_init_commodity_handler();
1069 gnc_sql_init_account_handler();
1070 gnc_sql_init_budget_handler();
1071 gnc_sql_init_price_handler();
1072 gnc_sql_init_transaction_handler();
1073 gnc_sql_init_slots_handler();
1074 gnc_sql_init_recurrence_handler();
1075 gnc_sql_init_schedxaction_handler();
1076 gnc_sql_init_lot_handler();
1079 business_core_sql_init();
1087 g_return_val_if_fail( value != NULL, 0 );
1089 if ( G_VALUE_HOLDS_INT(value) )
1091 return (gint64)g_value_get_int( value );
1093 else if ( G_VALUE_HOLDS_UINT(value) )
1095 return (gint64)g_value_get_uint( value );
1097 else if ( G_VALUE_HOLDS_LONG(value) )
1099 return (gint64)g_value_get_long( value );
1101 else if ( G_VALUE_HOLDS_ULONG(value) )
1103 return (gint64)g_value_get_ulong( value );
1105 else if ( G_VALUE_HOLDS_INT64(value) )
1107 return g_value_get_int64( value );
1109 else if ( G_VALUE_HOLDS_UINT64(value) )
1111 return (gint64)g_value_get_uint64( value );
1113 else if ( G_VALUE_HOLDS_STRING( value ) )
1115 return g_ascii_strtoll( g_value_get_string( value ), NULL, 10 );
1119 PWARN(
"Unknown type: %s", G_VALUE_TYPE_NAME( value ) );
1144 g_return_val_if_fail( obj_name != NULL, NULL );
1145 g_return_val_if_fail( table_row != NULL, NULL );
1149 getter = get_autoinc_id;
1158 getter = table_row->
getter;
1168 (*pList) = g_list_append( (*pList), g_strdup( table_row->
col_name ) );
1179 for ( subtable_row = subtable; subtable_row->
col_name != NULL; subtable_row++ )
1181 buf = g_strdup_printf(
"%s_%s", table_row->
col_name, subtable_row->
col_name );
1182 (*pList) = g_list_append( (*pList), buf );
1188 gint size, gboolean is_unicode )
1193 g_assert( info != NULL );
1214 g_return_if_fail( be != NULL );
1215 g_return_if_fail( row != NULL );
1216 g_return_if_fail( pObject != NULL );
1217 g_return_if_fail( table_row != NULL );
1218 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
1220 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
1221 g_return_if_fail( val != NULL );
1222 s = g_value_get_string( val );
1225 if (QOF_IS_INSTANCE (pObject))
1226 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
1228 if (QOF_IS_INSTANCE (pObject))
1229 qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
1233 g_return_if_fail( setter != NULL );
1234 (*setter)( pObject, (
const gpointer)s );
1244 g_return_if_fail( be != NULL );
1245 g_return_if_fail( table_row != NULL );
1246 g_return_if_fail( pList != NULL );
1248 info = create_column_info( table_row, BCT_STRING, table_row->
size, TRUE );
1250 *pList = g_list_append( *pList, info );
1261 g_return_if_fail( be != NULL );
1262 g_return_if_fail( obj_name != NULL );
1263 g_return_if_fail( pObject != NULL );
1264 g_return_if_fail( table_row != NULL );
1265 g_return_if_fail( pList != NULL );
1267 value = g_new0( GValue, 1 );
1268 g_assert( value != NULL );
1269 memset( value, 0,
sizeof( GValue ) );
1277 if ( getter != NULL )
1279 s = (gchar*)(*getter)( pObject, NULL );
1286 (void)g_value_init( value, G_TYPE_STRING );
1289 g_value_take_string( value, s );
1292 (*pList) = g_slist_append( (*pList), value );
1299 add_string_col_info_to_list,
1301 add_gvalue_string_to_slist
1304 typedef gint (*IntAccessFunc)(
const gpointer );
1305 typedef void (*IntSetterFunc)(
const gpointer, gint );
1314 IntSetterFunc i_setter;
1316 g_return_if_fail( be != NULL );
1317 g_return_if_fail( row != NULL );
1318 g_return_if_fail( pObject != NULL );
1319 g_return_if_fail( table_row != NULL );
1320 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
1322 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
1333 if (QOF_IS_INSTANCE (pObject))
1334 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
1336 if (QOF_IS_INSTANCE (pObject))
1337 qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
1341 g_return_if_fail( setter != NULL );
1342 i_setter = (IntSetterFunc)setter;
1343 (*i_setter)( pObject, int_value );
1353 g_return_if_fail( be != NULL );
1354 g_return_if_fail( table_row != NULL );
1355 g_return_if_fail( pList != NULL );
1357 info = create_column_info( table_row, BCT_INT, 0, FALSE );
1359 *pList = g_list_append( *pList, info );
1367 IntAccessFunc i_getter;
1370 g_return_if_fail( be != NULL );
1371 g_return_if_fail( obj_name != NULL );
1372 g_return_if_fail( pObject != NULL );
1373 g_return_if_fail( table_row != NULL );
1374 g_return_if_fail( pList != NULL );
1376 value = g_new0( GValue, 1 );
1377 g_assert( value != NULL );
1378 (void)g_value_init( value, G_TYPE_INT );
1387 if ( i_getter != NULL )
1389 int_value = (*i_getter)( pObject );
1391 g_value_set_int( value, int_value );
1394 (*pList) = g_slist_append( (*pList), value );
1401 add_int_col_info_to_list,
1403 add_gvalue_int_to_slist
1406 typedef gboolean (*BooleanAccessFunc)(
const gpointer );
1407 typedef void (*BooleanSetterFunc)(
const gpointer, gboolean );
1416 BooleanSetterFunc b_setter;
1418 g_return_if_fail( be != NULL );
1419 g_return_if_fail( row != NULL );
1420 g_return_if_fail( pObject != NULL );
1421 g_return_if_fail( table_row != NULL );
1422 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
1424 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
1435 if (QOF_IS_INSTANCE (pObject))
1436 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
1438 if (QOF_IS_INSTANCE (pObject))
1439 qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
1443 g_return_if_fail( setter != NULL );
1444 b_setter = (BooleanSetterFunc)setter;
1445 (*b_setter)( pObject, (int_value != 0) ? TRUE : FALSE );
1455 g_return_if_fail( be != NULL );
1456 g_return_if_fail( table_row != NULL );
1457 g_return_if_fail( pList != NULL );
1459 info = create_column_info( table_row, BCT_INT, 0, FALSE );
1461 *pList = g_list_append( *pList, info );
1469 BooleanAccessFunc b_getter;
1472 g_return_if_fail( be != NULL );
1473 g_return_if_fail( obj_name != NULL );
1474 g_return_if_fail( pObject != NULL );
1475 g_return_if_fail( table_row != NULL );
1476 g_return_if_fail( pList != NULL );
1478 value = g_new0( GValue, 1 );
1479 g_assert( value != NULL );
1483 g_object_get( pObject, table_row->
gobj_param_name, &int_value, NULL );
1488 if ( b_getter != NULL )
1490 int_value = ((*b_getter)( pObject )) ? 1 : 0;
1493 (void)g_value_init( value, G_TYPE_INT );
1494 g_value_set_int( value, int_value );
1496 (*pList) = g_slist_append( (*pList), value );
1503 add_boolean_col_info_to_list,
1505 add_gvalue_boolean_to_slist
1508 typedef gint64 (*Int64AccessFunc)(
const gpointer );
1509 typedef void (*Int64SetterFunc)(
const gpointer, gint64 );
1517 gint64 i64_value = 0;
1518 Int64SetterFunc i64_setter = (Int64SetterFunc)setter;
1520 g_return_if_fail( be != NULL );
1521 g_return_if_fail( row != NULL );
1522 g_return_if_fail( table_row != NULL );
1523 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
1525 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
1532 if (QOF_IS_INSTANCE (pObject))
1533 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
1535 if (QOF_IS_INSTANCE (pObject))
1536 qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
1540 (*i64_setter)( pObject, i64_value );
1550 g_return_if_fail( be != NULL );
1551 g_return_if_fail( table_row != NULL );
1552 g_return_if_fail( pList != NULL );
1554 info = create_column_info( table_row, BCT_INT64, 0, FALSE );
1556 *pList = g_list_append( *pList, info );
1563 gint64 i64_value = 0;
1564 Int64AccessFunc getter;
1567 g_return_if_fail( be != NULL );
1568 g_return_if_fail( obj_name != NULL );
1569 g_return_if_fail( pObject != NULL );
1570 g_return_if_fail( table_row != NULL );
1571 g_return_if_fail( pList != NULL );
1573 value = g_new0( GValue, 1 );
1574 g_assert( value != NULL );
1577 g_object_get( pObject, table_row->
gobj_param_name, &i64_value, NULL );
1582 if ( getter != NULL )
1584 i64_value = (*getter)( pObject );
1587 (void)g_value_init( value, G_TYPE_INT64 );
1588 g_value_set_int64( value, i64_value );
1590 (*pList) = g_slist_append( (*pList), value );
1597 add_int64_col_info_to_list,
1599 add_gvalue_int64_to_slist
1611 g_return_if_fail( be != NULL );
1612 g_return_if_fail( row != NULL );
1613 g_return_if_fail( pObject != NULL );
1614 g_return_if_fail( table_row != NULL );
1615 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
1617 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
1620 (*setter)( pObject, (gpointer)NULL );
1624 if ( G_VALUE_HOLDS(val, G_TYPE_INT) )
1626 d_value = (gdouble)g_value_get_int( val );
1628 else if ( G_VALUE_HOLDS(val, G_TYPE_FLOAT) )
1630 d_value = g_value_get_float( val );
1632 else if (G_VALUE_HOLDS(val, G_TYPE_DOUBLE) )
1634 d_value = g_value_get_double( val );
1638 PWARN(
"Unknown float value type: %s\n", g_type_name( G_VALUE_TYPE(val) ) );
1643 if (QOF_IS_INSTANCE (pObject))
1644 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
1646 if (QOF_IS_INSTANCE (pObject))
1647 qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
1651 (*setter)( pObject, (gpointer)&d_value );
1662 g_return_if_fail( be != NULL );
1663 g_return_if_fail( table_row != NULL );
1664 g_return_if_fail( pList != NULL );
1666 info = create_column_info( table_row, BCT_DOUBLE, 0, FALSE );
1668 *pList = g_list_append( *pList, info );
1676 gdouble* pDouble = NULL;
1680 g_return_if_fail( be != NULL );
1681 g_return_if_fail( obj_name != NULL );
1682 g_return_if_fail( pObject != NULL );
1683 g_return_if_fail( table_row != NULL );
1685 value = g_new0( GValue, 1 );
1686 g_assert( value != NULL );
1688 if ( getter != NULL )
1690 pDouble = (*getter)( pObject, NULL );
1692 if ( pDouble != NULL )
1695 (void)g_value_init( value, G_TYPE_DOUBLE );
1696 g_value_set_double( value, d_value );
1700 (void)g_value_init( value, G_TYPE_DOUBLE );
1701 g_value_set_double( value, 0.0 );
1704 (*pList) = g_slist_append( (*pList), value );
1711 add_double_col_info_to_list,
1713 add_gvalue_double_to_slist
1726 g_return_if_fail( be != NULL );
1727 g_return_if_fail( row != NULL );
1728 g_return_if_fail( pObject != NULL );
1729 g_return_if_fail( table_row != NULL );
1730 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
1732 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
1733 if ( val == NULL || g_value_get_string( val ) == NULL )
1742 if ( pGuid != NULL )
1746 if (QOF_IS_INSTANCE (pObject))
1747 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
1749 if (QOF_IS_INSTANCE (pObject))
1750 qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
1754 g_return_if_fail( setter != NULL );
1755 (*setter)( pObject, (
const gpointer)pGuid );
1766 g_return_if_fail( be != NULL );
1767 g_return_if_fail( table_row != NULL );
1768 g_return_if_fail( pList != NULL );
1772 *pList = g_list_append( *pList, info );
1784 g_return_if_fail( be != NULL );
1785 g_return_if_fail( obj_name != NULL );
1786 g_return_if_fail( pObject != NULL );
1787 g_return_if_fail( table_row != NULL );
1789 value = g_new0( GValue, 1 );
1790 g_assert( value != NULL );
1798 if ( getter != NULL )
1800 guid = (*getter)( pObject, NULL );
1803 (void)g_value_init( value, G_TYPE_STRING );
1807 g_value_set_string( value, guid_buf );
1810 (*pList) = g_slist_append( (*pList), value );
1818 add_guid_col_info_to_list,
1820 add_gvalue_guid_to_slist
1834 g_return_if_fail( be != NULL );
1835 g_return_if_fail( obj_name != NULL );
1836 g_return_if_fail( pObject != NULL );
1837 g_return_if_fail( table_row != NULL );
1839 value = g_new0( GValue, 1 );
1840 g_assert( value != NULL );
1848 if ( getter != NULL )
1850 inst = (*getter)( pObject, NULL );
1857 (void)g_value_init( value, G_TYPE_STRING );
1861 g_value_set_string( value, guid_buf );
1864 (*pList) = g_slist_append( (*pList), value );
1872 add_guid_col_info_to_list( be, table_row, pList );
1876 typedef Timespec (*TimespecAccessFunc)(
const gpointer );
1877 typedef void (*TimespecSetterFunc)(
const gpointer,
Timespec );
1879 #define TIMESPEC_STR_FORMAT "%04d%02d%02d%02d%02d%02d"
1880 #define TIMESPEC_COL_SIZE (4+2+2+2+2+2)
1893 year = tm->tm_year + 1900;
1896 year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec );
1908 TimespecSetterFunc ts_setter;
1909 gboolean isOK = FALSE;
1911 g_return_if_fail( be != NULL );
1912 g_return_if_fail( row != NULL );
1913 g_return_if_fail( pObject != NULL );
1914 g_return_if_fail( table_row != NULL );
1915 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
1917 ts_setter = (TimespecSetterFunc)setter;
1918 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
1925 if ( G_VALUE_HOLDS_INT64( val ) )
1930 else if (G_VALUE_HOLDS_STRING (val))
1932 const gchar* s = g_value_get_string( val );
1936 buf = g_strdup_printf(
"%c%c%c%c-%c%c-%c%c %c%c:%c%c:%c%c",
1937 s[0], s[1], s[2], s[3],
1950 PWARN(
"Unknown timespec type: %s", G_VALUE_TYPE_NAME( val ) );
1957 if (QOF_IS_INSTANCE (pObject))
1958 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
1960 if (QOF_IS_INSTANCE (pObject))
1961 qof_instance_decrease_editlevel (QOF_INSTANCE (pObject));
1965 (*ts_setter)( pObject, ts );
1976 g_return_if_fail( be != NULL );
1977 g_return_if_fail( table_row != NULL );
1978 g_return_if_fail( pList != NULL );
1980 info = create_column_info( table_row, BCT_DATETIME, TIMESPEC_COL_SIZE, FALSE );
1982 *pList = g_list_append( *pList, info );
1989 TimespecAccessFunc ts_getter;
1994 g_return_if_fail( be != NULL );
1995 g_return_if_fail( obj_name != NULL );
1996 g_return_if_fail( pObject != NULL );
1997 g_return_if_fail( table_row != NULL );
1998 g_return_if_fail( pList != NULL );
2009 g_return_if_fail( ts_getter != NULL );
2010 ts = (*ts_getter)( pObject );
2013 value = g_new0( GValue, 1 );
2014 g_assert( value != NULL );
2015 (void)g_value_init( value, G_TYPE_STRING );
2016 if ( ts.tv_sec != 0 || ts.tv_nsec != 0 )
2019 g_value_take_string( value, datebuf );
2022 (*pList) = g_slist_append( (*pList), value );
2029 add_timespec_col_info_to_list,
2031 add_gvalue_timespec_to_slist
2034 #define DATE_COL_SIZE 8
2043 g_return_if_fail( be != NULL );
2044 g_return_if_fail( row != NULL );
2045 g_return_if_fail( pObject != NULL );
2046 g_return_if_fail( table_row != NULL );
2047 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
2049 val = gnc_sql_row_get_value_at_col_name( row, table_row->
col_name );
2052 if (G_VALUE_HOLDS_INT64 (val))
2054 gint64 time = g_value_get_int64 (val);
2055 GDateTime *gdt = g_date_time_new_from_unix_utc (time);
2056 gint day, month, year;
2058 g_date_time_get_ymd (gdt, &year, &month, &day);
2059 date = g_date_new_dmy (day, month, year);
2060 g_date_time_unref (gdt);
2063 if (QOF_IS_INSTANCE (pObject))
2064 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
2066 if (QOF_IS_INSTANCE (pObject))
2067 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
2071 (*setter)( pObject, date );
2073 g_date_free( date );
2075 else if ( G_VALUE_HOLDS_STRING( val ) )
2078 const gchar* s = g_value_get_string( val );
2087 strncpy( buf, &s[0], 4 );
2089 year = (GDateYear)atoi( buf );
2090 strncpy( buf, &s[4], 2 );
2092 month = (guint)atoi( buf );
2093 strncpy( buf, &s[6], 2 );
2094 day = (GDateDay)atoi( buf );
2096 if ( year != 0 || month != 0 || day != (GDateDay)0 )
2098 date = g_date_new_dmy( day, month, year );
2101 if (QOF_IS_INSTANCE (pObject))
2102 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
2105 if (QOF_IS_INSTANCE (pObject))
2106 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
2110 (*setter)( pObject, date );
2112 g_date_free( date );
2118 PWARN(
"Unknown date type: %s", G_VALUE_TYPE_NAME( val ) );
2129 g_return_if_fail( be != NULL );
2130 g_return_if_fail( table_row != NULL );
2131 g_return_if_fail( pList != NULL );
2133 info = create_column_info( table_row, BCT_DATE, DATE_COL_SIZE, FALSE );
2135 *pList = g_list_append( *pList, info );
2140 const gpointer pObject,
2148 g_return_if_fail( be != NULL );
2149 g_return_if_fail( obj_name != NULL );
2150 g_return_if_fail( pObject != NULL );
2151 g_return_if_fail( table_row != NULL );
2153 value = g_new0( GValue, 1 );
2154 g_assert( value != NULL );
2155 (void)g_value_init( value, G_TYPE_STRING );
2163 if ( getter != NULL )
2165 date = (GDate*)(*getter)( pObject, NULL );
2168 if ( date && g_date_valid( date ) )
2170 buf = g_strdup_printf(
"%04d%02d%02d",
2171 g_date_get_year( date ), g_date_get_month( date ), g_date_get_day( date ) );
2172 g_value_take_string( value, buf );
2175 (*pList) = g_slist_append( (*pList), value );
2182 add_date_col_info_to_list,
2184 add_gvalue_date_to_slist
2187 typedef gnc_numeric (*NumericGetterFunc)(
const gpointer );
2188 typedef void (*NumericSetterFunc)( gpointer,
gnc_numeric );
2193 {
"num", CT_INT64, 0,
COL_NNUL,
"guid" },
2194 {
"denom", CT_INT64, 0,
COL_NNUL,
"guid" },
2208 gboolean isNull = FALSE;
2210 g_return_if_fail( be != NULL );
2211 g_return_if_fail( row != NULL );
2212 g_return_if_fail( pObject != NULL );
2213 g_return_if_fail( table_row != NULL );
2214 g_return_if_fail( table_row->
gobj_param_name != NULL || setter != NULL );
2216 buf = g_strdup_printf(
"%s_num", table_row->
col_name );
2217 val = gnc_sql_row_get_value_at_col_name( row, buf );
2228 buf = g_strdup_printf(
"%s_denom", table_row->
col_name );
2229 val = gnc_sql_row_get_value_at_col_name( row, buf );
2240 n = gnc_numeric_create( num, denom );
2245 if (QOF_IS_INSTANCE (pObject))
2246 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
2248 if (QOF_IS_INSTANCE (pObject))
2249 qof_instance_increase_editlevel (QOF_INSTANCE (pObject));
2253 NumericSetterFunc n_setter = (NumericSetterFunc)setter;
2254 (*n_setter)( pObject, n );
2267 g_return_if_fail( be != NULL );
2268 g_return_if_fail( table_row != NULL );
2269 g_return_if_fail( pList != NULL );
2271 for ( subtable_row = numeric_col_table; subtable_row->
col_name != NULL; subtable_row++ )
2273 buf = g_strdup_printf(
"%s_%s", table_row->
col_name, subtable_row->
col_name );
2275 g_assert( info != NULL );
2277 info->
type = BCT_INT64;
2281 *pList = g_list_append( *pList, info );
2295 NumericGetterFunc getter;
2298 GValue* denom_value;
2300 g_return_if_fail( be != NULL );
2301 g_return_if_fail( obj_name != NULL );
2302 g_return_if_fail( pObject != NULL );
2303 g_return_if_fail( table_row != NULL );
2314 if ( getter != NULL )
2316 n = (*getter)( pObject );
2320 n = gnc_numeric_zero();
2324 num_value = g_new0( GValue, 1 );
2325 g_assert( num_value != NULL );
2326 (void)g_value_init( num_value, G_TYPE_INT64 );
2327 g_value_set_int64( num_value, gnc_numeric_num( n ) );
2328 denom_value = g_new0( GValue, 1 );
2329 g_assert( denom_value != NULL );
2330 (void)g_value_init( denom_value, G_TYPE_INT64 );
2331 g_value_set_int64( denom_value, gnc_numeric_denom( n ) );
2333 (*pList) = g_slist_append( (*pList), num_value );
2334 (*pList) = g_slist_append( (*pList), denom_value );
2339 add_numeric_col_info_to_list,
2340 add_numeric_colname_to_list,
2341 add_gvalue_numeric_to_slist
2345 static GHashTable* g_columnTypeHash = NULL;
2350 g_return_if_fail( colType != NULL );
2351 g_return_if_fail( handler != NULL );
2353 if ( g_columnTypeHash == NULL )
2355 g_columnTypeHash = g_hash_table_new( g_str_hash, g_str_equal );
2356 g_assert( g_columnTypeHash != NULL );
2359 DEBUG(
"Col type %s registered\n", colType );
2360 g_hash_table_insert( g_columnTypeHash, (gpointer)colType, (gpointer)handler );
2368 g_return_val_if_fail( table_row != NULL, NULL );
2369 g_return_val_if_fail( table_row->
col_type != NULL, NULL );
2371 if ( g_columnTypeHash != NULL )
2373 pHandler = g_hash_table_lookup( g_columnTypeHash, table_row->
col_type );
2374 g_assert( pHandler != NULL );
2385 register_standard_col_type_handlers(
void )
2399 _retrieve_guid_( gpointer pObject, gpointer pValue )
2404 g_return_if_fail( pObject != NULL );
2405 g_return_if_fail( pValue != NULL );
2407 memcpy( pGuid, guid,
sizeof(
GncGUID ) );
2415 {
"guid", CT_GUID, 0, 0, NULL, NULL, NULL, _retrieve_guid_ },
2426 g_return_val_if_fail( be != NULL, NULL );
2427 g_return_val_if_fail( row != NULL, NULL );
2438 {
"tx_guid", CT_GUID, 0, 0, NULL, NULL, NULL, _retrieve_guid_ },
2449 g_return_val_if_fail( be != NULL, NULL );
2450 g_return_val_if_fail( row != NULL, NULL );
2466 g_return_if_fail( be != NULL );
2467 g_return_if_fail( row != NULL );
2468 g_return_if_fail( pObject != NULL );
2469 g_return_if_fail( table != NULL );
2471 for ( table_row = table; table_row->
col_name != NULL; table_row++ )
2475 setter = set_autoinc_id;
2479 g_assert( obj_name != NULL );
2485 setter = table_row->
setter;
2487 pHandler = get_handler( table_row );
2488 g_assert( pHandler != NULL );
2489 pHandler->
load_fn( be, row, setter, pObject, table_row );
2500 g_return_val_if_fail( be != NULL, NULL );
2501 g_return_val_if_fail( table_name != NULL, NULL );
2503 sql = g_strdup_printf(
"SELECT * FROM %s", table_name );
2511 const gchar* table_name,
2517 g_return_val_if_fail( be != NULL, NULL );
2518 g_return_val_if_fail( table_name != NULL, NULL );
2519 g_return_val_if_fail( table_row != NULL, NULL );
2521 sql = g_strdup_printf(
"SELECT %s FROM %s", table_row->
col_name, table_name );
2534 g_return_val_if_fail( be != NULL, NULL );
2535 g_return_val_if_fail( stmt != NULL, NULL );
2537 result = gnc_sql_connection_execute_select_statement( be->
conn, stmt );
2538 if ( result == NULL )
2540 PERR(
"SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
2552 g_return_val_if_fail( be != NULL, NULL );
2553 g_return_val_if_fail( sql != NULL, NULL );
2555 stmt = gnc_sql_connection_create_statement_from_sql( be->
conn, sql );
2558 PERR(
"SQL error: %s\n", sql );
2571 g_return_val_if_fail( be != NULL, NULL );
2572 g_return_val_if_fail( sql != NULL, NULL );
2579 result = gnc_sql_connection_execute_select_statement( be->
conn, stmt );
2580 gnc_sql_statement_dispose( stmt );
2581 if ( result == NULL )
2583 PERR(
"SQL error: %s\n", sql );
2596 g_return_val_if_fail( be != NULL, 0 );
2597 g_return_val_if_fail( sql != NULL, 0 );
2604 result = gnc_sql_connection_execute_nonselect_statement( be->
conn, stmt );
2605 gnc_sql_statement_dispose( stmt );
2615 g_return_val_if_fail( be != NULL, 0 );
2616 g_return_val_if_fail( stmt != NULL, 0 );
2619 if ( result != NULL )
2621 count = gnc_sql_result_get_num_rows( result );
2622 gnc_sql_result_dispose( result );
2632 gboolean first_guid = TRUE;
2635 g_return_val_if_fail( sql != NULL, 0 );
2637 if ( list == NULL )
return 0;
2639 for ( count = 0; list != NULL && count < maxCount; list = list->next, count++ )
2646 (void)g_string_append( sql,
"," );
2648 (void)g_string_append( sql,
"'" );
2649 (void)g_string_append( sql, guid_buf );
2650 (void)g_string_append( sql,
"'" );
2666 GSList* list = NULL;
2668 g_return_val_if_fail( be != NULL, FALSE );
2669 g_return_val_if_fail( table_name != NULL, FALSE );
2670 g_return_val_if_fail( obj_name != NULL, FALSE );
2671 g_return_val_if_fail( pObject != NULL, FALSE );
2672 g_return_val_if_fail( table != NULL, FALSE );
2675 sqlStmt = create_single_col_select_statement( be, table_name, table );
2676 g_assert( sqlStmt != NULL );
2679 pHandler = get_handler( table );
2680 g_assert( pHandler != NULL );
2682 g_assert( list != NULL );
2683 gnc_sql_statement_add_where_cond( sqlStmt, obj_name, pObject, &table[0], (GValue*)(list->data) );
2685 count = execute_statement_get_count( be, sqlStmt );
2686 gnc_sql_statement_dispose( sqlStmt );
2700 const gchar* table_name,
2705 gboolean ok = FALSE;
2707 g_return_val_if_fail( be != NULL, FALSE );
2708 g_return_val_if_fail( table_name != NULL, FALSE );
2709 g_return_val_if_fail( obj_name != NULL, FALSE );
2710 g_return_val_if_fail( pObject != NULL, FALSE );
2711 g_return_val_if_fail( table != NULL, FALSE );
2713 if ( op == OP_DB_INSERT )
2715 stmt = build_insert_statement( be, table_name, obj_name, pObject, table );
2717 else if ( op == OP_DB_UPDATE )
2719 stmt = build_update_statement( be, table_name, obj_name, pObject, table );
2721 else if ( op == OP_DB_DELETE )
2723 stmt = build_delete_statement( be, table_name, obj_name, pObject, table );
2733 result = gnc_sql_connection_execute_nonselect_statement( be->
conn, stmt );
2736 PERR(
"SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
2743 gnc_sql_statement_dispose( stmt );
2754 GSList* list = NULL;
2758 for ( table_row = table; table_row->
col_name != NULL; table_row++ )
2762 pHandler = get_handler( table_row );
2763 g_assert( pHandler != NULL );
2768 g_assert( list != NULL );
2775 if ( value != NULL && G_IS_VALUE( value ) )
2777 GType type = G_VALUE_TYPE(value);
2779 if ( G_VALUE_HOLDS_STRING(value) )
2781 if ( g_value_get_string( value ) != NULL )
2785 before_str = g_value_dup_string( value );
2786 after_str = gnc_sql_connection_quote_string( conn, before_str );
2787 g_free( before_str );
2792 return g_strdup(
"NULL" );
2795 else if ( type == G_TYPE_INT64 )
2797 return g_strdup_printf(
"%" G_GINT64_FORMAT, g_value_get_int64( value ) );
2800 else if ( type == G_TYPE_INT )
2802 return g_strdup_printf(
"%d", g_value_get_int( value ) );
2805 else if ( type == G_TYPE_DOUBLE )
2807 gchar doublestr[G_ASCII_DTOSTR_BUF_SIZE];
2808 g_ascii_dtostr( doublestr,
sizeof(doublestr),
2809 g_value_get_double( value ));
2810 return g_strdup( doublestr );
2813 else if ( g_value_type_transformable( type, G_TYPE_STRING ) )
2818 string = g_new0( GValue, 1 );
2819 g_assert(
string != NULL );
2820 (void)g_value_init(
string, G_TYPE_STRING );
2821 (void)g_value_transform( value,
string );
2822 str = g_value_dup_string(
string );
2823 g_value_unset(
string );
2825 PWARN(
"using g_value_transform(), gtype = '%s'\n", g_type_name( type ) );
2830 PWARN(
"not transformable, gtype = '%s'\n", g_type_name( type ) );
2831 return g_strdup(
"$$$" );
2836 PWARN(
"value is NULL or not G_IS_VALUE()\n" );
2837 return g_strdup(
"" );
2842 free_gvalue_list( GSList* list )
2847 for ( node = list; node != NULL; node = node->next )
2849 value = (GValue*)node->data;
2851 g_value_unset( value );
2854 g_slist_free( list );
2859 const gchar* table_name,
2868 GList* colnames = NULL;
2872 g_return_val_if_fail( be != NULL, NULL );
2873 g_return_val_if_fail( table_name != NULL, NULL );
2874 g_return_val_if_fail( obj_name != NULL, NULL );
2875 g_return_val_if_fail( pObject != NULL, NULL );
2876 g_return_val_if_fail( table != NULL, NULL );
2878 sqlbuf = g_strdup_printf(
"INSERT INTO %s(", table_name );
2879 sql = g_string_new( sqlbuf );
2883 for ( table_row = table; table_row->
col_name != NULL; table_row++ )
2890 pHandler = get_handler( table_row );
2891 g_assert( pHandler != NULL );
2895 g_assert( colnames != NULL );
2897 for ( colname = colnames; colname != NULL; colname = colname->next )
2899 if ( colname != colnames )
2901 g_string_append( sql,
"," );
2903 g_string_append( sql, (gchar*)colname->data );
2904 g_free( colname->data );
2906 g_list_free( colnames );
2908 g_string_append( sql,
") VALUES(" );
2909 values = create_gslist_from_values( be, obj_name, pObject, table );
2910 for ( node = values; node != NULL; node = node->next )
2912 GValue* value = (GValue*)node->data;
2914 if ( node != values )
2916 (void)g_string_append( sql,
"," );
2919 (void)g_string_append( sql, value_str );
2920 g_free( value_str );
2921 (void)g_value_reset( value );
2923 free_gvalue_list( values );
2924 (void)g_string_append( sql,
")" );
2926 stmt = gnc_sql_connection_create_statement_from_sql( be->
conn, sql->str );
2927 (void)g_string_free( sql, TRUE );
2934 const gchar* table_name,
2941 GList* colnames = NULL;
2948 g_return_val_if_fail( be != NULL, NULL );
2949 g_return_val_if_fail( table_name != NULL, NULL );
2950 g_return_val_if_fail( obj_name != NULL, NULL );
2951 g_return_val_if_fail( pObject != NULL, NULL );
2952 g_return_val_if_fail( table != NULL, NULL );
2955 for ( table_row = table; table_row->
col_name != NULL; table_row++ )
2962 pHandler = get_handler( table_row );
2963 g_assert( pHandler != NULL );
2967 g_assert( colnames != NULL );
2968 values = create_gslist_from_values( be, obj_name, pObject, table );
2971 sqlbuf = g_strdup_printf(
"UPDATE %s SET ", table_name );
2972 sql = g_string_new( sqlbuf );
2976 for ( colname = colnames->next, value = values->next;
2977 colname != NULL && value != NULL;
2978 colname = colname->next, value = value->next )
2983 (void)g_string_append( sql,
"," );
2985 (void)g_string_append( sql, (gchar*)colname->data );
2986 (void)g_string_append( sql,
"=" );
2988 (void)g_string_append( sql, value_str );
2989 g_free( value_str );
2992 for ( colname = colnames; colname != NULL; colname = colname->next )
2994 g_free( colname->data );
2996 g_list_free( colnames );
2997 if ( value != NULL || colname != NULL )
2999 PERR(
"Mismatch in number of column names and values" );
3002 stmt = gnc_sql_connection_create_statement_from_sql( be->
conn, sql->str );
3003 gnc_sql_statement_add_where_cond( stmt, obj_name, pObject, &table[0], (GValue*)(values->data) );
3004 free_gvalue_list( values );
3005 (void)g_string_free( sql, TRUE );
3012 const gchar* table_name,
3018 GSList* list = NULL;
3021 g_return_val_if_fail( be != NULL, NULL );
3022 g_return_val_if_fail( table_name != NULL, NULL );
3023 g_return_val_if_fail( obj_name != NULL, NULL );
3024 g_return_val_if_fail( pObject != NULL, NULL );
3025 g_return_val_if_fail( table != NULL, NULL );
3027 sqlbuf = g_strdup_printf(
"DELETE FROM %s ", table_name );
3028 stmt = gnc_sql_connection_create_statement_from_sql( be->
conn, sqlbuf );
3032 pHandler = get_handler( table );
3033 g_assert( pHandler != NULL );
3035 g_assert( list != NULL );
3036 gnc_sql_statement_add_where_cond( stmt, obj_name, pObject, &table[0], (GValue*)(list->data) );
3037 free_gvalue_list( list );
3052 is_infant = qof_instance_get_infant( inst );
3087 do_create_table(
const GncSqlBackend* be,
const gchar* table_name,
3090 GList* col_info_list = NULL;
3091 gboolean ok = FALSE;
3093 g_return_val_if_fail( be != NULL, FALSE );
3094 g_return_val_if_fail( table_name != NULL, FALSE );
3095 g_return_val_if_fail( col_table != NULL, FALSE );
3097 for ( ; col_table->
col_name != NULL; col_table++ )
3101 pHandler = get_handler( col_table );
3102 g_assert( pHandler != NULL );
3105 g_assert( col_info_list != NULL );
3106 ok = gnc_sql_connection_create_table( be->
conn, table_name, col_info_list );
3116 g_return_val_if_fail( be != NULL, FALSE );
3117 g_return_val_if_fail( table_name != NULL, FALSE );
3118 g_return_val_if_fail( col_table != NULL, FALSE );
3120 DEBUG(
"Creating %s table\n", table_name );
3122 ok = do_create_table( be, table_name, col_table );
3134 g_return_val_if_fail( be != NULL, FALSE );
3135 g_return_val_if_fail( table_name != NULL, FALSE );
3136 g_return_val_if_fail( col_table != NULL, FALSE );
3138 return do_create_table( be, table_name, col_table );
3143 const gchar* table_name,
3148 g_return_val_if_fail( be != NULL, FALSE );
3149 g_return_val_if_fail( index_name != NULL, FALSE );
3150 g_return_val_if_fail( table_name != NULL, FALSE );
3151 g_return_val_if_fail( col_table != NULL, FALSE );
3153 ok = gnc_sql_connection_create_index( be->
conn, index_name, table_name,
3161 g_return_val_if_fail( be != NULL, 0 );
3162 g_return_val_if_fail( table_name != NULL, 0 );
3170 return GPOINTER_TO_INT(g_hash_table_lookup( be->
versions, table_name ));
3180 gchar* temp_table_name;
3182 g_return_if_fail( be != NULL );
3183 g_return_if_fail( table_name != NULL );
3184 g_return_if_fail( col_table != NULL );
3186 DEBUG(
"Upgrading %s table\n", table_name );
3188 temp_table_name = g_strdup_printf(
"%s_new", table_name );
3190 sql = g_strdup_printf(
"INSERT INTO %s SELECT * FROM %s",
3191 temp_table_name, table_name );
3195 sql = g_strdup_printf(
"DROP TABLE %s", table_name );
3199 sql = g_strdup_printf(
"ALTER TABLE %s RENAME TO %s", temp_table_name, table_name );
3202 g_free( temp_table_name );
3209 GList* col_info_list = NULL;
3210 gboolean ok = FALSE;
3212 g_return_val_if_fail( be != NULL, FALSE );
3213 g_return_val_if_fail( table_name != NULL, FALSE );
3214 g_return_val_if_fail( new_col_table != NULL, FALSE );
3216 for ( ; new_col_table->
col_name != NULL; new_col_table++ )
3220 pHandler = get_handler( new_col_table );
3221 g_assert( pHandler != NULL );
3224 g_assert( col_info_list != NULL );
3225 ok = gnc_sql_connection_add_columns_to_table( be->
conn, table_name, col_info_list );
3230 #define VERSION_TABLE_NAME "versions"
3231 #define MAX_TABLE_NAME_LEN 50
3232 #define TABLE_COL_NAME "table_name"
3233 #define VERSION_COL_NAME "table_version"
3239 { VERSION_COL_NAME, CT_INT, 0,
COL_NNUL },
3253 g_return_if_fail( be != NULL );
3257 g_hash_table_destroy( be->
versions );
3259 be->
versions = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL );
3261 if ( gnc_sql_connection_does_table_exist( be->
conn, VERSION_TABLE_NAME ) )
3266 sql = g_strdup_printf(
"SELECT * FROM %s", VERSION_TABLE_NAME );
3269 if ( result != NULL )
3272 const GValue* version;
3275 row = gnc_sql_result_get_first_row( result );
3276 while ( row != NULL )
3278 name = gnc_sql_row_get_value_at_col_name( row, TABLE_COL_NAME );
3279 version = gnc_sql_row_get_value_at_col_name( row, VERSION_COL_NAME );
3281 g_strdup( g_value_get_string( name ) ),
3282 GINT_TO_POINTER((gint)g_value_get_int64( version )) );
3283 row = gnc_sql_result_get_next_row( result );
3285 gnc_sql_result_dispose( result );
3290 do_create_table( be, VERSION_TABLE_NAME, version_table );
3292 gnc_prefs_get_long_version() );
3294 GNUCASH_RESAVE_VERSION );
3310 g_return_val_if_fail( be != NULL, FALSE );
3312 ok = do_create_table( be, VERSION_TABLE_NAME, version_table );
3315 be->
versions = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL );
3319 g_hash_table_remove_all( be->
versions );
3335 g_return_if_fail( be != NULL );
3339 g_hash_table_destroy( be->
versions );
3360 g_return_val_if_fail( be != NULL, FALSE );
3361 g_return_val_if_fail( table_name != NULL, FALSE );
3362 g_return_val_if_fail( version > 0, FALSE );
3365 if ( cur_version != version )
3367 if ( cur_version == 0 )
3369 sql = g_strdup_printf(
"INSERT INTO %s VALUES('%s',%d)", VERSION_TABLE_NAME,
3370 table_name, version );
3374 sql = g_strdup_printf(
"UPDATE %s SET %s=%d WHERE %s='%s'", VERSION_TABLE_NAME,
3375 VERSION_COL_NAME, version,
3376 TABLE_COL_NAME, table_name );
3381 PERR(
"SQL error: %s\n", sql );
3387 g_hash_table_insert( be->
versions, g_strdup( table_name ), GINT_TO_POINTER(version) );
gboolean(* commit)(GncSqlBackend *be, QofInstance *inst)
const gchar * qof_param_name
int xaccAccountTreeForEachTransaction(Account *acc, TransactionCallback proc, void *data)
gboolean gnc_sql_object_is_it_in_db(GncSqlBackend *be, const gchar *table_name, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
load and save vendor data to SQL
gchar * gnc_timespec_to_iso8601_buff(Timespec ts, gchar *buff)
void gnc_sql_begin_edit(GncSqlBackend *be, QofInstance *inst)
void gnc_sql_finalize_version_info(GncSqlBackend *be)
void qof_backend_set_error(QofBackend *be, QofBackendError err)
time64 timespecToTime64(Timespec ts)
const GncGUID * qof_instance_get_guid(gconstpointer)
gint gnc_sql_get_table_version(const GncSqlBackend *be, const gchar *table_name)
gint gnc_account_n_descendants(const Account *account)
GNC_SQL_ADD_GVALUE_TO_SLIST_FN add_gvalue_to_slist_fn
gboolean(* write)(GncSqlBackend *be)
QofAccessFunc gnc_sql_get_getter(QofIdTypeConst obj_name, const GncSqlColumnTableEntry *table_row)
void gnc_sql_rollback_edit(GncSqlBackend *be, QofInstance *inst)
void gnc_account_foreach_descendant(const Account *acc, AccountCb thunk, gpointer user_data)
void gnc_sql_upgrade_table(GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
const GncGUID * gnc_sql_load_tx_guid(const GncSqlBackend *be, GncSqlRow *row)
a simple price database for gnucash
#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)
void gnc_sql_init(GncSqlBackend *be)
const gchar * QofIdTypeConst
load and save accounts data to SQL
GncSqlStatement * gnc_sql_create_select_statement(GncSqlBackend *be, const gchar *table_name)
#define DEBUG(format, args...)
gboolean qof_instance_get_destroying(gconstpointer ptr)
gboolean string_to_guid(const gchar *string, GncGUID *guid)
gint gnc_sql_execute_nonselect_sql(GncSqlBackend *be, const gchar *sql)
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)
Use a 64-bit unsigned int timespec.
load and save customer data to SQL
Account * gnc_book_get_template_root(const QofBook *book)
gboolean gnc_sql_add_columns_to_table(GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *new_col_table)
void gnc_sql_add_objectref_guid_col_info_to_list(const GncSqlBackend *be, const GncSqlColumnTableEntry *table_row, GList **pList)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
gboolean gnc_sql_save_transaction(GncSqlBackend *be, QofInstance *inst)
load and save accounts data to SQL
load and save data to SQL
#define PERR(format, args...)
#define ENTER(format, args...)
QofAccessFunc qof_class_get_parameter_getter(QofIdTypeConst obj_name, const char *parameter)
struct _QofQuery QofQuery
gint64 gnc_sql_get_integer_value(const GValue *value)
gboolean gnc_sql_create_index(const GncSqlBackend *be, const gchar *index_name, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
void(* run_query)(GncSqlBackend *be, gpointer pQuery)
void gnc_tm_free(struct tm *time)
free a struct tm* created with gnc_localtime() or gnc_gmtime()
#define PWARN(format, args...)
const GncGUID * gnc_sql_load_guid(const GncSqlBackend *be, GncSqlRow *row)
GncSqlBasicColumnType type
void gnc_sql_set_load_order(const gchar **load_order)
load and save accounts data to SQL
load and save order data to SQL
Account handling public routines.
void(* initial_load)(GncSqlBackend *be)
guint gnc_sql_append_guid_list_to_sql(GString *sql, GList *list, guint maxCount)
gboolean gnc_sql_set_table_version(GncSqlBackend *be, const gchar *table_name, gint version)
load and save owner data to SQL
void qof_book_mark_session_saved(QofBook *book)
load and save job data to SQL
load and save accounts data to SQL
void gnc_sql_add_gvalue_objectref_guid_to_slist(const GncSqlBackend *be, QofIdTypeConst obj_name, const gpointer pObject, const GncSqlColumnTableEntry *table_row, GSList **pList)
#define GUID_ENCODING_LENGTH
load and save data to SQL
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
Anchor Scheduled Transaction info in a book. See src/doc/books.txt for design overview.
load and save employee data to SQL
load and save data to SQL
Tax Table programming interface.
gchar * gnc_sql_get_sql_value(const GncSqlConnection *conn, const GValue *value)
GNC_SQL_ADD_COL_INFO_TO_LIST_FN add_col_info_to_list_fn
GncSqlResult * gnc_sql_execute_select_statement(GncSqlBackend *be, GncSqlStatement *stmt)
Timespec gnc_iso8601_to_timespec_gmt(const gchar *)
All type declarations for the whole Gnucash engine.
void gnc_sql_load_object(const GncSqlBackend *be, GncSqlRow *row, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
const gchar * gobj_param_name
struct _gnc_numeric gnc_numeric
An rational-number type.
void gnc_sql_push_commodity_for_postload_processing(GncSqlBackend *be, gpointer *comm)
GNC_SQL_ADD_COLNAME_TO_LIST_FN add_colname_to_list_fn
gboolean gnc_sql_create_temp_table(const GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
load and save data to SQL
void gnc_sql_transaction_load_all_tx(GncSqlBackend *be)
Generic api to store and retrieve preferences.
void gnc_sql_commit_edit(GncSqlBackend *be, QofInstance *inst)
GList * gnc_account_get_descendants(const Account *account)
API for the transaction logger.
Business Invoice Interface.
guint gnc_book_count_transactions(QofBook *book)
gboolean gnc_sql_slots_delete(GncSqlBackend *be, const GncGUID *guid)
gboolean qof_book_is_readonly(const QofBook *book)
load and save address data to SQL
void gnc_sql_sync_all(GncSqlBackend *be, QofBook *book)
void(* free_query)(GncSqlBackend *be, gpointer pQuery)
void qof_event_suspend(void)
Suspend all engine events.
void xaccAccountBeginEdit(Account *acc)
QofIdType qof_query_get_search_for(const QofQuery *q)
void qof_event_resume(void)
load and save entry data to SQL
gboolean gnc_sql_commit_standard_item(GncSqlBackend *be, QofInstance *inst, const gchar *tableName, QofIdTypeConst obj_name, const GncSqlColumnTableEntry *col_table)
#define LEAVE(format, args...)
void(* QofSetterFunc)(gpointer, gpointer)
struct tm * gnc_gmtime(const time64 *secs)
fill out a time struct from a 64-bit time value
gpointer(* compile_query)(GncSqlBackend *be, QofQuery *pQuery)
int qof_query_has_terms(QofQuery *q)
gboolean gnc_sql_do_db_operation(GncSqlBackend *be, E_DB_OPERATION op, const gchar *table_name, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
GncSqlStatement * gnc_sql_create_statement_from_sql(GncSqlBackend *be, const gchar *sql)
void(* create_tables)(GncSqlBackend *be)
const gchar * timespec_format
load and save data to SQL
load and save invoice data to SQL
QofSetterFunc qof_class_get_parameter_setter(QofIdTypeConst obj_name, const char *parameter)
void xaccAccountCommitEdit(Account *acc)
void gnc_sql_init_version_info(GncSqlBackend *be)
struct timespec64 Timespec
void gnc_sql_add_subtable_colnames_to_list(const GncSqlColumnTableEntry *table_row, const GncSqlColumnTableEntry *subtable, GList **pList)
void gnc_sql_load(GncSqlBackend *be, QofBook *book, QofBackendLoadType loadType)
gboolean gnc_sql_slots_save(GncSqlBackend *be, const GncGUID *guid, gboolean is_infant, KvpFrame *pFrame)
GncSqlResult * gnc_sql_execute_select_sql(GncSqlBackend *be, const gchar *sql)
const gchar * QofLogModule
load and save tax table data to SQL
void timespecFromTime64(Timespec *ts, time64 t)
gchar * gnc_sql_convert_timespec_to_string(const GncSqlBackend *be, Timespec ts)