Price Database
[GnuCash Engine: Core, Non-GUI Accounting Functions]


Detailed Description

The PriceDB is intended to be a database of price quotes, or more specifically, a database of GNCPrices. For the time being, it is still a fairly simple database supporting only fairly simple queries. It is expected that new queries will be added as needed, and that there is some advantage to delaying complex queries for now in the hope that we get a real DB implementation before they're really needed.

Every QofBook contains a GNCPriceDB, accessable via gnc_book_get_pricedb.

Warning:
The PriceDB does not currently use the object system used elsewhere in the GnuCash Engine, i.e. it does not use GUISD's, Entities and Collections. Its should. In particular, this means that currently prices cannot be queried with the same emchanism as everything else.
Whenever a you store a price in the pricedb, the pricedb adds its own reference to the price, so you can safely unref that price after inserting it into the DB if you're finished with it otherwise.

Similarly, when the pricedb returns a price to you, either singly, or in a price list, the price will have had a ref added for you, so you only need to unref the price(s) when you're finished with it/them.


Files

file  gnc-pricedb.h
 a simple price database for gnucash

Price Parameter Names

For use with QofQuery

#define PRICE_COMMODITY   "price-commodity"
#define PRICE_CURRENCY   "price-currency"
#define PRICE_DATE   "price-date"
#define PRICE_SOURCE   "price-source"
#define PRICE_TYPE   "price-type"
#define PRICE_VALUE   "price-value"

Defines

#define gnc_book_get_pricedb   gnc_pricedb_get_db
#define gnc_pricedb_dirty(db)   qof_instance_is_dirty(QOF_INSTANCE(db))

Typedefs

typedef gnc_price_db_s GNCPriceDB

Functions

GNCPriceDBgnc_pricedb_create (QofBook *book)
GNCPriceDBgnc_pricedb_get_db (QofBook *book)
GNCPriceDBgnc_collection_get_pricedb (QofCollection *col)
void gnc_pricedb_destroy (GNCPriceDB *db)
void gnc_pricedb_begin_edit (GNCPriceDB *)
void gnc_pricedb_commit_edit (GNCPriceDB *)
gboolean gnc_pricedb_add_price (GNCPriceDB *db, GNCPrice *p)
gboolean gnc_pricedb_remove_price (GNCPriceDB *db, GNCPrice *p)
gboolean gnc_pricedb_remove_old_prices (GNCPriceDB *db, Timespec cutoff)
GNCPricegnc_pricedb_lookup_latest (GNCPriceDB *db, gnc_commodity *commodity, gnc_commodity *currency)
GList * gnc_pricedb_lookup_latest_any_currency (GNCPriceDB *db, gnc_commodity *commodity)
gboolean gnc_pricedb_has_prices (GNCPriceDB *db, gnc_commodity *commodity, gnc_commodity *currency)
GList * gnc_pricedb_get_prices (GNCPriceDB *db, gnc_commodity *commodity, gnc_commodity *currency)
GList * gnc_pricedb_lookup_at_time (GNCPriceDB *db, gnc_commodity *commodity, gnc_commodity *currency, Timespec t)
GList * gnc_pricedb_lookup_at_time_any_currency (GNCPriceDB *db, gnc_commodity *c, Timespec t)
GList * gnc_pricedb_lookup_day (GNCPriceDB *db, gnc_commodity *commodity, gnc_commodity *currency, Timespec t)
GList * gnc_pricedb_lookup_day_any_currency (GNCPriceDB *db, gnc_commodity *c, Timespec t)
GNCPricegnc_pricedb_lookup_nearest_in_time (GNCPriceDB *db, gnc_commodity *c, gnc_commodity *currency, Timespec t)
GList * gnc_pricedb_lookup_nearest_in_time_any_currency (GNCPriceDB *db, gnc_commodity *c, Timespec t)
gnc_numeric gnc_pricedb_convert_balance_latest_price (GNCPriceDB *pdb, gnc_numeric balance, gnc_commodity *balance_currency, gnc_commodity *new_currency)
gnc_numeric gnc_pricedb_convert_balance_nearest_price (GNCPriceDB *pdb, gnc_numeric balance, gnc_commodity *balance_currency, gnc_commodity *new_currency, Timespec t)
gboolean gnc_pricedb_foreach_price (GNCPriceDB *db, gboolean(*f)(GNCPrice *p, gpointer user_data), gpointer user_data, gboolean stable_order)
guint gnc_pricedb_get_num_prices (GNCPriceDB *db)
gboolean gnc_pricedb_equal (GNCPriceDB *db1, GNCPriceDB *db2)
void gnc_price_print (GNCPrice *db, FILE *f, int indent)
void gnc_pricedb_print_contents (GNCPriceDB *db, FILE *f)


Define Documentation

#define gnc_pricedb_dirty db   )     qof_instance_is_dirty(QOF_INSTANCE(db))
 

gnc_pricedb_dirty - return FALSE if the database has not been modified.

Definition at line 386 of file gnc-pricedb.h.


Typedef Documentation

typedef struct gnc_price_db_s GNCPriceDB
 

Data type

Definition at line 252 of file gnc-pricedb.h.


Function Documentation

void gnc_price_print GNCPrice db,
FILE *  f,
int  indent
 

semi-lame debugging code

Definition at line 1925 of file gnc-pricedb.c.

01926 {
01927   gnc_commodity *commodity;
01928   gnc_commodity *currency;
01929   gchar *istr = NULL;           /* indent string */
01930   const char *str;
01931 
01932   if(!p) return;
01933   if(!f) return;
01934 
01935   commodity = gnc_price_get_commodity(p);
01936   currency = gnc_price_get_currency(p);
01937 
01938   if(!commodity) return;
01939   if(!currency) return;
01940 
01941   istr = g_strnfill(indent, ' ');
01942 
01943   fprintf(f, "%s<pdb:price>\n", istr);
01944   fprintf(f, "%s  <pdb:commodity pointer=%p>\n", istr, commodity);
01945   str = gnc_commodity_get_namespace(commodity);
01946   str = str ? str : "(null)";
01947   fprintf(f, "%s    <cmdty:ref-space>%s</gnc:cmdty:ref-space>\n", istr, str);
01948   str = gnc_commodity_get_mnemonic(commodity);
01949   str = str ? str : "(null)";
01950   fprintf(f, "%s    <cmdty:ref-id>%s</cmdty:ref-id>\n", istr, str);
01951   fprintf(f, "%s  </pdb:commodity>\n", istr);
01952   fprintf(f, "%s  <pdb:currency pointer=%p>\n", istr, currency);
01953   str = gnc_commodity_get_namespace(currency);
01954   str = str ? str : "(null)";
01955   fprintf(f, "%s    <cmdty:ref-space>%s</gnc:cmdty:ref-space>\n", istr, str);
01956   str = gnc_commodity_get_mnemonic(currency);
01957   str = str ? str : "(null)";
01958   fprintf(f, "%s    <cmdty:ref-id>%s</cmdty:ref-id>\n", istr, str);
01959   fprintf(f, "%s  </pdb:currency>\n", istr);
01960   str = gnc_price_get_source(p);
01961   str = str ? str : "(null)";
01962   fprintf(f, "%s  %s\n", istr, str);
01963   str = gnc_price_get_type(p);
01964   str = str ? str : "(null)";
01965   fprintf(f, "%s  %s\n", istr, str);
01966   fprintf(f, "%s  %g\n", istr, gnc_numeric_to_double(gnc_price_get_value(p)));
01967   fprintf(f, "%s</pdb:price>\n", istr);
01968 
01969   g_free(istr);
01970 }

gboolean gnc_pricedb_add_price GNCPriceDB db,
GNCPrice p
 

gnc_pricedb_add_price - add a price to the pricedb, you may drop your reference to the price (i.e. call unref) after this succeeds, whenever you're finished with the price.

Definition at line 845 of file gnc-pricedb.c.

00846 {
00847   if(!db || !p) return FALSE;
00848 
00849   ENTER ("db=%p, pr=%p dirty=%d do-free=%d",
00850          db, p, p->inst.dirty, p->inst.do_free);
00851 
00852   if (FALSE == add_price(db, p)) return FALSE;
00853 
00854   /* If we haven't been able to call the backend before, call it now */
00855   if (TRUE == p->inst.dirty)
00856   {
00857     gnc_price_begin_edit(p);
00858     db->inst.dirty = TRUE;
00859     gnc_price_commit_edit(p);
00860   }
00861 
00862   LEAVE ("db=%p, pr=%p dirty=%d do-free=%d",
00863          db, p, p->inst.dirty, p->inst.do_free);
00864 
00865   return TRUE;
00866 }

void gnc_pricedb_begin_edit GNCPriceDB  ) 
 

Used for editing the pricedb en-mass

Definition at line 180 of file gnc-pricedb.c.

00181 {
00182   QOF_BEGIN_EDIT (&pdb->inst);
00183 }

gnc_numeric gnc_pricedb_convert_balance_latest_price GNCPriceDB pdb,
gnc_numeric  balance,
gnc_commodity balance_currency,
gnc_commodity new_currency
 

gnc_pricedb_convert_balance_latest_price - Convert a balance from one currency to another.

Definition at line 1574 of file gnc-pricedb.c.

01578 {
01579   GNCPrice *price, *currency_price;
01580   GList *price_list, *list_helper;
01581   gnc_numeric currency_price_value;
01582   gnc_commodity *intermediate_currency;
01583 
01584   if (gnc_numeric_zero_p (balance) ||
01585       gnc_commodity_equiv (balance_currency, new_currency))
01586     return balance;
01587 
01588   /* Look for a direct price. */
01589   price = gnc_pricedb_lookup_latest (pdb, balance_currency, new_currency);
01590   if (price) {
01591     balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
01592                                gnc_commodity_get_fraction (new_currency),
01593                                GNC_HOW_RND_ROUND);
01594     gnc_price_unref (price);
01595     return balance;
01596   }
01597 
01598   /*
01599    * no direct price found, try if we find a price in another currency
01600    * and convert in two stages
01601    */
01602   price_list = gnc_pricedb_lookup_latest_any_currency(pdb, balance_currency);
01603   if (!price_list) {
01604     balance =  gnc_numeric_zero ();
01605     return balance;
01606   }
01607 
01608   list_helper = price_list;
01609   currency_price_value = gnc_numeric_zero();
01610 
01611   do {
01612     price = (GNCPrice *)(list_helper->data);
01613 
01614     intermediate_currency = gnc_price_get_currency(price);
01615     currency_price = gnc_pricedb_lookup_latest(pdb, intermediate_currency,
01616                                                new_currency);
01617     if(currency_price) {
01618       currency_price_value = gnc_price_get_value(currency_price);
01619       gnc_price_unref(currency_price);
01620     } else {
01621       currency_price = gnc_pricedb_lookup_latest(pdb, new_currency,
01622                                                  intermediate_currency);
01623       if (currency_price) {
01624         /* here we need the reciprocal */
01625         currency_price_value = gnc_numeric_div(gnc_numeric_create(1, 1),
01626                               gnc_price_get_value(currency_price),
01627                               GNC_DENOM_AUTO,
01628                               GNC_HOW_DENOM_EXACT | GNC_HOW_RND_NEVER);
01629         gnc_price_unref(currency_price);
01630       }
01631     }
01632 
01633     list_helper = list_helper->next;
01634   } while((list_helper != NULL) &&
01635           (!gnc_numeric_zero_p(currency_price_value)));
01636 
01637   balance = gnc_numeric_mul (balance, currency_price_value,
01638                              gnc_commodity_get_fraction (new_currency),
01639                              GNC_HOW_RND_ROUND);
01640   balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
01641                              gnc_commodity_get_fraction (new_currency),
01642                              GNC_HOW_RND_ROUND);
01643 
01644   gnc_price_list_destroy(price_list);
01645   return balance;
01646 }

gnc_numeric gnc_pricedb_convert_balance_nearest_price GNCPriceDB pdb,
gnc_numeric  balance,
gnc_commodity balance_currency,
gnc_commodity new_currency,
Timespec  t
 

gnc_pricedb_convert_balance_nearest_price - Convert a balance from one currency to another.

Definition at line 1649 of file gnc-pricedb.c.

01654 {
01655   GNCPrice *price, *currency_price;
01656   GList *price_list, *list_helper;
01657   gnc_numeric currency_price_value;
01658   gnc_commodity *intermediate_currency;
01659 
01660   if (gnc_numeric_zero_p (balance) ||
01661       gnc_commodity_equiv (balance_currency, new_currency))
01662     return balance;
01663 
01664   /* Look for a direct price. */
01665   price = gnc_pricedb_lookup_nearest_in_time (pdb, balance_currency, new_currency, t);
01666   if (price) {
01667     balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
01668                                gnc_commodity_get_fraction (new_currency),
01669                                GNC_HOW_RND_ROUND);
01670     gnc_price_unref (price);
01671     return balance;
01672   }
01673 
01674   /*
01675    * no direct price found, try if we find a price in another currency
01676    * and convert in two stages
01677    */
01678   price_list = gnc_pricedb_lookup_nearest_in_time_any_currency(pdb, balance_currency, t);
01679   if (!price_list) {
01680     balance =  gnc_numeric_zero ();
01681     return balance;
01682   }
01683 
01684   list_helper = price_list;
01685   currency_price_value = gnc_numeric_zero();
01686 
01687   do {
01688     price = (GNCPrice *)(list_helper->data);
01689 
01690     intermediate_currency = gnc_price_get_currency(price);
01691     currency_price = gnc_pricedb_lookup_nearest_in_time(pdb, intermediate_currency,
01692                                                         new_currency, t);
01693     if(currency_price) {
01694       currency_price_value = gnc_price_get_value(currency_price);
01695       gnc_price_unref(currency_price);
01696     } else {
01697       currency_price = gnc_pricedb_lookup_nearest_in_time(pdb, new_currency,
01698                                                           intermediate_currency, t);
01699       if (currency_price) {
01700         /* here we need the reciprocal */
01701         currency_price_value = gnc_numeric_div(gnc_numeric_create(1, 1),
01702                                                gnc_price_get_value(currency_price),
01703                                                gnc_commodity_get_fraction (new_currency),
01704                                                GNC_HOW_RND_ROUND);
01705         gnc_price_unref(currency_price);
01706       }
01707     }
01708 
01709     list_helper = list_helper->next;
01710   } while((list_helper != NULL) &&
01711           (!gnc_numeric_zero_p(currency_price_value)));
01712 
01713   balance = gnc_numeric_mul (balance, currency_price_value,
01714                              gnc_commodity_get_fraction (new_currency),
01715                              GNC_HOW_RND_ROUND);
01716   balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
01717                              gnc_commodity_get_fraction (new_currency),
01718                              GNC_HOW_RND_ROUND);
01719 
01720   gnc_price_list_destroy(price_list);
01721   return balance;
01722 }

GNCPriceDB* gnc_pricedb_create QofBook book  ) 
 

gnc_pricedb_create - create a new pricedb. Normally you won't need this; you will get the pricedb via gnc_pricedb_get_db.

Definition at line 595 of file gnc-pricedb.c.

00596 {
00597   GNCPriceDB * result;
00598   QofCollection *col;
00599 
00600   g_return_val_if_fail (book, NULL);
00601 
00602   /* There can only be one pricedb per book.  So if one exits already,
00603    * then use that.  Warn user, they shouldn't be creating two ...
00604    */
00605   col = qof_book_get_collection (book, GNC_ID_PRICEDB);
00606   result = qof_collection_get_data (col);
00607   if (result)
00608   {
00609     PWARN ("A price database already exists for this book!");
00610     return result;
00611   }
00612 
00613   result = g_new0(GNCPriceDB, 1);
00614   qof_instance_init (&result->inst, GNC_ID_PRICEDB, book);
00615 
00616   /* This leaks result when the collection is destroyed.  When
00617      qofcollection is fixed to allow a destroy notifier, we'll need to
00618      provide one here. */
00619   qof_collection_set_data (col, result);
00620 
00621   result->commodity_hash = g_hash_table_new(commodity_hash, commodity_equal);
00622   g_return_val_if_fail (result->commodity_hash, NULL);
00623   return result;
00624 }

void gnc_pricedb_destroy GNCPriceDB db  ) 
 

gnc_pricedb_destroy - destroy the given pricedb and unref all of the prices it contains. This may not deallocate all of those prices. Other code may still be holding references to them.

Definition at line 659 of file gnc-pricedb.c.

00660 {
00661   if(!db) return;
00662   if(!db->commodity_hash) {
00663   g_hash_table_foreach (db->commodity_hash,
00664                         destroy_pricedb_commodity_hash_data,
00665                         NULL);
00666   }
00667   g_hash_table_destroy (db->commodity_hash);
00668   db->commodity_hash = NULL;
00669   qof_instance_release (&db->inst);
00670   g_free(db);
00671 }

gboolean gnc_pricedb_foreach_price GNCPriceDB db,
gboolean(*)(GNCPrice *p, gpointer user_data)  f,
gpointer  user_data,
gboolean  stable_order
 

gnc_pricedb_foreach_price - call f once for each price in db, until and unless f returns FALSE. If stable_order is not FALSE, make sure the ordering of the traversal is stable (i.e. the same order every time given the same db contents -- stable traversals may be less efficient).

Definition at line 1852 of file gnc-pricedb.c.

01856 {
01857   ENTER ("db=%p f=%p", db, f);
01858   if(stable_order) return stable_price_traversal(db, f, user_data);
01859   return unstable_price_traversal(db, f, user_data);
01860   LEAVE (" ");
01861 }

GNCPriceDB* gnc_pricedb_get_db QofBook book  ) 
 

return the pricedb associated with the book

Definition at line 687 of file gnc-pricedb.c.

00688 {
00689   QofCollection *col;
00690   if (!book) return NULL;
00691   col = qof_book_get_collection (book, GNC_ID_PRICEDB);
00692   return gnc_collection_get_pricedb (col);
00693 }

guint gnc_pricedb_get_num_prices GNCPriceDB db  ) 
 

gnc_pricedb_get_num_prices - return the number of prices in the database.

Definition at line 708 of file gnc-pricedb.c.

00709 {
00710   guint count;
00711 
00712   if (!db) return 0;
00713 
00714   count = 0;
00715 
00716   gnc_pricedb_foreach_price(db, num_prices_helper, &count, FALSE);
00717 
00718   return count;
00719 }

GList* gnc_pricedb_get_prices GNCPriceDB db,
gnc_commodity commodity,
gnc_commodity currency
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1138 of file gnc-pricedb.c.

01141 {
01142   GList *price_list;
01143   GList *result;
01144   GList *node;
01145   GHashTable *currency_hash;
01146 
01147   ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
01148   if(!db || !commodity) return NULL;
01150 #ifdef GNUCASH_MAJOR_VERSION
01151   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01152   {
01153      GNCPriceLookup pl;
01154      pl.type = LOOKUP_ALL;
01155      pl.prdb = db;
01156      pl.commodity = commodity;
01157      pl.currency = currency;
01158      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01159   }
01160 #endif
01161   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
01162   if(!currency_hash) return NULL;
01163 
01164   if (currency) {
01165     price_list = g_hash_table_lookup(currency_hash, currency);
01166     if(!price_list) return NULL;
01167     result = g_list_copy (price_list);
01168   } else {
01169     result = NULL;
01170     g_hash_table_foreach(currency_hash, hash_values_helper, (gpointer)&result);
01171   }
01172   for (node = result; node; node = node->next)
01173     gnc_price_ref (node->data);
01174 
01175   LEAVE (" ");
01176   return result;
01177 }

gboolean gnc_pricedb_has_prices GNCPriceDB db,
gnc_commodity commodity,
gnc_commodity currency
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1093 of file gnc-pricedb.c.

01096 {
01097   GList *price_list;
01098   GHashTable *currency_hash;
01099   gint size;
01100 
01101   ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
01102   if(!db || !commodity) return FALSE;
01104 #ifdef GNUCASH_MAJOR_VERSION
01105   if (db->inst.book && db->inst.book->backend && db->inst.book->backend->price_lookup)
01106   {
01107      GNCPriceLookup pl;
01108      pl.type = LOOKUP_ALL;
01109      pl.prdb = db;
01110      pl.commodity = commodity;
01111      pl.currency = currency;
01112      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01113   }
01114 #endif
01115   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
01116   if(!currency_hash) {
01117     LEAVE("no, no currency_hash table");
01118     return FALSE;
01119   }
01120 
01121   if (currency) {
01122     price_list = g_hash_table_lookup(currency_hash, currency);
01123     if (price_list) {
01124       LEAVE("yes");
01125       return TRUE;
01126     }
01127     LEAVE("no, no price list");
01128     return FALSE;
01129   }
01130 
01131   size = g_hash_table_size (currency_hash);
01132   LEAVE("%s", size > 0 ? "yes" : "no");
01133   return size > 0;
01134 }

