GnuCash 2.4.99
gnc-entry-sql.c
Go to the documentation of this file.
00001 /********************************************************************\
00002  * gnc-entry-sql.c -- entry sql backend                             *
00003  *                                                                  *
00004  * This program is free software; you can redistribute it and/or    *
00005  * modify it under the terms of the GNU General Public License as   *
00006  * published by the Free Software Foundation; either version 2 of   *
00007  * the License, or (at your option) any later version.              *
00008  *                                                                  *
00009  * This program is distributed in the hope that it will be useful,  *
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00012  * GNU General Public License for more details.                     *
00013  *                                                                  *
00014  * You should have received a copy of the GNU General Public License*
00015  * along with this program; if not, contact:                        *
00016  *                                                                  *
00017  * Free Software Foundation           Voice:  +1-617-542-5942       *
00018  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00019  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00020  *                                                                  *
00021 \********************************************************************/
00022 
00031 #include "config.h"
00032 
00033 #include <glib.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 
00037 #include "gnc-backend-sql.h"
00038 #include "gnc-slots-sql.h"
00039 
00040 #include "gncEntryP.h"
00041 #include "gncOrderP.h"
00042 #include "gncInvoiceP.h"
00043 #include "gncTaxTableP.h"
00044 #include "gnc-bill-term-sql.h"
00045 #include "gnc-entry-sql.h"
00046 #include "gnc-invoice-sql.h"
00047 #include "gnc-order-sql.h"
00048 #include "gnc-owner-sql.h"
00049 #include "gnc-tax-table-sql.h"
00050 
00051 #define _GNC_MOD_NAME   GNC_ID_ENTRY
00052 
00053 static QofLogModule log_module = G_LOG_DOMAIN;
00054 
00055 #define TABLE_NAME "entries"
00056 #define TABLE_VERSION 3
00057 #define MAX_DESCRIPTION_LEN 2048
00058 #define MAX_ACTION_LEN 2048
00059 #define MAX_NOTES_LEN 2048
00060 #define MAX_DISCTYPE_LEN 2048
00061 #define MAX_DISCHOW_LEN 2048
00062 
00063 static void entry_set_invoice( gpointer pObject, gpointer val );
00064 static void entry_set_bill( gpointer pObject, gpointer val );
00065 
00066 static GncSqlColumnTableEntry col_table[] =
00067 {
00068     { "guid",          CT_GUID,        0,                   COL_NNUL | COL_PKEY, "guid" },
00069     { "date",          CT_TIMESPEC,    0,                   COL_NNUL,          NULL, ENTRY_DATE },
00070     { "date_entered",  CT_TIMESPEC,    0,                   0,                 NULL, ENTRY_DATE_ENTERED },
00071     { "description",   CT_STRING,      MAX_DESCRIPTION_LEN, 0,                 "description" },
00072     { "action",        CT_STRING,      MAX_ACTION_LEN,      0,                 NULL, ENTRY_ACTION },
00073     { "notes",         CT_STRING,      MAX_NOTES_LEN,       0,                 NULL, ENTRY_NOTES },
00074     { "quantity",      CT_NUMERIC,     0,                   0,                 NULL, ENTRY_QTY },
00075     { "i_acct",        CT_ACCOUNTREF,  0,                   0,                 NULL, ENTRY_IACCT },
00076     { "i_price",       CT_NUMERIC,     0,                   0,                 NULL, ENTRY_IPRICE },
00077     {
00078         "i_discount",    CT_NUMERIC,     0,                   0,                 NULL, NULL,
00079         (QofAccessFunc)gncEntryGetInvDiscount, (QofSetterFunc)gncEntrySetInvDiscount
00080     },
00081     {
00082         "invoice",       CT_INVOICEREF,  0,                   0,                 NULL, NULL,
00083         (QofAccessFunc)gncEntryGetInvoice, (QofSetterFunc)entry_set_invoice
00084     },
00085     { "i_disc_type",   CT_STRING,      MAX_DISCTYPE_LEN,    0,                          NULL, ENTRY_INV_DISC_TYPE },
00086     { "i_disc_how",    CT_STRING,      MAX_DISCHOW_LEN,     0,                          NULL, ENTRY_INV_DISC_HOW },
00087     { "i_taxable",     CT_BOOLEAN,     0,                   0,                          NULL, ENTRY_INV_TAXABLE },
00088     { "i_taxincluded", CT_BOOLEAN,     0,                   0,                          NULL, ENTRY_INV_TAX_INC },
00089     {
00090         "i_taxtable",    CT_TAXTABLEREF, 0,                   0,                                NULL, NULL,
00091         (QofAccessFunc)gncEntryGetInvTaxTable, (QofSetterFunc)gncEntrySetInvTaxTable
00092     },
00093     { "b_acct",        CT_ACCOUNTREF,  0,                   0,                          NULL, ENTRY_BACCT },
00094     { "b_price",       CT_NUMERIC,     0,                   0,                          NULL, ENTRY_BPRICE },
00095     {
00096         "bill",          CT_INVOICEREF,  0,                   0,                                NULL, NULL,
00097         (QofAccessFunc)gncEntryGetBill, (QofSetterFunc)entry_set_bill
00098     },
00099     { "b_taxable",     CT_BOOLEAN,     0,                   0,                          NULL, ENTRY_BILL_TAXABLE },
00100     { "b_taxincluded", CT_BOOLEAN,     0,                   0,                          NULL, ENTRY_BILL_TAX_INC },
00101     {
00102         "b_taxtable",    CT_TAXTABLEREF, 0,                   0,                                NULL, NULL,
00103         (QofAccessFunc)gncEntryGetBillTaxTable, (QofSetterFunc)gncEntrySetBillTaxTable
00104     },
00105     {
00106         "b_paytype",     CT_INT,         0,                   0,                                NULL, NULL,
00107         (QofAccessFunc)gncEntryGetBillPayment, (QofSetterFunc)gncEntrySetBillPayment
00108     },
00109     { "billable",      CT_BOOLEAN,     0,                   0,                          NULL, ENTRY_BILLABLE },
00110     { "billto",        CT_OWNERREF,    0,                   0,                          NULL, ENTRY_BILLTO },
00111     {
00112         "order_guid",    CT_ORDERREF,    0,                   0,                                NULL, NULL,
00113         (QofAccessFunc)gncEntryGetOrder, (QofSetterFunc)gncEntrySetOrder
00114     },
00115     { NULL }
00116 };
00117 
00118 static void
00119 entry_set_invoice( gpointer pObject, gpointer val )
00120 {
00121     GncEntry* entry;
00122     GncInvoice* invoice;
00123 
00124     g_return_if_fail( pObject != NULL );
00125     g_return_if_fail( GNC_IS_ENTRY(pObject) );
00126     g_return_if_fail( val != NULL );
00127     g_return_if_fail( GNC_IS_INVOICE(val) );
00128 
00129     entry = GNC_ENTRY(pObject);
00130     invoice = GNC_INVOICE(val);
00131 
00132     gncInvoiceAddEntry( invoice, entry );
00133 }
00134 
00135 static void
00136 entry_set_bill( gpointer pObject, gpointer val )
00137 {
00138     GncEntry* entry;
00139     GncInvoice* bill;
00140 
00141     g_return_if_fail( pObject != NULL );
00142     g_return_if_fail( GNC_IS_ENTRY(pObject) );
00143     g_return_if_fail( val != NULL );
00144     g_return_if_fail( GNC_IS_INVOICE(val) );
00145 
00146     entry = GNC_ENTRY(pObject);
00147     bill = GNC_INVOICE(val);
00148 
00149     gncBillAddEntry( bill, entry );
00150 }
00151 
00152 static GncEntry*
00153 load_single_entry( GncSqlBackend* be, GncSqlRow* row )
00154 {
00155     const GncGUID* guid;
00156     GncEntry* pEntry;
00157 
00158     g_return_val_if_fail( be != NULL, NULL );
00159     g_return_val_if_fail( row != NULL, NULL );
00160 
00161     guid = gnc_sql_load_guid( be, row );
00162     pEntry = gncEntryLookup( be->book, guid );
00163     if ( pEntry == NULL )
00164     {
00165         pEntry = gncEntryCreate( be->book );
00166     }
00167     gnc_sql_load_object( be, row, GNC_ID_ENTRY, pEntry, col_table );
00168     qof_instance_mark_clean( QOF_INSTANCE(pEntry) );
00169 
00170     return pEntry;
00171 }
00172 
00173 static void
00174 load_all_entries( GncSqlBackend* be )
00175 {
00176     GncSqlStatement* stmt;
00177     GncSqlResult* result;
00178     QofBook* pBook;
00179 
00180     g_return_if_fail( be != NULL );
00181 
00182     pBook = be->book;
00183 
00184     stmt = gnc_sql_create_select_statement( be, TABLE_NAME );
00185     result = gnc_sql_execute_select_statement( be, stmt );
00186     gnc_sql_statement_dispose( stmt );
00187     if ( result != NULL )
00188     {
00189         GncSqlRow* row;
00190         GList* list = NULL;
00191 
00192         row = gnc_sql_result_get_first_row( result );
00193         while ( row != NULL )
00194         {
00195             GncEntry* pEntry = load_single_entry( be, row );
00196             if ( pEntry != NULL )
00197             {
00198                 list = g_list_append( list, pEntry );
00199             }
00200             row = gnc_sql_result_get_next_row( result );
00201         }
00202         gnc_sql_result_dispose( result );
00203 
00204         if ( list != NULL )
00205         {
00206             gnc_sql_slots_load_for_list( be, list );
00207             g_list_free( list );
00208         }
00209     }
00210 }
00211 
00212 /* ================================================================= */
00213 static void
00214 create_entry_tables( GncSqlBackend* be )
00215 {
00216     gint version;
00217 
00218     g_return_if_fail( be != NULL );
00219 
00220     version = gnc_sql_get_table_version( be, TABLE_NAME );
00221     if ( version == 0 )
00222     {
00223         gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
00224     }
00225     else if ( version < TABLE_VERSION )
00226     {
00227         /* Upgrade:
00228             1->2: 64 bit int handling
00229                 2->3: "entered" -> "date_entered", and it can be NULL
00230         */
00231         gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
00232         gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
00233 
00234         PINFO("Entries table upgraded from version %d to version %d\n", version, TABLE_VERSION);
00235     }
00236 }
00237 
00238 /* ================================================================= */
00239 static gboolean
00240 save_entry( GncSqlBackend* be, QofInstance* inst )
00241 {
00242     g_return_val_if_fail( inst != NULL, FALSE );
00243     g_return_val_if_fail( GNC_IS_ENTRY(inst), FALSE );
00244     g_return_val_if_fail( be != NULL, FALSE );
00245 
00246     return gnc_sql_commit_standard_item( be, inst, TABLE_NAME, GNC_ID_ENTRY, col_table );
00247 }
00248 
00249 /* ================================================================= */
00250 static void
00251 write_single_entry( QofInstance *term_p, gpointer data_p )
00252 {
00253     write_objects_t* s = (write_objects_t*)data_p;
00254     GncEntry* entry = GNC_ENTRY(term_p);
00255 
00256     g_return_if_fail( term_p != NULL );
00257     g_return_if_fail( GNC_IS_ENTRY(term_p) );
00258     g_return_if_fail( data_p != NULL );
00259 
00260     /* Only save if attached */
00261     if ( s->is_ok && (gncEntryGetOrder( entry ) != NULL || gncEntryGetInvoice( entry ) != NULL ||
00262                       gncEntryGetBill( entry ) != NULL) )
00263     {
00264         s->is_ok = save_entry( s->be, term_p );
00265     }
00266 }
00267 
00268 static gboolean
00269 write_entries( GncSqlBackend* be )
00270 {
00271     write_objects_t data;
00272 
00273     g_return_val_if_fail( be != NULL, FALSE );
00274 
00275     data.be = be;
00276     data.is_ok = TRUE;
00277     qof_object_foreach( GNC_ID_ENTRY, be->book, write_single_entry, &data );
00278 
00279     return data.is_ok;
00280 }
00281 
00282 /* ================================================================= */
00283 void
00284 gnc_entry_sql_initialize( void )
00285 {
00286     static GncSqlObjectBackend be_data =
00287     {
00288         GNC_SQL_BACKEND_VERSION,
00289         GNC_ID_ENTRY,
00290         save_entry,                                                     /* commit */
00291         load_all_entries,                                       /* initial_load */
00292         create_entry_tables,                            /* create_tables */
00293         NULL, NULL, NULL,
00294         write_entries                                           /* write */
00295     };
00296 
00297     qof_object_register_backend( GNC_ID_ENTRY, GNC_SQL_BACKEND, &be_data );
00298 }
00299 /* ========================== END OF FILE ===================== */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines