GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Modules | Files | Data Structures | Macros | Typedefs | Enumerations | Functions
SQL Backend Core

Modules

 Columns
 

Files

file  gnc-backend-sql.h
 load and save data to SQL
 

Data Structures

struct  GncSqlBackend
 
struct  GncSqlStatement
 
struct  GncSqlConnection
 
struct  GncSqlRow
 
struct  GncSqlResult
 
struct  GncSqlObjectBackend
 
struct  GncSqlColumnInfo
 
struct  GncSqlColumnTableEntry
 
struct  GncSqlColumnTypeHandler
 
struct  write_objects_t
 

Macros

#define gnc_sql_statement_dispose(STMT)   (STMT)->dispose(STMT)
 
#define gnc_sql_statement_to_sql(STMT)   (STMT)->toSql(STMT)
 
#define gnc_sql_statement_add_where_cond(STMT, TYPENAME, OBJ, COLDESC, VALUE)   (STMT)->addWhereCond(STMT, TYPENAME, OBJ, COLDESC, VALUE)
 
#define gnc_sql_connection_dispose(CONN)   (CONN)->dispose(CONN)
 
#define gnc_sql_connection_execute_select_statement(CONN, STMT)   (CONN)->executeSelectStatement(CONN,STMT)
 
#define gnc_sql_connection_execute_nonselect_statement(CONN, STMT)   (CONN)->executeNonSelectStatement(CONN,STMT)
 
#define gnc_sql_connection_create_statement_from_sql(CONN, SQL)   (CONN)->createStatementFromSql(CONN,SQL)
 
#define gnc_sql_connection_does_table_exist(CONN, NAME)   (CONN)->doesTableExist(CONN,NAME)
 
#define gnc_sql_connection_begin_transaction(CONN)   (CONN)->beginTransaction(CONN)
 
#define gnc_sql_connection_rollback_transaction(CONN)   (CONN)->rollbackTransaction(CONN)
 
#define gnc_sql_connection_commit_transaction(CONN)   (CONN)->commitTransaction(CONN)
 
#define gnc_sql_connection_create_table(CONN, NAME, COLLIST)   (CONN)->createTable(CONN,NAME,COLLIST)
 
#define gnc_sql_connection_create_index(CONN, INDEXNAME, TABLENAME, COLTABLE)   (CONN)->createIndex(CONN,INDEXNAME,TABLENAME,COLTABLE)
 
#define gnc_sql_connection_add_columns_to_table(CONN, TABLENAME, COLLIST)   (CONN)->addColumnsToTable(CONN,TABLENAME,COLLIST)
 
#define gnc_sql_connection_quote_string(CONN, STR)   (CONN)->quoteString(CONN,STR)
 
#define gnc_sql_row_get_value_at_col_name(ROW, N)   (ROW)->getValueAtColName(ROW,N)
 
#define gnc_sql_row_dispose(ROW)   (ROW)->dispose(ROW)
 
#define gnc_sql_result_get_num_rows(RESULT)   (RESULT)->getNumRows(RESULT)
 
#define gnc_sql_result_get_first_row(RESULT)   (RESULT)->getFirstRow(RESULT)
 
#define gnc_sql_result_get_next_row(RESULT)   (RESULT)->getNextRow(RESULT)
 
#define gnc_sql_result_dispose(RESULT)   (RESULT)->dispose(RESULT)
 
#define GNC_SQL_BACKEND   "gnc:sql:1"
 
#define GNC_SQL_BACKEND_VERSION   1
 
#define CT_STRING   "ct_string"
 
#define CT_GUID   "ct_guid"
 
#define CT_INT   "ct_int"
 
#define CT_INT64   "ct_int64"
 
#define CT_TIMESPEC   "ct_timespec"
 
#define CT_GDATE   "ct_gdate"
 
#define CT_NUMERIC   "ct_numeric"
 
#define CT_DOUBLE   "ct_double"
 
#define CT_BOOLEAN   "ct_boolean"
 
#define CT_ACCOUNTREF   "ct_accountref"
 
#define CT_BUDGETREF   "ct_budgetref"
 
#define CT_COMMODITYREF   "ct_commodityref"
 
#define CT_LOTREF   "ct_lotref"
 
#define CT_TXREF   "ct_txref"
 

Typedefs

typedef struct GncSqlConnection GncSqlConnection
 
typedef struct GncSqlBackend GncSqlBackend
 
typedef struct
GncSqlColumnTableEntry 
GncSqlColumnTableEntry
 
typedef struct GncSqlStatement GncSqlStatement
 
typedef struct GncSqlResult GncSqlResult
 
typedef struct GncSqlRow GncSqlRow
 
typedef void(* GNC_SQL_LOAD_FN )(const GncSqlBackend *be, GncSqlRow *row, QofSetterFunc setter, gpointer pObject, const GncSqlColumnTableEntry *table)
 
typedef void(* GNC_SQL_ADD_COL_INFO_TO_LIST_FN )(const GncSqlBackend *be, const GncSqlColumnTableEntry *table_row, GList **pList)
 
typedef void(* GNC_SQL_ADD_COLNAME_TO_LIST_FN )(const GncSqlColumnTableEntry *table_row, GList **pList)
 
typedef void(* GNC_SQL_ADD_GVALUE_TO_SLIST_FN )(const GncSqlBackend *be, QofIdTypeConst obj_name, const gpointer pObject, const GncSqlColumnTableEntry *table_row, GSList **pList)
 

Enumerations

enum  GncSqlBasicColumnType {
  BCT_STRING, BCT_INT, BCT_INT64, BCT_DATE,
  BCT_DOUBLE, BCT_DATETIME
}
 
enum  E_DB_OPERATION { OP_DB_INSERT, OP_DB_UPDATE, OP_DB_DELETE }
 

Functions

void gnc_sql_init (GncSqlBackend *be)
 
void gnc_sql_load (GncSqlBackend *be, QofBook *book, QofBackendLoadType loadType)
 
void gnc_sql_push_commodity_for_postload_processing (GncSqlBackend *be, gpointer *comm)
 
void gnc_sql_sync_all (GncSqlBackend *be, QofBook *book)
 
void gnc_sql_begin_edit (GncSqlBackend *be, QofInstance *inst)
 
void gnc_sql_rollback_edit (GncSqlBackend *qbe, QofInstance *inst)
 
void gnc_sql_commit_edit (GncSqlBackend *qbe, QofInstance *inst)
 
QofAccessFunc gnc_sql_get_getter (QofIdTypeConst obj_name, const GncSqlColumnTableEntry *table_row)
 
void gnc_sql_add_colname_to_list (const GncSqlColumnTableEntry *table_row, GList **pList)
 
gboolean gnc_sql_do_db_operation (GncSqlBackend *be, E_DB_OPERATION op, const gchar *table_name, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
 
GncSqlResultgnc_sql_execute_select_statement (GncSqlBackend *be, GncSqlStatement *statement)
 
GncSqlResultgnc_sql_execute_select_sql (GncSqlBackend *be, const gchar *sql)
 
gint gnc_sql_execute_nonselect_sql (GncSqlBackend *be, const gchar *sql)
 
GncSqlStatementgnc_sql_create_statement_from_sql (GncSqlBackend *be, const gchar *sql)
 
void gnc_sql_load_object (const GncSqlBackend *be, GncSqlRow *row, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
 
gboolean gnc_sql_object_is_it_in_db (GncSqlBackend *be, const gchar *table_name, QofIdTypeConst obj_name, const gpointer pObject, const GncSqlColumnTableEntry *table)
 
gint gnc_sql_get_table_version (const GncSqlBackend *be, const gchar *table_name)
 
gboolean gnc_sql_set_table_version (GncSqlBackend *be, const gchar *table_name, gint version)
 
gboolean gnc_sql_create_table (GncSqlBackend *be, const gchar *table_name, gint table_version, const GncSqlColumnTableEntry *col_table)
 
gboolean gnc_sql_create_temp_table (const GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
 
gboolean gnc_sql_create_index (const GncSqlBackend *be, const gchar *index_name, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
 
const GncGUIDgnc_sql_load_guid (const GncSqlBackend *be, GncSqlRow *row)
 
const GncGUIDgnc_sql_load_tx_guid (const GncSqlBackend *be, GncSqlRow *row)
 
GncSqlStatementgnc_sql_create_select_statement (GncSqlBackend *be, const gchar *table_name)
 
void gnc_sql_register_col_type_handler (const gchar *colType, const GncSqlColumnTypeHandler *handler)
 
void gnc_sql_add_gvalue_objectref_guid_to_slist (const GncSqlBackend *be, QofIdTypeConst obj_name, const gpointer pObject, const GncSqlColumnTableEntry *table_row, GSList **pList)
 
void gnc_sql_add_objectref_guid_col_info_to_list (const GncSqlBackend *be, const GncSqlColumnTableEntry *table_row, GList **pList)
 
guint gnc_sql_append_guid_list_to_sql (GString *str, GList *list, guint maxCount)
 
void gnc_sql_add_subtable_colnames_to_list (const GncSqlColumnTableEntry *table_row, const GncSqlColumnTableEntry *subtable, GList **pList)
 
gchar * gnc_sql_get_sql_value (const GncSqlConnection *conn, const GValue *value)
 
void gnc_sql_init_version_info (GncSqlBackend *be)
 
void gnc_sql_finalize_version_info (GncSqlBackend *be)
 
gboolean gnc_sql_commit_standard_item (GncSqlBackend *be, QofInstance *inst, const gchar *tableName, QofIdTypeConst obj_name, const GncSqlColumnTableEntry *col_table)
 
gint64 gnc_sql_get_integer_value (const GValue *value)
 
gchar * gnc_sql_convert_timespec_to_string (const GncSqlBackend *be, Timespec ts)
 
void gnc_sql_upgrade_table (GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
 
gboolean gnc_sql_add_columns_to_table (GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *new_col_table)
 
void gnc_sql_set_load_order (const gchar **load_order)
 
void _retrieve_guid_ (gpointer pObject, gpointer pValue)
 
gpointer gnc_sql_compile_query (QofBackend *pBEnd, QofQuery *pQuery)
 
void gnc_sql_free_query (QofBackend *pBEnd, gpointer pQuery)
 
void gnc_sql_run_query (QofBackend *pBEnd, gpointer pQuery)
 

Detailed Description

Enumeration Type Documentation

Basic column type

Definition at line 286 of file gnc-backend-sql.h.

287 {
288  BCT_STRING,
289  BCT_INT,
290  BCT_INT64,
291  BCT_DATE,
292  BCT_DOUBLE,
293  BCT_DATETIME
GncSqlBasicColumnType

Function Documentation

void gnc_sql_add_colname_to_list ( const GncSqlColumnTableEntry table_row,
GList **  pList 
)

Adds a column name to a list. If the column type spans multiple columns, all of the column names for the pieces are added.

Parameters
table_rowDB table column
pListList

Definition at line 1166 of file gnc-backend-sql.c.

1167 {
1168  (*pList) = g_list_append( (*pList), g_strdup( table_row->col_name ) );
1169 }
gboolean gnc_sql_add_columns_to_table ( GncSqlBackend be,
const gchar *  table_name,
const GncSqlColumnTableEntry new_col_table 
)

Adds one or more columns to an existing table.

Parameters
beSQL backend
table_nameSQL table name
new_col_tableColumn table for new columns
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 3206 of file gnc-backend-sql.c.

3208 {
3209  GList* col_info_list = NULL;
3210  gboolean ok = FALSE;
3211 
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 );
3215 
3216  for ( ; new_col_table->col_name != NULL; new_col_table++ )
3217  {
3218  GncSqlColumnTypeHandler* pHandler;
3219 
3220  pHandler = get_handler( new_col_table );
3221  g_assert( pHandler != NULL );
3222  pHandler->add_col_info_to_list_fn( be, new_col_table, &col_info_list );
3223  }
3224  g_assert( col_info_list != NULL );
3225  ok = gnc_sql_connection_add_columns_to_table( be->conn, table_name, col_info_list );
3226  return ok;
3227 }
GncSqlConnection * conn
GNC_SQL_ADD_COL_INFO_TO_LIST_FN add_col_info_to_list_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 
)

Adds a GValue for an object reference GncGUID to the end of a GSList.

Parameters
beSQL backend struct
obj_nameQOF object type name
pObjectObject
table_rowDB table column description
pListList

Definition at line 1825 of file gnc-backend-sql.c.

1827 {
1828  QofAccessFunc getter;
1829  const GncGUID* guid = NULL;
1830  gchar guid_buf[GUID_ENCODING_LENGTH+1];
1831  QofInstance* inst = NULL;
1832  GValue* value;
1833 
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 );
1838 
1839  value = g_new0( GValue, 1 );
1840  g_assert( value != NULL );
1841  if ( table_row->gobj_param_name != NULL )
1842  {
1843  g_object_get( pObject, table_row->gobj_param_name, &inst, NULL );
1844  }
1845  else
1846  {
1847  getter = gnc_sql_get_getter( obj_name, table_row );
1848  if ( getter != NULL )
1849  {
1850  inst = (*getter)( pObject, NULL );
1851  }
1852  }
1853  if ( inst != NULL )
1854  {
1855  guid = qof_instance_get_guid( inst );
1856  }
1857  (void)g_value_init( value, G_TYPE_STRING );
1858  if ( guid != NULL )
1859  {
1860  (void)guid_to_string_buff( guid, guid_buf );
1861  g_value_set_string( value, guid_buf );
1862  }
1863 
1864  (*pList) = g_slist_append( (*pList), value );
1865 }
const GncGUID * qof_instance_get_guid(gconstpointer)
QofAccessFunc gnc_sql_get_getter(QofIdTypeConst obj_name, const GncSqlColumnTableEntry *table_row)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:177
Definition: guid.h:65
#define GUID_ENCODING_LENGTH
Definition: guid.h:74
const gchar * gobj_param_name
void gnc_sql_add_objectref_guid_col_info_to_list ( const GncSqlBackend be,
const GncSqlColumnTableEntry table_row,
GList **  pList 
)

Adds a column info structure for an object reference GncGUID to the end of a GList.

Parameters
beSQL backend struct
table_rowDB table column description
pListList

Definition at line 1868 of file gnc-backend-sql.c.

1871 {
1872  add_guid_col_info_to_list( be, table_row, pList );
1873 }
void gnc_sql_add_subtable_colnames_to_list ( const GncSqlColumnTableEntry table_row,
const GncSqlColumnTableEntry subtable,
GList **  pList 
)

Appends column names for a subtable to the end of a GList.

Parameters
table_rowMain DB column description
subtableSub-column description table
pListList

Definition at line 1173 of file gnc-backend-sql.c.

1175 {
1176  const GncSqlColumnTableEntry* subtable_row;
1177  gchar* buf;
1178 
1179  for ( subtable_row = subtable; subtable_row->col_name != NULL; subtable_row++ )
1180  {
1181  buf = g_strdup_printf( "%s_%s", table_row->col_name, subtable_row->col_name );
1182  (*pList) = g_list_append( (*pList), buf );
1183  }
1184 }
guint gnc_sql_append_guid_list_to_sql ( GString *  str,
GList *  list,
guint  maxCount 
)

Appends the ascii strings for a list of GUIDs to the end of an SQL string.

Parameters
strSQL string
listList of GUIDs
maxCountMax # of GUIDs to append
Returns
Number of GUIDs appended

Definition at line 2629 of file gnc-backend-sql.c.

2630 {
2631  gchar guid_buf[GUID_ENCODING_LENGTH+1];
2632  gboolean first_guid = TRUE;
2633  guint count;
2634 
2635  g_return_val_if_fail( sql != NULL, 0 );
2636 
2637  if ( list == NULL ) return 0;
2638 
2639  for ( count = 0; list != NULL && count < maxCount; list = list->next, count++ )
2640  {
2641  QofInstance* inst = QOF_INSTANCE(list->data);
2642  (void)guid_to_string_buff( qof_instance_get_guid( inst ), guid_buf );
2643 
2644  if ( !first_guid )
2645  {
2646  (void)g_string_append( sql, "," );
2647  }
2648  (void)g_string_append( sql, "'" );
2649  (void)g_string_append( sql, guid_buf );
2650  (void)g_string_append( sql, "'" );
2651  first_guid = FALSE;
2652  }
2653 
2654  return count;
2655 }
const GncGUID * qof_instance_get_guid(gconstpointer)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
#define GUID_ENCODING_LENGTH
Definition: guid.h:74
void gnc_sql_begin_edit ( GncSqlBackend be,
QofInstance inst 
)

An object is about to be edited.

Parameters
beSQL backend
instObject being edited

Definition at line 526 of file gnc-backend-sql.c.

527 {
528  g_return_if_fail( be != NULL );
529  g_return_if_fail( inst != NULL );
530 
531  ENTER( " " );
532  LEAVE( "" );
533 }
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
void gnc_sql_commit_edit ( GncSqlBackend qbe,
QofInstance inst 
)

Object editting is complete and the object should be saved.

Parameters
qbeSQL backend
instObject being edited

Definition at line 569 of file gnc-backend-sql.c.

570 {
571  sql_backend be_data;
572  gboolean is_dirty;
573  gboolean is_destroying;
574  gboolean is_infant;
575 
576  g_return_if_fail( be != NULL );
577  g_return_if_fail( inst != NULL );
578 
579  if ( qof_book_is_readonly( be->book ) )
580  {
582  (void)gnc_sql_connection_rollback_transaction( be->conn );
583  return;
584  }
585  /* During initial load where objects are being created, don't commit
586  anything, but do mark the object as clean. */
587  if ( be->loading )
588  {
589  qof_instance_mark_clean( inst );
590  return;
591  }
592 
593  // The engine has a PriceDB object but it isn't in the database
594  if ( strcmp( inst->e_type, "PriceDB" ) == 0 )
595  {
596  qof_instance_mark_clean( inst );
597  qof_book_mark_session_saved( be->book );
598  return;
599  }
600 
601  ENTER( " " );
602 
603  is_dirty = qof_instance_get_dirty_flag( inst );
604  is_destroying = qof_instance_get_destroying( inst );
605  is_infant = qof_instance_get_infant( inst );
606 
607  DEBUG( "%s dirty = %d, do_free = %d, infant = %d\n",
608  (inst->e_type ? inst->e_type : "(null)"),
609  is_dirty, is_destroying, is_infant );
610 
611  if ( !is_dirty && !is_destroying )
612  {
613  LEAVE( "!dirty OR !destroying" );
614  return;
615  }
616 
617  if ( !gnc_sql_connection_begin_transaction( be->conn ) )
618  {
619  PERR( "gnc_sql_commit_edit(): begin_transaction failed\n" );
620  LEAVE( "Rolled back - database transaction begin error" );
621  return;
622  }
623 
624  be_data.is_known = FALSE;
625  be_data.be = be;
626  be_data.inst = inst;
627  be_data.is_ok = TRUE;
628 
629  qof_object_foreach_backend( GNC_SQL_BACKEND, commit_cb, &be_data );
630 
631  if ( !be_data.is_known )
632  {
633  PERR( "gnc_sql_commit_edit(): Unknown object type '%s'\n", inst->e_type );
634  (void)gnc_sql_connection_rollback_transaction( be->conn );
635 
636  // Don't let unknown items still mark the book as being dirty
637  qof_book_mark_session_saved( be->book );
638  qof_instance_mark_clean(inst);
639  LEAVE( "Rolled back - unknown object type" );
640  return;
641  }
642  if ( !be_data.is_ok )
643  {
644  // Error - roll it back
645  (void)gnc_sql_connection_rollback_transaction( be->conn );
646 
647  // This *should* leave things marked dirty
648  LEAVE( "Rolled back - database error" );
649  return;
650  }
651 
652  (void)gnc_sql_connection_commit_transaction( be->conn );
653 
654  qof_book_mark_session_saved( be->book );
655  qof_instance_mark_clean(inst);
656 
657  LEAVE( "" );
658 }
QofIdType e_type
Definition: qofinstance.h:69
void qof_backend_set_error(QofBackend *be, QofBackendError err)
#define DEBUG(format, args...)
Definition: qoflog.h:255
gboolean qof_instance_get_destroying(gconstpointer ptr)
#define PERR(format, args...)
Definition: qoflog.h:237
#define ENTER(format, args...)
Definition: qoflog.h:261
void qof_book_mark_session_saved(QofBook *book)
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
gboolean qof_book_is_readonly(const QofBook *book)
#define LEAVE(format, args...)
Definition: qoflog.h:271
gboolean gnc_sql_commit_standard_item ( GncSqlBackend be,
QofInstance inst,
const gchar *  tableName,
QofIdTypeConst  obj_name,
const GncSqlColumnTableEntry col_table 
)

Commits a "standard" item to the database. In most cases, a commit of one object vs another differs only in the table name and column table.

Parameters
beSQL backend
instInstance
tableNameSQL table name
obj_nameQOF object type name
col_tableColumn table
Returns
TRUE if successful, FALSE if not

Definition at line 3044 of file gnc-backend-sql.c.

3046 {
3047  const GncGUID* guid;
3048  gboolean is_infant;
3049  gint op;
3050  gboolean is_ok;
3051 
3052  is_infant = qof_instance_get_infant( inst );
3053  if ( qof_instance_get_destroying( inst ) )
3054  {
3055  op = OP_DB_DELETE;
3056  }
3057  else if ( be->is_pristine_db || is_infant )
3058  {
3059  op = OP_DB_INSERT;
3060  }
3061  else
3062  {
3063  op = OP_DB_UPDATE;
3064  }
3065  is_ok = gnc_sql_do_db_operation( be, op, tableName, obj_name, inst, col_table );
3066 
3067  if ( is_ok )
3068  {
3069  // Now, commit any slots
3070  guid = qof_instance_get_guid( inst );
3071  if ( !qof_instance_get_destroying(inst) )
3072  {
3073  is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
3074  }
3075  else
3076  {
3077  is_ok = gnc_sql_slots_delete( be, guid );
3078  }
3079  }
3080 
3081  return is_ok;
3082 }
const GncGUID * qof_instance_get_guid(gconstpointer)
gboolean qof_instance_get_destroying(gconstpointer ptr)
Definition: guid.h:65
gboolean gnc_sql_slots_delete(GncSqlBackend *be, const GncGUID *guid)
gboolean is_pristine_db
gboolean gnc_sql_do_db_operation(GncSqlBackend *be, E_DB_OPERATION op, const gchar *table_name, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
gboolean gnc_sql_slots_save(GncSqlBackend *be, const GncGUID *guid, gboolean is_infant, KvpFrame *pFrame)
gchar* gnc_sql_convert_timespec_to_string ( const GncSqlBackend be,
Timespec  ts 
)

Converts a Timespec value to a string value for the database.

Parameters
beSQL backend
tsTimespec to be converted
Returns
String representation of the Timespec

Definition at line 1883 of file gnc-backend-sql.c.

1884 {
1885  time64 time;
1886  struct tm* tm;
1887  gint year;
1888  gchar* datebuf;
1889 
1890  time = timespecToTime64( ts );
1891  tm = gnc_gmtime( &time );
1892 
1893  year = tm->tm_year + 1900;
1894 
1895  datebuf = g_strdup_printf( be->timespec_format,
1896  year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec );
1897  gnc_tm_free (tm);
1898  return datebuf;
1899 }
time64 timespecToTime64(Timespec ts)
void gnc_tm_free(struct tm *time)
free a struct tm* created with gnc_localtime() or gnc_gmtime()
struct tm * gnc_gmtime(const time64 *secs)
fill out a time struct from a 64-bit time value
gint64 time64
Definition: gnc-date.h:83
const gchar * timespec_format
gboolean gnc_sql_create_index ( const GncSqlBackend be,
const gchar *  index_name,
const gchar *  table_name,
const GncSqlColumnTableEntry col_table 
)

Creates an index in the database

Parameters
beSQL backend struct
index_nameIndex name
table_nameTable name
col_tableColumns that the index should index
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 3142 of file gnc-backend-sql.c.

3145 {
3146  gboolean ok;
3147 
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 );
3152 
3153  ok = gnc_sql_connection_create_index( be->conn, index_name, table_name,
3154  col_table );
3155  return ok;
3156 }
GncSqlConnection * conn
GncSqlStatement* gnc_sql_create_select_statement ( GncSqlBackend be,
const gchar *  table_name 
)

Creates a basic SELECT statement for a table.

Parameters
beSQL backend struct
table_nameTable name
Returns
Statement

Definition at line 2495 of file gnc-backend-sql.c.

2496 {
2497  gchar* sql;
2498  GncSqlStatement* stmt;
2499 
2500  g_return_val_if_fail( be != NULL, NULL );
2501  g_return_val_if_fail( table_name != NULL, NULL );
2502 
2503  sql = g_strdup_printf( "SELECT * FROM %s", table_name );
2504  stmt = gnc_sql_create_statement_from_sql( be, sql );
2505  g_free( sql );
2506  return stmt;
2507 }
GncSqlStatement * gnc_sql_create_statement_from_sql(GncSqlBackend *be, const gchar *sql)
GncSqlStatement* gnc_sql_create_statement_from_sql ( GncSqlBackend be,
const gchar *  sql 
)

Creates a statement from an SQL char string.

Parameters
beSQL backend struct
sqlSQL char string
Returns
Statement

Definition at line 2548 of file gnc-backend-sql.c.

2549 {
2550  GncSqlStatement* stmt;
2551 
2552  g_return_val_if_fail( be != NULL, NULL );
2553  g_return_val_if_fail( sql != NULL, NULL );
2554 
2555  stmt = gnc_sql_connection_create_statement_from_sql( be->conn, sql );
2556  if ( stmt == NULL )
2557  {
2558  PERR( "SQL error: %s\n", sql );
2560  }
2561 
2562  return stmt;
2563 }
void qof_backend_set_error(QofBackend *be, QofBackendError err)
GncSqlConnection * conn
QofBackend be
#define PERR(format, args...)
Definition: qoflog.h:237
gboolean gnc_sql_create_table ( GncSqlBackend be,
const gchar *  table_name,
gint  table_version,
const GncSqlColumnTableEntry col_table 
)

Creates a table in the database

Parameters
beSQL backend struct
table_nameTable name
table_versionTable version
col_tableDB table description
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 3111 of file gnc-backend-sql.c.

3113 {
3114  gboolean ok;
3115 
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 );
3119 
3120  DEBUG( "Creating %s table\n", table_name );
3121 
3122  ok = do_create_table( be, table_name, col_table );
3123  if ( ok )
3124  {
3125  ok = gnc_sql_set_table_version( be, table_name, table_version );
3126  }
3127  return ok;
3128 }
#define DEBUG(format, args...)
Definition: qoflog.h:255
gboolean gnc_sql_set_table_version(GncSqlBackend *be, const gchar *table_name, gint version)
gboolean gnc_sql_create_temp_table ( const GncSqlBackend be,
const gchar *  table_name,
const GncSqlColumnTableEntry col_table 
)

Creates a temporary table in the database. A temporary table does not have a version number added to the versions table.

Parameters
beSQL backend struct
table_nameTable name
col_tableDB table description
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 3131 of file gnc-backend-sql.c.

3133 {
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 );
3137 
3138  return do_create_table( be, table_name, col_table );
3139 }
gboolean gnc_sql_do_db_operation ( GncSqlBackend be,
E_DB_OPERATION  op,
const gchar *  table_name,
QofIdTypeConst  obj_name,
gpointer  pObject,
const GncSqlColumnTableEntry table 
)

Performs an operation on the database.

Parameters
beSQL backend struct
opOperation type
table_nameSQL table name
obj_nameQOF object type name
pObjectGnucash object
tableDB table description
Returns
TRUE if successful, FALSE if not

Definition at line 2698 of file gnc-backend-sql.c.

2703 {
2704  GncSqlStatement* stmt = NULL;
2705  gboolean ok = FALSE;
2706 
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 );
2712 
2713  if ( op == OP_DB_INSERT )
2714  {
2715  stmt = build_insert_statement( be, table_name, obj_name, pObject, table );
2716  }
2717  else if ( op == OP_DB_UPDATE )
2718  {
2719  stmt = build_update_statement( be, table_name, obj_name, pObject, table );
2720  }
2721  else if ( op == OP_DB_DELETE )
2722  {
2723  stmt = build_delete_statement( be, table_name, obj_name, pObject, table );
2724  }
2725  else
2726  {
2727  g_assert( FALSE );
2728  }
2729  if ( stmt != NULL )
2730  {
2731  gint result;
2732 
2733  result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
2734  if ( result == -1 )
2735  {
2736  PERR( "SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
2738  }
2739  else
2740  {
2741  ok = TRUE;
2742  }
2743  gnc_sql_statement_dispose( stmt );
2744  }
2745 
2746  return ok;
2747 }
void qof_backend_set_error(QofBackend *be, QofBackendError err)
GncSqlConnection * conn
QofBackend be
#define PERR(format, args...)
Definition: qoflog.h:237
gint gnc_sql_execute_nonselect_sql ( GncSqlBackend be,
const gchar *  sql 
)

Executes an SQL non-SELECT statement from an SQL char string.

Parameters
beSQL backend struct
sqlSQL non-SELECT string
Returns
Number of rows affected, or -1 if an error has occured

Definition at line 2591 of file gnc-backend-sql.c.

2592 {
2593  GncSqlStatement* stmt;
2594  gint result;
2595 
2596  g_return_val_if_fail( be != NULL, 0 );
2597  g_return_val_if_fail( sql != NULL, 0 );
2598 
2599  stmt = gnc_sql_create_statement_from_sql( be, sql );
2600  if ( stmt == NULL )
2601  {
2602  return -1;
2603  }
2604  result = gnc_sql_connection_execute_nonselect_statement( be->conn, stmt );
2605  gnc_sql_statement_dispose( stmt );
2606  return result;
2607 }
GncSqlConnection * conn
GncSqlStatement * gnc_sql_create_statement_from_sql(GncSqlBackend *be, const gchar *sql)
GncSqlResult* gnc_sql_execute_select_sql ( GncSqlBackend be,
const gchar *  sql 
)

Executes an SQL SELECT statement from an SQL char string and returns the result rows. If an error occurs, an entry is added to the log, an error status is returned to qof and NULL is returned.

Parameters
beSQL backend struct
sqlSQL SELECT string
Returns
Results, or NULL if an error has occured

Definition at line 2566 of file gnc-backend-sql.c.

2567 {
2568  GncSqlStatement* stmt;
2569  GncSqlResult* result = NULL;
2570 
2571  g_return_val_if_fail( be != NULL, NULL );
2572  g_return_val_if_fail( sql != NULL, NULL );
2573 
2574  stmt = gnc_sql_create_statement_from_sql( be, sql );
2575  if ( stmt == NULL )
2576  {
2577  return NULL;
2578  }
2579  result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
2580  gnc_sql_statement_dispose( stmt );
2581  if ( result == NULL )
2582  {
2583  PERR( "SQL error: %s\n", sql );
2585  }
2586 
2587  return result;
2588 }
void qof_backend_set_error(QofBackend *be, QofBackendError err)
GncSqlConnection * conn
QofBackend be
#define PERR(format, args...)
Definition: qoflog.h:237
GncSqlStatement * gnc_sql_create_statement_from_sql(GncSqlBackend *be, const gchar *sql)
GncSqlResult* gnc_sql_execute_select_statement ( GncSqlBackend be,
GncSqlStatement statement 
)

Executes an SQL SELECT statement and returns the result rows. If an error occurs, an entry is added to the log, an error status is returned to qof and NULL is returned.

Parameters
beSQL backend struct
statementStatement
Returns
Results, or NULL if an error has occured

Definition at line 2530 of file gnc-backend-sql.c.

2531 {
2532  GncSqlResult* result;
2533 
2534  g_return_val_if_fail( be != NULL, NULL );
2535  g_return_val_if_fail( stmt != NULL, NULL );
2536 
2537  result = gnc_sql_connection_execute_select_statement( be->conn, stmt );
2538  if ( result == NULL )
2539  {
2540  PERR( "SQL error: %s\n", gnc_sql_statement_to_sql( stmt ) );
2542  }
2543 
2544  return result;
2545 }
void qof_backend_set_error(QofBackend *be, QofBackendError err)
GncSqlConnection * conn
QofBackend be
#define PERR(format, args...)
Definition: qoflog.h:237
void gnc_sql_finalize_version_info ( GncSqlBackend be)

Finalizes DB table version information.

Parameters
beSQL backend struct

Finalizes the version table info by destroying the hash table.

Parameters
beBackend struct

Definition at line 3333 of file gnc-backend-sql.c.

3334 {
3335  g_return_if_fail( be != NULL );
3336 
3337  if ( be->versions != NULL )
3338  {
3339  g_hash_table_destroy( be->versions );
3340  be->versions = NULL;
3341  }
3342 }
GHashTable * versions
QofAccessFunc gnc_sql_get_getter ( QofIdTypeConst  obj_name,
const GncSqlColumnTableEntry table_row 
)

Returns the QOF access function for a column.

Parameters
obj_nameQOF object type name
table_rowDB table column
Returns
Access function

Definition at line 1140 of file gnc-backend-sql.c.

1141 {
1142  QofAccessFunc getter;
1143 
1144  g_return_val_if_fail( obj_name != NULL, NULL );
1145  g_return_val_if_fail( table_row != NULL, NULL );
1146 
1147  if ( (table_row->flags & COL_AUTOINC) != 0 )
1148  {
1149  getter = get_autoinc_id;
1150  }
1151  else if ( table_row->qof_param_name != NULL )
1152  {
1153  getter = qof_class_get_parameter_getter( obj_name,
1154  table_row->qof_param_name );
1155  }
1156  else
1157  {
1158  getter = table_row->getter;
1159  }
1160 
1161  return getter;
1162 }
const gchar * qof_param_name
#define COL_AUTOINC
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:177
QofAccessFunc qof_class_get_parameter_getter(QofIdTypeConst obj_name, const char *parameter)
gint64 gnc_sql_get_integer_value ( const GValue *  value)

Gets an integer value (of any size) from a GValue.

Parameters
valueSource value
Returns
Integer value

Definition at line 1085 of file gnc-backend-sql.c.

1086 {
1087  g_return_val_if_fail( value != NULL, 0 );
1088 
1089  if ( G_VALUE_HOLDS_INT(value) )
1090  {
1091  return (gint64)g_value_get_int( value );
1092  }
1093  else if ( G_VALUE_HOLDS_UINT(value) )
1094  {
1095  return (gint64)g_value_get_uint( value );
1096  }
1097  else if ( G_VALUE_HOLDS_LONG(value) )
1098  {
1099  return (gint64)g_value_get_long( value );
1100  }
1101  else if ( G_VALUE_HOLDS_ULONG(value) )
1102  {
1103  return (gint64)g_value_get_ulong( value );
1104  }
1105  else if ( G_VALUE_HOLDS_INT64(value) )
1106  {
1107  return g_value_get_int64( value );
1108  }
1109  else if ( G_VALUE_HOLDS_UINT64(value) )
1110  {
1111  return (gint64)g_value_get_uint64( value );
1112  }
1113  else if ( G_VALUE_HOLDS_STRING( value ) )
1114  {
1115  return g_ascii_strtoll( g_value_get_string( value ), NULL, 10 );
1116  }
1117  else
1118  {
1119  PWARN( "Unknown type: %s", G_VALUE_TYPE_NAME( value ) );
1120  }
1121 
1122  return 0;
1123 }
#define PWARN(format, args...)
Definition: qoflog.h:243
gchar* gnc_sql_get_sql_value ( const GncSqlConnection conn,
const GValue *  value 
)

Returns a string corresponding to the SQL representation of a GValue. The caller must free the string.

Parameters
connSQL connection
valueValue to be converted
Returns
String

Definition at line 2773 of file gnc-backend-sql.c.

2774 {
2775  if ( value != NULL && G_IS_VALUE( value ) )
2776  {
2777  GType type = G_VALUE_TYPE(value);
2778 
2779  if ( G_VALUE_HOLDS_STRING(value) )
2780  {
2781  if ( g_value_get_string( value ) != NULL )
2782  {
2783  gchar* before_str;
2784  gchar* after_str;
2785  before_str = g_value_dup_string( value );
2786  after_str = gnc_sql_connection_quote_string( conn, before_str );
2787  g_free( before_str );
2788  return after_str;
2789  }
2790  else
2791  {
2792  return g_strdup( "NULL" );
2793  }
2794  }
2795  else if ( type == G_TYPE_INT64 )
2796  {
2797  return g_strdup_printf( "%" G_GINT64_FORMAT, g_value_get_int64( value ) );
2798 
2799  }
2800  else if ( type == G_TYPE_INT )
2801  {
2802  return g_strdup_printf( "%d", g_value_get_int( value ) );
2803 
2804  }
2805  else if ( type == G_TYPE_DOUBLE )
2806  {
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 );
2811 
2812  }
2813  else if ( g_value_type_transformable( type, G_TYPE_STRING ) )
2814  {
2815  GValue* string;
2816  gchar* str;
2817 
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 );
2824  g_free( string );
2825  PWARN( "using g_value_transform(), gtype = '%s'\n", g_type_name( type ) );
2826  return str;
2827  }
2828  else
2829  {
2830  PWARN( "not transformable, gtype = '%s'\n", g_type_name( type ) );
2831  return g_strdup( "$$$" );
2832  }
2833  }
2834  else
2835  {
2836  PWARN( "value is NULL or not G_IS_VALUE()\n" );
2837  return g_strdup( "" );
2838  }
2839 }
#define PWARN(format, args...)
Definition: qoflog.h:243
gint gnc_sql_get_table_version ( const GncSqlBackend be,
const gchar *  table_name 
)

Returns the version number for a DB table.

Parameters
beSQL backend struct
table_nameTable name
Returns
Version number, or 0 if the table does not exist

Definition at line 3159 of file gnc-backend-sql.c.

3160 {
3161  g_return_val_if_fail( be != NULL, 0 );
3162  g_return_val_if_fail( table_name != NULL, 0 );
3163 
3164  /* If the db is pristine because it's being saved, the table does not exist. */
3165  if ( be->is_pristine_db )
3166  {
3167  return 0;
3168  }
3169 
3170  return GPOINTER_TO_INT(g_hash_table_lookup( be->versions, table_name ));
3171 }
GHashTable * versions
gboolean is_pristine_db
void gnc_sql_init ( GncSqlBackend be)

Initialize the SQL backend.

Parameters
beSQL backend

Definition at line 137 of file gnc-backend-sql.c.

138 {
139  static gboolean initialized = FALSE;
140 
141  if ( !initialized )
142  {
143  register_standard_col_type_handlers();
144  gnc_sql_init_object_handlers();
145  initialized = TRUE;
146  }
147 }
void gnc_sql_init_version_info ( GncSqlBackend be)

Initializes DB table version information.

Parameters
beSQL backend struct

Sees if the version table exists, and if it does, loads the info into the version hash table. Otherwise, it creates an empty version table.

Parameters
beBackend struct

Definition at line 3251 of file gnc-backend-sql.c.

3252 {
3253  g_return_if_fail( be != NULL );
3254 
3255  if ( be->versions != NULL )
3256  {
3257  g_hash_table_destroy( be->versions );
3258  }
3259  be->versions = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, NULL );
3260 
3261  if ( gnc_sql_connection_does_table_exist( be->conn, VERSION_TABLE_NAME ) )
3262  {
3263  GncSqlResult* result;
3264  gchar* sql;
3265 
3266  sql = g_strdup_printf( "SELECT * FROM %s", VERSION_TABLE_NAME );
3267  result = gnc_sql_execute_select_sql( be, sql );
3268  g_free( sql );
3269  if ( result != NULL )
3270  {
3271  const GValue* name;
3272  const GValue* version;
3273  GncSqlRow* row;
3274 
3275  row = gnc_sql_result_get_first_row( result );
3276  while ( row != NULL )
3277  {
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 );
3280  g_hash_table_insert( be->versions,
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 );
3284  }
3285  gnc_sql_result_dispose( result );
3286  }
3287  }
3288  else
3289  {
3290  do_create_table( be, VERSION_TABLE_NAME, version_table );
3291  gnc_sql_set_table_version( be, "Gnucash",
3292  gnc_prefs_get_long_version() );
3293  gnc_sql_set_table_version( be, "Gnucash-Resave",
3294  GNUCASH_RESAVE_VERSION );
3295  }
3296 }
GHashTable * versions
GncSqlConnection * conn
gboolean gnc_sql_set_table_version(GncSqlBackend *be, const gchar *table_name, gint version)
GncSqlResult * gnc_sql_execute_select_sql(GncSqlBackend *be, const gchar *sql)
void gnc_sql_load ( GncSqlBackend be,
QofBook book,
QofBackendLoadType  loadType 
)

Load the contents of an SQL database into a book.

Parameters
beSQL backend
bookBook to be loaded

Definition at line 228 of file gnc-backend-sql.c.

229 {
230  GncSqlObjectBackend* pData;
231  gint i;
232  Account* root;
233 
234  g_return_if_fail( be != NULL );
235  g_return_if_fail( book != NULL );
236 
237  ENTER( "be=%p, book=%p", be, book );
238 
239  be->loading = TRUE;
240 
241  if ( loadType == LOAD_TYPE_INITIAL_LOAD )
242  {
243  g_assert( be->book == NULL );
244  be->book = book;
245 
246  /* Load any initial stuff. Some of this needs to happen in a certain order */
247  for ( i = 0; fixed_load_order[i] != NULL; i++ )
248  {
249  pData = qof_object_lookup_backend( fixed_load_order[i], GNC_SQL_BACKEND );
250  if ( pData->initial_load != NULL )
251  {
252  update_progress( be );
253  (pData->initial_load)( be );
254  }
255  }
256  if ( other_load_order != NULL )
257  {
258  for ( i = 0; other_load_order[i] != NULL; i++ )
259  {
260  pData = qof_object_lookup_backend( other_load_order[i], GNC_SQL_BACKEND );
261  if ( pData->initial_load != NULL )
262  {
263  update_progress( be );
264  (pData->initial_load)( be );
265  }
266  }
267  }
268 
269  root = gnc_book_get_root_account( book );
270  gnc_account_foreach_descendant( root, (AccountCb)xaccAccountBeginEdit, NULL );
271 
272  qof_object_foreach_backend( GNC_SQL_BACKEND, initial_load_cb, be );
273 
274  gnc_account_foreach_descendant( root, (AccountCb)xaccAccountCommitEdit, NULL );
275  }
276  else if ( loadType == LOAD_TYPE_LOAD_ALL )
277  {
278  // Load all transactions
280  }
281 
282  be->loading = FALSE;
283  g_list_free_full (post_load_commodities, commit_commodity);
284  post_load_commodities = NULL;
285 
286  /* Mark the sessoion as clean -- though it should never be marked
287  * dirty with this backend
288  */
290  finish_progress( be );
291 
292  LEAVE( "" );
293 }
gboolean loading
void gnc_account_foreach_descendant(const Account *acc, AccountCb thunk, gpointer user_data)
Definition: Account.c:2958
#define ENTER(format, args...)
Definition: qoflog.h:261
QofBook * book
void(* initial_load)(GncSqlBackend *be)
void qof_book_mark_session_saved(QofBook *book)
void gnc_sql_transaction_load_all_tx(GncSqlBackend *be)
void xaccAccountBeginEdit(Account *acc)
Definition: Account.c:1280
#define LEAVE(format, args...)
Definition: qoflog.h:271
void xaccAccountCommitEdit(Account *acc)
Definition: Account.c:1321
const GncGUID* gnc_sql_load_guid ( const GncSqlBackend be,
GncSqlRow row 
)

Loads the object guid from a database row. The table must have a column named "guid" with type CT_GUID.

Parameters
beSQL backend struct
rowDatabase row
Returns
GncGUID

Definition at line 2422 of file gnc-backend-sql.c.

2423 {
2424  static GncGUID guid;
2425 
2426  g_return_val_if_fail( be != NULL, NULL );
2427  g_return_val_if_fail( row != NULL, NULL );
2428 
2429  gnc_sql_load_object( be, row, NULL, &guid, guid_table );
2430 
2431  return &guid;
2432 }
Definition: guid.h:65
void gnc_sql_load_object(const GncSqlBackend *be, GncSqlRow *row, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
void gnc_sql_load_object ( const GncSqlBackend be,
GncSqlRow row,
QofIdTypeConst  obj_name,
gpointer  pObject,
const GncSqlColumnTableEntry table 
)

Loads a Gnucash object from the database.

Parameters
beSQL backend struct
rowDB result row
obj_nameQOF object type name
pObjectObject to be loaded
tableDB table description

Definition at line 2458 of file gnc-backend-sql.c.

2461 {
2462  QofSetterFunc setter;
2463  GncSqlColumnTypeHandler* pHandler;
2464  const GncSqlColumnTableEntry* table_row;
2465 
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 );
2470 
2471  for ( table_row = table; table_row->col_name != NULL; table_row++ )
2472  {
2473  if ( (table_row->flags & COL_AUTOINC) != 0 )
2474  {
2475  setter = set_autoinc_id;
2476  }
2477  else if ( table_row->qof_param_name != NULL )
2478  {
2479  g_assert( obj_name != NULL );
2480  setter = qof_class_get_parameter_setter( obj_name,
2481  table_row->qof_param_name );
2482  }
2483  else
2484  {
2485  setter = table_row->setter;
2486  }
2487  pHandler = get_handler( table_row );
2488  g_assert( pHandler != NULL );
2489  pHandler->load_fn( be, row, setter, pObject, table_row );
2490  }
2491 }
const gchar * qof_param_name
#define COL_AUTOINC
void(* QofSetterFunc)(gpointer, gpointer)
Definition: qofclass.h:184
QofSetterFunc qof_class_get_parameter_setter(QofIdTypeConst obj_name, const char *parameter)
const GncGUID* gnc_sql_load_tx_guid ( const GncSqlBackend be,
GncSqlRow row 
)

Loads the transaction guid from a database row. The table must have a column named "tx_guid" with type CT_GUID.

Parameters
beSQL backend struct
rowDatabase row
Returns
GncGUID

Definition at line 2445 of file gnc-backend-sql.c.

2446 {
2447  static GncGUID guid;
2448 
2449  g_return_val_if_fail( be != NULL, NULL );
2450  g_return_val_if_fail( row != NULL, NULL );
2451 
2452  gnc_sql_load_object( be, row, NULL, &guid, tx_guid_table );
2453 
2454  return &guid;
2455 }
Definition: guid.h:65
void gnc_sql_load_object(const GncSqlBackend *be, GncSqlRow *row, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
gboolean gnc_sql_object_is_it_in_db ( GncSqlBackend be,
const gchar *  table_name,
QofIdTypeConst  obj_name,
const gpointer  pObject,
const GncSqlColumnTableEntry table 
)

Checks whether an object is in the database or not.

Parameters
beSQL backend struct
table_nameDB table name
obj_nameQOF object type name
pObjectObject to be checked
tableDB table description
Returns
TRUE if the object is in the database, FALSE otherwise

Definition at line 2659 of file gnc-backend-sql.c.

2662 {
2663  GncSqlStatement* sqlStmt;
2664  guint count;
2665  GncSqlColumnTypeHandler* pHandler;
2666  GSList* list = NULL;
2667 
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 );
2673 
2674  /* SELECT * FROM */
2675  sqlStmt = create_single_col_select_statement( be, table_name, table );
2676  g_assert( sqlStmt != NULL );
2677 
2678  /* WHERE */
2679  pHandler = get_handler( table );
2680  g_assert( pHandler != NULL );
2681  pHandler->add_gvalue_to_slist_fn( be, obj_name, pObject, table, &list );
2682  g_assert( list != NULL );
2683  gnc_sql_statement_add_where_cond( sqlStmt, obj_name, pObject, &table[0], (GValue*)(list->data) );
2684 
2685  count = execute_statement_get_count( be, sqlStmt );
2686  gnc_sql_statement_dispose( sqlStmt );
2687  if ( count == 0 )
2688  {
2689  return FALSE;
2690  }
2691  else
2692  {
2693  return TRUE;
2694  }
2695 }
GNC_SQL_ADD_GVALUE_TO_SLIST_FN add_gvalue_to_slist_fn
void gnc_sql_push_commodity_for_postload_processing ( GncSqlBackend be,
gpointer *  comm 
)

Register a commodity to be committed after loading is complete.

Necessary to save corrections made while loading.

Parameters
beSQL backend
commThe commodity item to be committed.

Definition at line 214 of file gnc-backend-sql.c.

216 {
217  post_load_commodities = g_list_prepend(post_load_commodities, comm);
218 }
void gnc_sql_register_col_type_handler ( const gchar *  colType,
const GncSqlColumnTypeHandler handler 
)

Registers a column handler for a new column type.

Parameters
colTypeColumn type
handlerColumn handler

Definition at line 2348 of file gnc-backend-sql.c.

2349 {
2350  g_return_if_fail( colType != NULL );
2351  g_return_if_fail( handler != NULL );
2352 
2353  if ( g_columnTypeHash == NULL )
2354  {
2355  g_columnTypeHash = g_hash_table_new( g_str_hash, g_str_equal );
2356  g_assert( g_columnTypeHash != NULL );
2357  }
2358 
2359  DEBUG( "Col type %s registered\n", colType );
2360  g_hash_table_insert( g_columnTypeHash, (gpointer)colType, (gpointer)handler );
2361 }
#define DEBUG(format, args...)
Definition: qoflog.h:255
void gnc_sql_rollback_edit ( GncSqlBackend qbe,
QofInstance inst 
)

Object editing has been cancelled.

Parameters
qbeSQL backend
instObject being edited

Definition at line 536 of file gnc-backend-sql.c.

537 {
538  g_return_if_fail( be != NULL );
539  g_return_if_fail( inst != NULL );
540 
541  ENTER( " " );
542  LEAVE( "" );
543 }
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
void gnc_sql_set_load_order ( const gchar **  load_order)

Specifies the load order for a set of objects. When loading from a database, the objects will be loaded in this order, so that when later objects have references to objects, those objects will already have been loaded.

Parameters
load_orderNULL-terminated array of object type ID strings

Definition at line 177 of file gnc-backend-sql.c.

178 {
179  other_load_order = load_order;
180 }
gboolean gnc_sql_set_table_version ( GncSqlBackend be,
const gchar *  table_name,
gint  version 
)

Registers the version for a table. Registering involves updating the db version table and also the hash table.

Parameters
beBackend struct
table_nameTable name
versionVersion number
Returns
TRUE if successful, FALSE if unsuccessful

Definition at line 3354 of file gnc-backend-sql.c.

3355 {
3356  gchar* sql;
3357  gint cur_version;
3358  gint status;
3359 
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 );
3363 
3364  cur_version = gnc_sql_get_table_version( be, table_name );
3365  if ( cur_version != version )
3366  {
3367  if ( cur_version == 0 )
3368  {
3369  sql = g_strdup_printf( "INSERT INTO %s VALUES('%s',%d)", VERSION_TABLE_NAME,
3370  table_name, version );
3371  }
3372  else
3373  {
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 );
3377  }
3378  status = gnc_sql_execute_nonselect_sql( be, sql );
3379  if ( status == -1 )
3380  {
3381  PERR( "SQL error: %s\n", sql );
3383  }
3384  g_free( sql );
3385  }
3386 
3387  g_hash_table_insert( be->versions, g_strdup( table_name ), GINT_TO_POINTER(version) );
3388 
3389  return TRUE;
3390 }
void qof_backend_set_error(QofBackend *be, QofBackendError err)
gint gnc_sql_get_table_version(const GncSqlBackend *be, const gchar *table_name)
GHashTable * versions
gint gnc_sql_execute_nonselect_sql(GncSqlBackend *be, const gchar *sql)
QofBackend be
#define PERR(format, args...)
Definition: qoflog.h:237
void gnc_sql_sync_all ( GncSqlBackend be,
QofBook book 
)

Save the contents of a book to an SQL database.

Parameters
beSQL backend
bookBook to be saved

Definition at line 450 of file gnc-backend-sql.c.

451 {
452  gboolean is_ok;
453 
454  g_return_if_fail( be != NULL );
455  g_return_if_fail( book != NULL );
456 
457  ENTER( "book=%p, be->book=%p", book, be->book );
458  update_progress( be );
459  (void)reset_version_info( be );
460 
461  /* Create new tables */
462  be->is_pristine_db = TRUE;
463  qof_object_foreach_backend( GNC_SQL_BACKEND, create_tables_cb, be );
464 
465  /* Save all contents */
466  be->book = book;
467  be->obj_total = 0;
468  be->obj_total += 1 + gnc_account_n_descendants( gnc_book_get_root_account( book ) );
469  be->obj_total += gnc_book_count_transactions( book );
470  be->operations_done = 0;
471 
472  is_ok = gnc_sql_connection_begin_transaction( be->conn );
473 
474  // FIXME: should write the set of commodities that are used
475  //write_commodities( be, book );
476  if ( is_ok )
477  {
478  is_ok = gnc_sql_save_book( be, QOF_INSTANCE(book) );
479  }
480  if ( is_ok )
481  {
482  is_ok = write_accounts( be );
483  }
484  if ( is_ok )
485  {
486  is_ok = write_transactions( be );
487  }
488  if ( is_ok )
489  {
490  is_ok = write_template_transactions( be );
491  }
492  if ( is_ok )
493  {
494  is_ok = write_schedXactions( be );
495  }
496  if ( is_ok )
497  {
498  qof_object_foreach_backend( GNC_SQL_BACKEND, write_cb, be );
499  }
500  if ( is_ok )
501  {
502  is_ok = gnc_sql_connection_commit_transaction( be->conn );
503  }
504  if ( is_ok )
505  {
506  be->is_pristine_db = FALSE;
507 
508  /* Mark the session as clean -- though it shouldn't ever get
509  * marked dirty with this backend
510  */
512  }
513  else
514  {
516  is_ok = gnc_sql_connection_rollback_transaction( be->conn );
517  }
518  finish_progress( be );
519  LEAVE( "book=%p", book );
520 }
void qof_backend_set_error(QofBackend *be, QofBackendError err)
gint gnc_account_n_descendants(const Account *account)
Definition: Account.c:2698
GncSqlConnection * conn
#define ENTER(format, args...)
Definition: qoflog.h:261
QofBook * book
void qof_book_mark_session_saved(QofBook *book)
guint gnc_book_count_transactions(QofBook *book)
Definition: Transaction.c:2483
#define LEAVE(format, args...)
Definition: qoflog.h:271
gboolean is_pristine_db
void gnc_sql_upgrade_table ( GncSqlBackend be,
const gchar *  table_name,
const GncSqlColumnTableEntry col_table 
)

Upgrades a table to a new structure. The upgrade is done by creating a new table with the new structure, SELECTing the old data into the new table, deleting the old table, then renaming the new table. Therefore, this will only work if the new table structure is similar enough to the old table that the SELECT will work.

Parameters
beSQL backend
table_nameSQL table name
col_tableColumn table

Definition at line 3176 of file gnc-backend-sql.c.

3178 {
3179  gchar* sql;
3180  gchar* temp_table_name;
3181 
3182  g_return_if_fail( be != NULL );
3183  g_return_if_fail( table_name != NULL );
3184  g_return_if_fail( col_table != NULL );
3185 
3186  DEBUG( "Upgrading %s table\n", table_name );
3187 
3188  temp_table_name = g_strdup_printf( "%s_new", table_name );
3189  (void)gnc_sql_create_temp_table( be, temp_table_name, col_table );
3190  sql = g_strdup_printf( "INSERT INTO %s SELECT * FROM %s",
3191  temp_table_name, table_name );
3192  (void)gnc_sql_execute_nonselect_sql( be, sql );
3193  g_free( sql );
3194 
3195  sql = g_strdup_printf( "DROP TABLE %s", table_name );
3196  (void)gnc_sql_execute_nonselect_sql( be, sql );
3197  g_free( sql );
3198 
3199  sql = g_strdup_printf( "ALTER TABLE %s RENAME TO %s", temp_table_name, table_name );
3200  (void)gnc_sql_execute_nonselect_sql( be, sql );
3201  g_free( sql );
3202  g_free( temp_table_name );
3203 }
#define DEBUG(format, args...)
Definition: qoflog.h:255
gint gnc_sql_execute_nonselect_sql(GncSqlBackend *be, const gchar *sql)
gboolean gnc_sql_create_temp_table(const GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *col_table)