GList* gnc_pricedb_lookup_at_time GNCPriceDB db,
gnc_commodity c,
gnc_commodity currency,
Timespec  t
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1295 of file gnc-pricedb.c.

01299 {
01300   GList *price_list;
01301   GList *result = NULL;
01302   GList *item = NULL;
01303   GHashTable *currency_hash;
01304 
01305   ENTER ("db=%p commodity=%p currency=%p", db, c, currency);
01306   if(!db || !c || !currency) return NULL;
01308 #ifdef GNUCASH_MAJOR_VERSION
01309   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01310   {
01311      GNCPriceLookup pl;
01312      pl.type = LOOKUP_AT_TIME;
01313      pl.prdb = db;
01314      pl.commodity = c;
01315      pl.currency = currency;
01316      pl.date = t;
01317      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01318   }
01319 #endif
01320   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
01321   if(!currency_hash) return NULL;
01322 
01323   price_list = g_hash_table_lookup(currency_hash, currency);
01324   if(!price_list) return NULL;
01325 
01326   item = price_list;
01327   while(item) {
01328     GNCPrice *p = item->data;
01329     Timespec price_time = gnc_price_get_time(p);
01330     if(timespec_equal(&price_time, &t)) {
01331       result = g_list_prepend(result, p);
01332       gnc_price_ref(p);
01333     }
01334     item = item->next;
01335   }
01336   LEAVE (" ");
01337   return result;
01338 }

GList* gnc_pricedb_lookup_at_time_any_currency GNCPriceDB db,
gnc_commodity c,
Timespec  t
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1362 of file gnc-pricedb.c.

01365 {
01366   GList *result = NULL;
01367   GHashTable *currency_hash;
01368   GNCPriceLookupHelper lookup_helper;
01369 
01370   ENTER ("db=%p commodity=%p", db, c);
01371   if(!db || !c) return NULL;
01373 #ifdef GNUCASH_MAJOR_VERSION
01374   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01375   {
01376      GNCPriceLookup pl;
01377      pl.type = LOOKUP_AT_TIME;
01378      pl.prdb = db;
01379      pl.commodity = c;
01380      pl.currency = NULL;  /* can the backend handle this??? */
01381      pl.date = t;
01382      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01383   }
01384 #endif
01385   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
01386   if(!currency_hash) return NULL;
01387 
01388   lookup_helper.return_list = &result;
01389   lookup_helper.time = t;
01390   g_hash_table_foreach(currency_hash, lookup_time, &lookup_helper);
01391 
01392   if(!result) return NULL;
01393 
01394   result = g_list_sort(result, compare_prices_by_date);
01395 
01396   LEAVE (" ");
01397   return result;
01398 }

GList* gnc_pricedb_lookup_day GNCPriceDB db,
gnc_commodity c,
gnc_commodity currency,
Timespec  t
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1181 of file gnc-pricedb.c.

01185 {
01186   GList *price_list;
01187   GList *result = NULL;
01188   GList *item = NULL;
01189   GHashTable *currency_hash;
01190 
01191   ENTER ("db=%p commodity=%p currency=%p", db, c, currency);
01192   if(!db || !c || !currency) return NULL;
01193 
01194   /* Convert to noon local time. */
01195   t = timespecCanonicalDayTime(t);
01197 #ifdef GNUCASH_MAJOR_VERSION
01198   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01199   {
01200      GNCPriceLookup pl;
01201      pl.type = LOOKUP_AT_TIME;
01202      pl.prdb = db;
01203      pl.commodity = c;
01204      pl.currency = currency;
01205      pl.date = t;
01206      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01207   }
01208 #endif
01209   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
01210   if(!currency_hash) return NULL;
01211 
01212   price_list = g_hash_table_lookup(currency_hash, currency);
01213   if(!price_list) return NULL;
01214 
01215   item = price_list;
01216   while(item) {
01217     GNCPrice *p = item->data;
01218     Timespec price_time = timespecCanonicalDayTime(gnc_price_get_time(p));
01219     if(timespec_equal(&price_time, &t)) {
01220       result = g_list_prepend(result, p);
01221       gnc_price_ref(p);
01222     }
01223     item = item->next;
01224   }
01225   LEAVE (" ");
01226   return result;
01227 }

GList* gnc_pricedb_lookup_day_any_currency GNCPriceDB db,
gnc_commodity c,
Timespec  t
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1252 of file gnc-pricedb.c.

