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

Files

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

Typedefs

typedef struct gnc_price_db_s GNCPriceDB
 

Functions

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 *)
 
void gnc_pricedb_set_bulk_update (GNCPriceDB *db, gboolean bulk_update)
 
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, const gboolean delete_user, gboolean delete_last)
 
GNCPricegnc_pricedb_lookup_latest (GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
 
PriceList * gnc_pricedb_lookup_latest_any_currency (GNCPriceDB *db, const gnc_commodity *commodity)
 
gboolean gnc_pricedb_has_prices (GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
 
PriceList * gnc_pricedb_get_prices (GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
 
PriceList * gnc_pricedb_lookup_at_time (GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency, Timespec t)
 
GNCPricegnc_pricedb_lookup_day (GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency, Timespec t)
 
GNCPricegnc_pricedb_lookup_nearest_in_time (GNCPriceDB *db, const gnc_commodity *c, const gnc_commodity *currency, Timespec t)
 
PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency (GNCPriceDB *db, const gnc_commodity *c, Timespec t)
 
GNCPricegnc_pricedb_lookup_latest_before (GNCPriceDB *db, gnc_commodity *c, gnc_commodity *currency, Timespec t)
 
PriceList * gnc_pricedb_lookup_latest_before_any_currency (GNCPriceDB *db, gnc_commodity *c, Timespec t)
 
gnc_numeric gnc_pricedb_convert_balance_latest_price (GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency)
 
gnc_numeric gnc_pricedb_convert_balance_nearest_price (GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const 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)
 

Internal/Debugging

void gnc_pricedb_print_contents (GNCPriceDB *db, FILE *f)
 

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"
 

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, accessible via gnc_pricedb_get_db.

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. It should. In particular, this means that currently prices cannot be queried with the same mechanism 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.

Typedef Documentation

typedef struct gnc_price_db_s GNCPriceDB

Data type

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

Function Documentation

GNCPriceDB* gnc_collection_get_pricedb ( QofCollection *  col)
Todo:
Collections of prices are not destroyed fully.
gnc_pricedb_destroy does not clean up properly because gnc_pricedb_create reports an existing PriceDB after running gnc_pricedb_destroy. To change the pricedb, we need to destroy and recreate the book. Yuk.

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

866 {
867  if (!col) return NULL;
868  return qof_collection_get_data (col);
869 }
gpointer qof_collection_get_data(const QofCollection *col)
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 1053 of file gnc-pricedb.c.

1054 {
1055  if (!db || !p) return FALSE;
1056 
1057  ENTER ("db=%p, pr=%p dirty=%d destroying=%d",
1058  db, p, qof_instance_get_dirty_flag(p),
1060 
1061  if (FALSE == add_price(db, p))
1062  {
1063  LEAVE (" failed to add price");
1064  return FALSE;
1065  }
1066 
1068  qof_instance_set_dirty(&db->inst);
1069  gnc_pricedb_commit_edit(db);
1070 
1071  LEAVE ("db=%p, pr=%p dirty=%d destroying=%d",
1072  db, p, qof_instance_get_dirty_flag(p),
1074 
1075  return TRUE;
1076 }
gboolean qof_instance_get_destroying(gconstpointer ptr)
#define ENTER(format, args...)
Definition: qoflog.h:261
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
void gnc_pricedb_begin_edit(GNCPriceDB *pdb)
Definition: gnc-pricedb.c:358
#define LEAVE(format, args...)
Definition: qoflog.h:271
void gnc_pricedb_begin_edit ( GNCPriceDB )

Used for editing the pricedb en-mass

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

359 {
360  qof_begin_edit(&pdb->inst);
361 }
gboolean qof_begin_edit(QofInstance *inst)
gnc_numeric gnc_pricedb_convert_balance_latest_price ( GNCPriceDB pdb,
gnc_numeric  balance,
const gnc_commodity balance_currency,
const gnc_commodity new_currency 
)

gnc_pricedb_convert_balance_latest_price - Convert a balance from one currency to another.

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

2017 {
2018  GNCPrice *price, *currency_price;
2019  GList *price_list, *list_helper;
2020  gnc_numeric currency_price_value;
2021  gnc_commodity *intermediate_currency;
2022 
2023  if (gnc_numeric_zero_p (balance) ||
2024  gnc_commodity_equiv (balance_currency, new_currency))
2025  return balance;
2026 
2027  /* Look for a direct price. */
2028  price = gnc_pricedb_lookup_latest (pdb, balance_currency, new_currency);
2029  if (price)
2030  {
2031  balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
2032  gnc_commodity_get_fraction (new_currency),
2034  gnc_price_unref (price);
2035  return balance;
2036  }
2037 
2038  /* Look for a price of the new currency in the balance currency and use
2039  * the reciprocal if we find it
2040  */
2041  price = gnc_pricedb_lookup_latest (pdb, new_currency, balance_currency);
2042  if (price)
2043  {
2044  balance = gnc_numeric_div (balance, gnc_price_get_value (price),
2045  gnc_commodity_get_fraction (new_currency),
2047  gnc_price_unref (price);
2048  return balance;
2049  }
2050 
2051  /*
2052  * no direct price found, try if we find a price in another currency
2053  * and convert in two stages
2054  */
2055  price_list = gnc_pricedb_lookup_latest_any_currency(pdb, balance_currency);
2056  if (!price_list)
2057  {
2058  balance = gnc_numeric_zero ();
2059  return balance;
2060  }
2061 
2062  list_helper = price_list;
2063  currency_price_value = gnc_numeric_zero();
2064 
2065  do
2066  {
2067  price = (GNCPrice *)(list_helper->data);
2068 
2069  intermediate_currency = gnc_price_get_currency(price);
2070  currency_price = gnc_pricedb_lookup_latest(pdb, intermediate_currency,
2071  new_currency);
2072  if (currency_price)
2073  {
2074  currency_price_value = gnc_price_get_value(currency_price);
2075  gnc_price_unref(currency_price);
2076  }
2077  else
2078  {
2079  currency_price = gnc_pricedb_lookup_latest(pdb, new_currency,
2080  intermediate_currency);
2081  if (currency_price)
2082  {
2083  /* here we need the reciprocal */
2084  currency_price_value = gnc_numeric_div(gnc_numeric_create(1, 1),
2085  gnc_price_get_value(currency_price),
2088  gnc_price_unref(currency_price);
2089  }
2090  }
2091 
2092  list_helper = list_helper->next;
2093  }
2094  while ((list_helper != NULL) &&
2095  (gnc_numeric_zero_p(currency_price_value)));
2096 
2097  balance = gnc_numeric_mul (balance, currency_price_value,
2100  balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
2101  gnc_commodity_get_fraction (new_currency),
2103 
2104  gnc_price_list_destroy(price_list);
2105  return balance;
2106 }
void gnc_price_list_destroy(PriceList *prices)
Definition: gnc-pricedb.c:701
int gnc_commodity_get_fraction(const gnc_commodity *cm)
void gnc_price_unref(GNCPrice *p)
Definition: gnc-pricedb.c:272
gboolean gnc_numeric_zero_p(gnc_numeric a)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
PriceList * gnc_pricedb_lookup_latest_any_currency(GNCPriceDB *db, const gnc_commodity *commodity)
Definition: gnc-pricedb.c:1373
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
GNCPrice * gnc_pricedb_lookup_latest(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
Definition: gnc-pricedb.c:1309
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
gnc_numeric gnc_pricedb_convert_balance_nearest_price ( GNCPriceDB pdb,
gnc_numeric  balance,
const gnc_commodity balance_currency,
const gnc_commodity new_currency,
Timespec  t 
)

gnc_pricedb_convert_balance_nearest_price - Convert a balance from one currency to another.

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

2114 {
2115  GNCPrice *price, *currency_price;
2116  GList *price_list, *list_helper;
2117  gnc_numeric currency_price_value;
2118  gnc_commodity *intermediate_currency;
2119 
2120  if (gnc_numeric_zero_p (balance) ||
2121  gnc_commodity_equiv (balance_currency, new_currency))
2122  return balance;
2123 
2124  /* Look for a direct price. */
2125  price = gnc_pricedb_lookup_nearest_in_time (pdb, balance_currency, new_currency, t);
2126  if (price)
2127  {
2128  balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
2129  gnc_commodity_get_fraction (new_currency),
2131  gnc_price_unref (price);
2132  return balance;
2133  }
2134 
2135  /* Look for a price of the new currency in the balance currency and use
2136  * the reciprocal if we find it
2137  */
2138  price = gnc_pricedb_lookup_nearest_in_time (pdb, new_currency, balance_currency, t);
2139  if (price)
2140  {
2141  balance = gnc_numeric_div (balance, gnc_price_get_value (price),
2142  gnc_commodity_get_fraction (new_currency),
2144  gnc_price_unref (price);
2145  return balance;
2146  }
2147 
2148  /*
2149  * no direct price found, try if we find a price in another currency
2150  * and convert in two stages
2151  */
2152  price_list = gnc_pricedb_lookup_nearest_in_time_any_currency(pdb, balance_currency, t);
2153  if (!price_list)
2154  {
2155  balance = gnc_numeric_zero ();
2156  return balance;
2157  }
2158 
2159  list_helper = price_list;
2160  currency_price_value = gnc_numeric_zero();
2161 
2162  do
2163  {
2164  price = (GNCPrice *)(list_helper->data);
2165 
2166  intermediate_currency = gnc_price_get_currency(price);
2167  currency_price = gnc_pricedb_lookup_nearest_in_time(pdb, intermediate_currency,
2168  new_currency, t);
2169  if (currency_price)
2170  {
2171  currency_price_value = gnc_price_get_value(currency_price);
2172  gnc_price_unref(currency_price);
2173  }
2174  else
2175  {
2176  currency_price = gnc_pricedb_lookup_nearest_in_time(pdb, new_currency,
2177  intermediate_currency, t);
2178  if (currency_price)
2179  {
2180  /* here we need the reciprocal */
2181  currency_price_value = gnc_numeric_div(gnc_numeric_create(1, 1),
2182  gnc_price_get_value(currency_price),
2185  gnc_price_unref(currency_price);
2186  }
2187  }
2188 
2189  list_helper = list_helper->next;
2190  }
2191  while ((list_helper != NULL) &&
2192  (gnc_numeric_zero_p(currency_price_value)));
2193 
2194  balance = gnc_numeric_mul (balance, currency_price_value,
2197 
2198  balance = gnc_numeric_mul (balance, gnc_price_get_value (price),
2199  gnc_commodity_get_fraction (new_currency),
2201 
2202  gnc_price_list_destroy(price_list);
2203  return balance;
2204 }
void gnc_price_list_destroy(PriceList *prices)
Definition: gnc-pricedb.c:701
int gnc_commodity_get_fraction(const gnc_commodity *cm)
PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency(GNCPriceDB *db, const gnc_commodity *c, Timespec t)
Definition: gnc-pricedb.c:1908
void gnc_price_unref(GNCPrice *p)
Definition: gnc-pricedb.c:272
gboolean gnc_numeric_zero_p(gnc_numeric a)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
GNCPrice * gnc_pricedb_lookup_nearest_in_time(GNCPriceDB *db, const gnc_commodity *c, const gnc_commodity *currency, Timespec t)
Definition: gnc-pricedb.c:1744
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
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 828 of file gnc-pricedb.c.

829 {
830  if (!db) return;
831  if (db->commodity_hash)
832  {
833  g_hash_table_foreach (db->commodity_hash,
834  destroy_pricedb_commodity_hash_data,
835  NULL);
836  }
837  g_hash_table_destroy (db->commodity_hash);
838  db->commodity_hash = NULL;
839  /* qof_instance_release (&db->inst); */
840  g_object_unref(db);
841 }
gboolean gnc_pricedb_equal ( GNCPriceDB db1,
GNCPriceDB db2 
)

gnc_pricedb_equal - test equality of two pricedbs

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

950 {
951  GNCPriceDBEqualData equal_data;
952 
953  if (db1 == db2) return TRUE;
954 
955  if (!db1 || !db2)
956  {
957  PWARN ("one is NULL");
958  return FALSE;
959  }
960 
961  equal_data.equal = TRUE;
962  equal_data.db2 = db2;
963 
964  g_hash_table_foreach (db1->commodity_hash,
965  pricedb_equal_foreach_currencies_hash,
966  &equal_data);
967 
968  return equal_data.equal;
969 }
#define PWARN(format, args...)
Definition: qoflog.h:243
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 2344 of file gnc-pricedb.c.

2348 {
2349  ENTER ("db=%p f=%p", db, f);
2350  if (stable_order)
2351  {
2352  LEAVE (" stable order found");
2353  return stable_price_traversal(db, f, user_data);
2354  }
2355  LEAVE (" use unstable order");
2356  return unstable_price_traversal(db, f, user_data);
2357 }
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
GNCPriceDB* gnc_pricedb_get_db ( QofBook book)

return the pricedb associated with the book

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

873 {
874  QofCollection *col;
875 
876  if (!book) return NULL;
877  col = qof_book_get_collection (book, GNC_ID_PRICEDB);
878  return gnc_collection_get_pricedb (col);
879 }
GNCPriceDB * gnc_collection_get_pricedb(QofCollection *col)
Definition: gnc-pricedb.c:865
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
guint gnc_pricedb_get_num_prices ( GNCPriceDB db)

gnc_pricedb_get_num_prices - return the number of prices in the database.

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

895 {
896  guint count;
897 
898  if (!db) return 0;
899 
900  count = 0;
901 
902  gnc_pricedb_foreach_price(db, num_prices_helper, &count, FALSE);
903 
904  return count;
905 }
gboolean gnc_pricedb_foreach_price(GNCPriceDB *db, gboolean(*f)(GNCPrice *p, gpointer user_data), gpointer user_data, gboolean stable_order)
Definition: gnc-pricedb.c:2344
PriceList* gnc_pricedb_get_prices ( GNCPriceDB db,
const gnc_commodity commodity,
const gnc_commodity currency 
)

gnc_pricedb_get_prices - return all the prices for a given commodity in the given currency. Returns NULL on failure. The result is a GNCPrice list (see above).

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

1482 {
1483  GList *price_list;
1484  GList *result;
1485  GList *node;
1486  GHashTable *currency_hash;
1487  QofBook *book;
1488  QofBackend *be;
1489 
1490  if (!db || !commodity) return NULL;
1491  ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
1492  book = qof_instance_get_book(&db->inst);
1493  be = qof_book_get_backend(book);
1494 #ifdef GNUCASH_MAJOR_VERSION
1495  if (be && be->price_lookup)
1496  {
1497  GNCPriceLookup pl;
1498  pl.type = LOOKUP_ALL;
1499  pl.prdb = db;
1500  pl.commodity = commodity;
1501  pl.currency = currency;
1502  (be->price_lookup) (be, &pl);
1503  }
1504 #endif
1505  currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
1506  if (!currency_hash)
1507  {
1508  LEAVE (" no currency hash");
1509  return NULL;
1510  }
1511 
1512  if (currency)
1513  {
1514  price_list = g_hash_table_lookup(currency_hash, currency);
1515  if (!price_list)
1516  {
1517  LEAVE (" no price list");
1518  return NULL;
1519  }
1520  result = g_list_copy (price_list);
1521  }
1522  else
1523  {
1524  result = NULL;
1525  g_hash_table_foreach(currency_hash, hash_values_helper, (gpointer)&result);
1526  }
1527  for (node = result; node; node = node->next)
1528  gnc_price_ref (node->data);
1529 
1530  LEAVE (" ");
1531  return result;
1532 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
void gnc_price_ref(GNCPrice *p)
Definition: gnc-pricedb.c:265
gboolean gnc_pricedb_has_prices ( GNCPriceDB db,
const gnc_commodity commodity,
const gnc_commodity currency 
)

gnc_pricedb_has_prices - return an indication of whether or not there are any prices for a given commodity in the given currency. Returns TRUE if there are prices, FALSE otherwise.

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

1431 {
1432  GList *price_list;
1433  GHashTable *currency_hash;
1434  gint size;
1435  QofBook *book;
1436  QofBackend *be;
1437 
1438  if (!db || !commodity) return FALSE;
1439  ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
1440  book = qof_instance_get_book(&db->inst);
1441  be = qof_book_get_backend(book);
1442 #ifdef GNUCASH_MAJOR_VERSION
1443  if (book && be && be->price_lookup)
1444  {
1445  GNCPriceLookup pl;
1446  pl.type = LOOKUP_ALL;
1447  pl.prdb = db;
1448  pl.commodity = commodity;
1449  pl.currency = currency;
1450  (be->price_lookup) (be, &pl);
1451  }
1452 #endif
1453  currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
1454  if (!currency_hash)
1455  {
1456  LEAVE("no, no currency_hash table");
1457  return FALSE;
1458  }
1459 
1460  if (currency)
1461  {
1462  price_list = g_hash_table_lookup(currency_hash, currency);
1463  if (price_list)
1464  {
1465  LEAVE("yes");
1466  return TRUE;
1467  }
1468  LEAVE("no, no price list");
1469  return FALSE;
1470  }
1471 
1472  size = g_hash_table_size (currency_hash);
1473  LEAVE("%s", size > 0 ? "yes" : "no");
1474  return size > 0;
1475 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
PriceList* gnc_pricedb_lookup_at_time ( GNCPriceDB db,
const gnc_commodity commodity,
const gnc_commodity currency,
Timespec  t 
)

gnc_pricedb_lookup_at_time - return all prices that match the given commodity, currency, and timespec. Prices will be returned as a GNCPrice list (see above).

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

1549 {
1550  GList *price_list;
1551  GList *result = NULL;
1552  GList *item = NULL;
1553  GHashTable *currency_hash;
1554  QofBook *book;
1555  QofBackend *be;
1556 
1557  if (!db || !c || !currency) return NULL;
1558  ENTER ("db=%p commodity=%p currency=%p", db, c, currency);
1559  book = qof_instance_get_book(&db->inst);
1560  be = qof_book_get_backend(book);
1561 #ifdef GNUCASH_MAJOR_VERSION
1562  if (be && be->price_lookup)
1563  {
1564  GNCPriceLookup pl;
1565  pl.type = LOOKUP_AT_TIME;
1566  pl.prdb = db;
1567  pl.commodity = c;
1568  pl.currency = currency;
1569  pl.date = t;
1570  (be->price_lookup) (be, &pl);
1571  }
1572 #endif
1573  currency_hash = g_hash_table_lookup(db->commodity_hash, c);
1574  if (!currency_hash)
1575  {
1576  LEAVE (" no currency hash");
1577  return NULL;
1578  }
1579 
1580  price_list = g_hash_table_lookup(currency_hash, currency);
1581  if (!price_list)
1582  {
1583  LEAVE (" no price list");
1584  return NULL;
1585  }
1586 
1587  item = price_list;
1588  while (item)
1589  {
1590  GNCPrice *p = item->data;
1591  Timespec price_time = gnc_price_get_time(p);
1592  if (timespec_equal(&price_time, &t))
1593  {
1594  result = g_list_prepend(result, p);
1595  gnc_price_ref(p);
1596  }
1597  item = item->next;
1598  }
1599  LEAVE (" ");
1600  return result;
1601 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
gboolean timespec_equal(const Timespec *ta, const Timespec *tb)
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
void gnc_price_ref(GNCPrice *p)
Definition: gnc-pricedb.c:265
GNCPrice* gnc_pricedb_lookup_day ( GNCPriceDB db,
const gnc_commodity commodity,
const gnc_commodity currency,
Timespec  t 
)

gnc_pricedb_lookup_day - return the price that matchex the given commodity, currency, and timespec which is on the same day. If no prices are on that day, returns a null value.

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

1540 {
1541  return lookup_nearest_in_time(db, c, currency, t, TRUE);
1542 }
GNCPrice* gnc_pricedb_lookup_latest ( GNCPriceDB db,
const gnc_commodity commodity,
const gnc_commodity currency 
)

gnc_pricedb_lookup_latest - find the most recent price for the given commodity in the given currency. Returns NULL on failure.

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

1312 {
1313  GList *price_list;
1314  GNCPrice *result;
1315  GHashTable *currency_hash;
1316  QofBook *book;
1317  QofBackend *be;
1318 
1319  if (!db || !commodity || !currency) return NULL;
1320  ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
1321  book = qof_instance_get_book(&db->inst);
1322  be = qof_book_get_backend(book);
1323 #ifdef GNUCASH_MAJOR_VERSION
1324  if (be && be->price_lookup)
1325  {
1326  GNCPriceLookup pl;
1327  pl.type = LOOKUP_LATEST;
1328  pl.prdb = db;
1329  pl.commodity = commodity;
1330  pl.currency = currency;
1331  (be->price_lookup) (be, &pl);
1332  }
1333 #endif
1334 
1335  currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
1336  if (!currency_hash)
1337  {
1338  LEAVE (" no currency hash");
1339  return NULL;
1340  }
1341 
1342  price_list = g_hash_table_lookup(currency_hash, currency);
1343  if (!price_list)
1344  {
1345  LEAVE (" no price list");
1346  return NULL;
1347  }
1348 
1349  /* This works magically because prices are inserted in date-sorted
1350  * order, and the latest date always comes first. So return the
1351  * first in the list. */
1352  result = price_list->data;
1353  gnc_price_ref(result);
1354  LEAVE(" ");
1355  return result;
1356 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
void gnc_price_ref(GNCPrice *p)
Definition: gnc-pricedb.c:265
PriceList* gnc_pricedb_lookup_latest_any_currency ( GNCPriceDB db,
const gnc_commodity commodity 
)

gnc_pricedb_lookup_latest_any_currency - find the most recent prices for the given commodity in any available currency. Prices will be returned as a GNCPrice list (see above).

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

1375 {
1376  GList *result;
1377  GHashTable *currency_hash;
1378  QofBook *book;
1379  QofBackend *be;
1380 
1381  result = NULL;
1382 
1383  if (!db || !commodity) return NULL;
1384  ENTER ("db=%p commodity=%p", db, commodity);
1385  book = qof_instance_get_book(&db->inst);
1386  be = qof_book_get_backend(book);
1387 #ifdef GNUCASH_MAJOR_VERSION
1388  if (be && be->price_lookup)
1389  {
1390  GNCPriceLookup pl;
1391  pl.type = LOOKUP_LATEST;
1392  pl.prdb = db;
1393  pl.commodity = commodity;
1394  pl.currency = NULL; /* can the backend handle this??? */
1395  (be->price_lookup) (be, &pl);
1396  }
1397 #endif
1398  currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
1399  if (!currency_hash)
1400  {
1401  LEAVE (" no currency hash");
1402  return NULL;
1403  }
1404 
1405  g_hash_table_foreach(currency_hash, lookup_latest, &result);
1406 
1407  if (!result)
1408  {
1409  LEAVE (" ");
1410  return NULL;
1411  }
1412 
1413  result = g_list_sort(result, compare_prices_by_date);
1414 
1415  LEAVE(" ");
1416  return result;
1417 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
GNCPrice* gnc_pricedb_lookup_latest_before ( GNCPriceDB db,
gnc_commodity c,
gnc_commodity currency,
Timespec  t 
)

gnc_pricedb_lookup_latest_before - return the latest price for the given commodity in the given currency up to and including time t.

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

1757 {
1758  GList *price_list;
1759  GNCPrice *current_price = NULL;
1760  /* GNCPrice *next_price = NULL;
1761  GNCPrice *result = NULL;*/
1762  GList *item = NULL;
1763  GHashTable *currency_hash;
1764  QofBook *book;
1765  QofBackend *be;
1766  Timespec price_time;
1767 
1768  if (!db || !c || !currency) return NULL;
1769  ENTER ("db=%p commodity=%p currency=%p", db, c, currency);
1770  book = qof_instance_get_book(&db->inst);
1771  be = qof_book_get_backend(book);
1772 #ifdef GNUCASH_MAJOR_VERSION
1773  if (be && be->price_lookup)
1774  {
1775  GNCPriceLookup pl;
1776  pl.type = LOOKUP_LATEST_BEFORE;
1777  pl.prdb = db;
1778  pl.commodity = c;
1779  pl.currency = currency;
1780  pl.date = t;
1781  (be->price_lookup) (be, &pl);
1782  }
1783 #endif
1784  currency_hash = g_hash_table_lookup(db->commodity_hash, c);
1785  if (!currency_hash)
1786  {
1787  LEAVE ("no currency hash");
1788  return NULL;
1789  }
1790 
1791  price_list = g_hash_table_lookup(currency_hash, currency);
1792  if (!price_list)
1793  {
1794  LEAVE ("no price list");
1795  return NULL;
1796  }
1797 
1798  item = price_list;
1799  do
1800  {
1801  price_time = gnc_price_get_time (item->data);
1802  if (timespec_cmp(&price_time, &t) <= 0)
1803  current_price = item->data;
1804  item = item->next;
1805  }
1806  while (timespec_cmp(&price_time, &t) > 0 && item);
1807  gnc_price_ref(current_price);
1808  LEAVE (" ");
1809  return current_price;
1810 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
#define ENTER(format, args...)
Definition: qoflog.h:261
gint timespec_cmp(const Timespec *ta, const Timespec *tb)
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
void gnc_price_ref(GNCPrice *p)
Definition: gnc-pricedb.c:265
PriceList* gnc_pricedb_lookup_latest_before_any_currency ( GNCPriceDB db,
gnc_commodity c,
Timespec  t 
)

gnc_pricedb_lookup_latest_before_any_currency - return recent prices that match the given commodity up to and including time t in any available currency. Prices will be returned as a GNCPrice list (see above).

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

1962 {
1963  GList *result = NULL;
1964  GHashTable *currency_hash;
1965  GNCPriceLookupHelper lookup_helper;
1966  QofBook *book;
1967  QofBackend *be;
1968 
1969  if (!db || !c) return NULL;
1970  ENTER ("db=%p commodity=%p", db, c);
1971  book = qof_instance_get_book(&db->inst);
1972  be = qof_book_get_backend(book);
1973 #ifdef GNUCASH_MAJOR_VERSION
1974  if (be && be->price_lookup)
1975  {
1976  GNCPriceLookup pl;
1977  pl.type = LOOKUP_LATEST_BEFORE;
1978  pl.prdb = db;
1979  pl.commodity = c;
1980  pl.currency = NULL; /* can the backend handle this??? */
1981  pl.date = t;
1982  (be->price_lookup) (be, &pl);
1983  }
1984 #endif
1985  currency_hash = g_hash_table_lookup(db->commodity_hash, c);
1986  if (!currency_hash)
1987  {
1988  LEAVE (" no currency hash");
1989  return NULL;
1990  }
1991 
1992  lookup_helper.return_list = &result;
1993  lookup_helper.time = t;
1994  g_hash_table_foreach(currency_hash, lookup_latest_before, &lookup_helper);
1995 
1996  if (!result)
1997  {
1998  LEAVE (" ");
1999  return NULL;
2000  }
2001 
2002  result = g_list_sort(result, compare_prices_by_date);
2003 
2004  LEAVE (" ");
2005  return result;
2006 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
GNCPrice* gnc_pricedb_lookup_nearest_in_time ( GNCPriceDB db,
const gnc_commodity c,
const gnc_commodity currency,
Timespec  t 
)

gnc_pricedb_lookup_nearest_in_time - return the price for the given commodity in the given currency nearest to the given time t.

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

1748 {
1749  return lookup_nearest_in_time(db, c, currency, t, FALSE);
1750 }
PriceList* gnc_pricedb_lookup_nearest_in_time_any_currency ( GNCPriceDB db,
const gnc_commodity c,
Timespec  t 
)

gnc_pricedb_lookup_nearest_in_time_any_currency - return all prices that match the given commodity and timespec in any available currency. Prices will be returned as a GNCPrice list (see above).

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

1911 {
1912  GList *result = NULL;
1913  GHashTable *currency_hash;
1914  GNCPriceLookupHelper lookup_helper;
1915  QofBook *book;
1916  QofBackend *be;
1917 
1918  if (!db || !c) return NULL;
1919  ENTER ("db=%p commodity=%p", db, c);
1920  book = qof_instance_get_book(&db->inst);
1921  be = qof_book_get_backend(book);
1922 #ifdef GNUCASH_MAJOR_VERSION
1923  if (be && be->price_lookup)
1924  {
1925  GNCPriceLookup pl;
1926  pl.type = LOOKUP_NEAREST_IN_TIME;
1927  pl.prdb = db;
1928  pl.commodity = c;
1929  pl.currency = NULL; /* can the backend handle this??? */
1930  pl.date = t;
1931  (be->price_lookup) (be, &pl);
1932  }
1933 #endif
1934  currency_hash = g_hash_table_lookup(db->commodity_hash, c);
1935  if (!currency_hash)
1936  {
1937  LEAVE (" no currency hash");
1938  return NULL;
1939  }
1940 
1941  lookup_helper.return_list = &result;
1942  lookup_helper.time = t;
1943  g_hash_table_foreach(currency_hash, lookup_nearest, &lookup_helper);
1944 
1945  if (!result)
1946  {
1947  LEAVE (" ");
1948  return NULL;
1949  }
1950 
1951  result = g_list_sort(result, compare_prices_by_date);
1952 
1953  LEAVE (" ");
1954  return result;
1955 }
QofBook * qof_instance_get_book(gconstpointer)
void(* price_lookup)(QofBackend *, gpointer)
Definition: qofbackend-p.h:336
#define ENTER(format, args...)
Definition: qoflog.h:261
#define LEAVE(format, args...)
Definition: qoflog.h:271
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
void gnc_pricedb_print_contents ( GNCPriceDB db,
FILE *  f 
)

This simple function can be useful for debugging the pricedb code

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

2481 {
2482  if (!db)
2483  {
2484  PERR("NULL PriceDB\n");
2485  return;
2486  }
2487  if (!f)
2488  {
2489  PERR("NULL FILE*\n");
2490  return;
2491  }
2492 
2493  fprintf(f, "<gnc:pricedb>\n");
2494  gnc_pricedb_foreach_price(db, print_pricedb_adapter, f, FALSE);
2495  fprintf(f, "</gnc:pricedb>\n");
2496 }
#define PERR(format, args...)
Definition: qoflog.h:237
gboolean gnc_pricedb_foreach_price(GNCPriceDB *db, gboolean(*f)(GNCPrice *p, gpointer user_data), gpointer user_data, gboolean stable_order)
Definition: gnc-pricedb.c:2344
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 1160 of file gnc-pricedb.c.

1161 {
1162  gboolean rc;
1163  if (!db || !p) return FALSE;
1164  ENTER ("db=%p, pr=%p dirty=%d destroying=%d",
1165  db, p, qof_instance_get_dirty_flag(p),
1167 
1168  gnc_price_ref(p);
1169  rc = remove_price (db, p, TRUE);
1171  qof_instance_set_dirty(&db->inst);
1172  gnc_pricedb_commit_edit(db);
1173 
1174  /* invoke the backend to delete this price */
1175  gnc_price_begin_edit (p);
1176  qof_instance_set_destroying(p, TRUE);
1177  gnc_price_commit_edit (p);
1178  p->db = NULL;
1179  gnc_price_unref(p);
1180  LEAVE ("db=%p, pr=%p", db, p);
1181  return rc;
1182 }
void gnc_price_unref(GNCPrice *p)
Definition: gnc-pricedb.c:272
gboolean qof_instance_get_destroying(gconstpointer ptr)
#define ENTER(format, args...)
Definition: qoflog.h:261
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
void gnc_pricedb_begin_edit(GNCPriceDB *pdb)
Definition: gnc-pricedb.c:358
#define LEAVE(format, args...)
Definition: qoflog.h:271
void gnc_price_ref(GNCPrice *p)
Definition: gnc-pricedb.c:265
void gnc_pricedb_set_bulk_update ( GNCPriceDB db,
gboolean  bulk_update 
)

Indicate whether or not the database is in the middle of a bulk update. Setting this flag will disable checks for duplicate entries.

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

845 {
846  db->bulk_update = bulk_update;
847 }