-
Notifications
You must be signed in to change notification settings - Fork 3
/
README
148 lines (95 loc) · 4.51 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
README for currency contrib module
----------------------------------
This postgres module implements an arbitrary precision, multi-currency
money type.
* support for up to 999 currencies in a currency lookup table
* monetary values stored in the same amount of space as a NUMERIC,
plus 2 bytes.
* convenient conversion between currencies
* addition of values in different currencies; nomination of a
"neutral" currency via auxilliary table
* fast bulk comparisons (eg sorting a large result set by price), by
internally caching exchange rates table
Defined Entities
----------------
TLA is defined as a basic type, represented as a 15-bit quantity
internally (stored in an int2)
CURRENCY is also defined as a basic type, which wraps the "numeric"
type and associates a TLA with it; the currency code.
CURRENCY_RATE is a defined lookup table; entries must be inserted into
it before any values can be constructed.
This contains:
currency_code: a three-letter currency code
description: an arbitrary text comment for the code
symbol: prefix for display purposes (may be NULL, in which case the
code is used as a suffix instead)
minor: for currencies which use a minor currency unit, the number of
decimal points between the major and the minor currency unit.
eg 2 for USD, EUR, 0 for currencies which don't use a minor
currency unit. For divisible, high unit value currencies
like gold etc, use 5 or higher.
rate: conversion rate to the neutral currency
is_exchange: boolean, set to 't' for the neutral currency - there
MUST be exactly ONE neutral currency.
Supported Operations
--------------------
The examples below assume that CURRENCY_RATE is pre-loaded with EUR
and NZD and that EUR has a symbol defined, but NZD doesn't.
Conversion to/from text returns any 'useless' precision present:
'100EUR'::currency = '100 EUR'
'-100EUR'::currency = '-100 EUR'
'+100.000EUR'::currency = '100.000 EUR'
Printing using relevant currency sign and precision:
format('100EUR'::currency) = '€ 100.00'
#'100EUR'::currency = '€ 100.00'
#'100NZD'::currency = 'NZD 100.00'
Get components out:
code('100EUR'::currency) = 'EUR'::tla
value('100EUR'::currency) = '100'::numeric
Valid ways to combine a currency code and a number:
currency(100, 'eur') = '100 EUR'
(100::text || 'EUR')::currency
Conversion to a particular currency:
'100EUR'::currency->'USD' = '132.40 USD'::currency
Conversion to the 'exchange' or 'neutral' currency, you can simply
cast as 'money';
'100EUR'::currency::money = '$600.00'::money
Otherwise, you have to use the 'particular currency' mechanism above.
Note that the 'money' type is limited to a 64-bit quantity of whatever
the smallest unit of currency is.
Comparisons between currency values are supported; they need not be of
the same currency type.
'100EUR'::currency > '100GBP'::currency
... ORDER BY my_currency_column;
Addition of units (assuming BTC as the 'exchange' currency, exchanging
at 4 BTC = 1 USD is used a neutral currency):
'100EUR'::currency + '10USD'::currency = '5997.19 BTC'::currency
Other math on currency units:
'100EUR'::currency - '10EUR'::currency = '90 EUR'::currency
'100EUR'::currency / 7 = '14.28 EUR'::currency
'14.28EUR'::currency * 7 = '99.96 EUR'::currency
'100EUR'::currency / 7 * 7 = '100.00 EUR'::currency (see below)
'100EUR'::currency / '10EUR' = 10::numeric
'100EUR'::currency + 10 => type error
'100EUR'::currency * '10EUR'::currency => type error
-'100EUR'::currency = '-100 EUR'::currency
+'100EUR'::currency = '100 EUR'::currency
Indexing
--------
To support queries which might join by or sort by currency values,
there are operator classes defined.
However, do not index currency values; the functions which back them
are not IMMUTABLE, so if you create indexes with them then those
indexes may not be able to retrieve your data or otherwise behave
bizarrely. Postgres should notice this and refuse to create the
index, but doesn't currently, so just beware.
Rounding
--------
All decisions on precision and suchlike are punted on and given to the
NUMERIC type underlying the values. To avoid lots of useless
precision, use the format() functions.
Copyright and License
---------------------
This contrib/ module is Copyright (c) 2010, 2011, Adioso Ltd. This
module is free software; you may use it under the same terms as
Postgres itself.