01255 {
01256   GList *result = NULL;
01257   GHashTable *currency_hash;
01258   GNCPriceLookupHelper lookup_helper;
01259 
01260   ENTER ("db=%p commodity=%p", db, c);
01261   if(!db || !c) return NULL;
01262 
01263   /* Convert to noon local time. */
01264   t = timespecCanonicalDayTime(t);
01266 #ifdef GNUCASH_MAJOR_VERSION
01267   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01268   {
01269      GNCPriceLookup pl;
01270      pl.type = LOOKUP_AT_TIME;
01271      pl.prdb = db;
01272      pl.commodity = c;
01273      pl.currency = NULL;  /* can the backend handle this??? */
01274      pl.date = t;
01275      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01276   }
01277 #endif
01278   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
01279   if(!currency_hash) return NULL;
01280 
01281   lookup_helper.return_list = &result;
01282   lookup_helper.time = t;
01283   g_hash_table_foreach(currency_hash, lookup_day, &lookup_helper);
01284 
01285   if(!result) return NULL;
01286 
01287   result = g_list_sort(result, compare_prices_by_date);
01288 
01289   LEAVE (" ");
01290   return result;
01291 }

GNCPrice* gnc_pricedb_lookup_latest GNCPriceDB db,
gnc_commodity commodity,
gnc_commodity currency
 

Todo:
Fix the backend lookup that relies on a define
Todo:
QOF spinout: fix book->backend price_lookup in gnucash

Definition at line 996 of file gnc-pricedb.c.

00999 {
01000   GList *price_list;
01001   GNCPrice *result;
01002   GHashTable *currency_hash;
01003 
01004   ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
01005   if(!db || !commodity || !currency) return NULL;
01007 #ifdef GNUCASH_MAJOR_VERSION
01008   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01009   {
01010      GNCPriceLookup pl;
01011      pl.type = LOOKUP_LATEST;
01012      pl.prdb = db;
01013      pl.commodity = commodity;
01014      pl.currency = currency;
01015      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01016   }
01017 #endif
01018 
01019   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
01020   if(!currency_hash) return NULL;
01021 
01022   price_list = g_hash_table_lookup(currency_hash, currency);
01023   if(!price_list) return NULL;
01024 
01025   /* This works magically because prices are inserted in date-sorted
01026    * order, and the latest date always comes first. So return the
01027    * first in the list.  */
01028   result = price_list->data;
01029   gnc_price_ref(result);
01030   LEAVE(" ");
01031   return result;
01032 }

GList* gnc_pricedb_lookup_latest_any_currency GNCPriceDB db,
gnc_commodity commodity
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1049 of file gnc-pricedb.c.

01051 {
01052   GList *result;
01053   GHashTable *currency_hash;
01054 
01055   result = NULL;
01056 
01057   ENTER ("db=%p commodity=%p", db, commodity);
01058   if(!db || !commodity) return NULL;
01060 #ifdef GNUCASH_MAJOR_VERSION
01061   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01062   {
01063      GNCPriceLookup pl;
01064      pl.type = LOOKUP_LATEST;
01065      pl.prdb = db;
01066      pl.commodity = commodity;
01067      pl.currency = NULL;  /* can the backend handle this??? */
01068      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01069   }
01070 #endif
01071   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
01072   if(!currency_hash) return NULL;
01073 
01074   g_hash_table_foreach(currency_hash, lookup_latest, &result);
01075 
01076   if(!result) return NULL;
01077 
01078   result = g_list_sort(result, compare_prices_by_date);
01079 
01080   LEAVE(" ");
01081   return result;
01082 }

GNCPrice* gnc_pricedb_lookup_nearest_in_time GNCPriceDB db,
gnc_commodity c,
gnc_commodity currency,
Timespec  t
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1402 of file gnc-pricedb.c.

01406 {
01407   GList *price_list;
01408   GNCPrice *current_price = NULL;
01409   GNCPrice *next_price = NULL;
01410   GNCPrice *result = NULL;
01411   GList *item = NULL;
01412   GHashTable *currency_hash;
01413 
01414   ENTER ("db=%p commodity=%p currency=%p", db, c, currency);
01415   if(!db || !c || !currency) return NULL;
01417 #ifdef GNUCASH_MAJOR_VERSION
01418   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01419   {
01420      GNCPriceLookup pl;
01421      pl.type = LOOKUP_NEAREST_IN_TIME;
01422      pl.prdb = db;
01423      pl.commodity = c;
01424      pl.currency = currency;
01425      pl.date = t;
01426      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01427   }
01428 #endif
01429   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
01430   if(!currency_hash) return NULL;
01431 
01432   price_list = g_hash_table_lookup(currency_hash, currency);
01433   if(!price_list) return NULL;
01434 
01435   item = price_list;
01436 
01437   /* default answer */
01438   current_price = item->data;
01439 
01440   /* find the first candidate past the one we want.  Remember that
01441      prices are in most-recent-first order. */
01442   while (!next_price && item) {
01443     GNCPrice *p = item->data;
01444     Timespec price_time = gnc_price_get_time(p);
01445     if (timespec_cmp(&price_time, &t) <= 0) {
01446       next_price = item->data;
01447       break;
01448     }
01449     current_price = item->data;
01450     item = item->next;
01451   }
01452 
01453   if (current_price) {
01454     if (!next_price) {
01455       result = current_price;
01456     } else {
01457       Timespec current_t = gnc_price_get_time(current_price);
01458       Timespec next_t = gnc_price_get_time(next_price);
01459       Timespec diff_current = timespec_diff(&current_t, &t);
01460       Timespec diff_next = timespec_diff(&next_t, &t);
01461       Timespec abs_current = timespec_abs(&diff_current);
01462       Timespec abs_next = timespec_abs(&diff_next);
01463 
01464       if (timespec_cmp(&abs_current, &abs_next) <= 0) {
01465         result = current_price;
01466       } else {
01467         result = next_price;
01468       }
01469     }
01470   }
01471 
01472   gnc_price_ref(result);
01473   LEAVE (" ");
01474   return result;
01475 }

GList* gnc_pricedb_lookup_nearest_in_time_any_currency GNCPriceDB db,
gnc_commodity c,
Timespec  t
 

Todo:
QOF spinout: Fix the book->backend lookup

Definition at line 1531 of file gnc-pricedb.c.

01534 {
01535   GList *result = NULL;
01536   GHashTable *currency_hash;
01537   GNCPriceLookupHelper lookup_helper;
01538 
01539   ENTER ("db=%p commodity=%p", db, c);
01540   if(!db || !c) return NULL;
01542 #ifdef GNUCASH_MAJOR_VERSION
01543   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
01544   {
01545      GNCPriceLookup pl;
01546      pl.type = LOOKUP_NEAREST_IN_TIME;
01547      pl.prdb = db;
01548      pl.commodity = c;
01549      pl.currency = NULL;  /* can the backend handle this??? */
01550      pl.date = t;
01551      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
01552   }
01553 #endif
01554   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
01555   if(!currency_hash) return NULL;
01556 
01557   lookup_helper.return_list = &result;
01558   lookup_helper.time = t;
01559   g_hash_table_foreach(currency_hash, lookup_nearest, &lookup_helper);
01560 
01561   if(!result) return NULL;
01562 
01563   result = g_list_sort(result, compare_prices_by_date);
01564 
01565   LEAVE (" ");
01566   return result;
01567 }

gboolean gnc_pricedb_remove_price GNCPriceDB db,
GNCPrice p
 

gnc_pricedb_remove_price - removes the given price, p, from the pricedb. Returns TRUE if successful, FALSE otherwise.

Definition at line 926 of file gnc-pricedb.c.

00927 {
00928   gboolean rc;
00929   if(!db || !p) return FALSE;
00930   ENTER ("db=%p, pr=%p dirty=%d do-free=%d",
00931          db, p, p->inst.dirty, p->inst.do_free);
00932 
00933   gnc_price_ref(p);
00934   rc = remove_price (db, p, TRUE);
00935 
00936   /* invoke the backend to delete this price */
00937   gnc_price_begin_edit (p);
00938   db->inst.dirty = TRUE;
00939   p->inst.do_free = TRUE;
00940   gnc_price_commit_edit (p);
00941 
00942   p->db = NULL;
00943   gnc_price_unref(p);
00944   LEAVE ("db=%p, pr=%p", db, p);
00945   return rc;
00946 }


Generated on Sun Sep 4 18:09:13 2005 for GnuCash by  doxygen 1.4.3-20050530