Comments (9)
Documented go-cmp and pgx integration in 7535b54.
The next step will be to create a separate section for database integration, with integration notes for mysql (decimal column) and sqlite (int column). The int approach has been made possible by e18a432, since there are now methods for both getting the amount as an integer, and creating an amount from an integer.
from currency.
Thanks! Mentioning go-cmp somewhere would indeed be good.
What are the benefits of trying to use BinaryMarshaler for db storage?
My assumption was that anyone storing amounts in the database would use separate decimal and char fields for the number and currency_code. The binary marshal was implemented for exchange on the wire (e.g. the gob package).
I believe that if the format was reversed ("9.99USD" instead of "USD9.99") then MySQL could cast the value into a number for ordering, but I haven't explored the performance of that, nor how it would work in Postgres.
from currency.
The idea is that not all databases support decimal in a portable way, AFAIK (maybe they now do ? it wasn't implemented in a portable way some years ago in SQL engines, even less in NoSQL): providing a string representation allows the type to be stored to just about anything without having to implement application-level mapping.
Using BinaryMarshaler for this is just a really simple way to do it, no special interest in it.
from currency.
The decimal type is a part of the SQL standard, and it's currently supported by all databases that I checked, so it's safe to recommend.
For cases where a decimal type is not available, there are two solid options:
- Store the number as an integer, in minor units (a.ToMinorUnits()). We currently don't have a helper for creating an amount from an integer. That is being fixed in PR #7.
- Store the number as a string (a.Number()), if we need larger precision than the number of minor units (e.g. > 2 decimals for EUR, USD). Many systems have a way of sorting a string numerically.
This means that for proper sorting in any system, the primary thing to do is store the number and the currency code separately. Which means that we can probably keep the binary format as-is, but document storage recommendations. How does that sound?
from currency.
Hadn't realized that Decimal was now usable across engines, so it is indeed enough to document it. Better have better doc than more code, I think.
Just to explain how this issue came: when drafting a homework subject for my students using monetary amounts, I wondered, thinking about how they'd have to store these data: "ok so we have currency.NewAmount" to create an Amount from a string. Now, what is the inverse function generating the same string I can pass to NewAmount again to obtain an identity when they get the result from the DB ?"
from currency.
Yeah, that's a valid question, it's not obvious at all. I'll see what I can come up with for the README
from currency.
BTW, I double checked, and AIUI SQLite does not actually support DECIMAL: it only pretends to, by mapping it to its NUMERIC type, which uses a float if the value is not an integer. That's really something currencies want to avoid.
from currency.
Haven't forgotten about this. In the meantime, opened #9 to improve DX for Postgres users.
from currency.
Database integration notes are now complete at https://github.com/bojanz/currency/wiki/Database-integration-notes
The SQLite section can be expanded with actual examples if someone's in the mood to give us an example schema.
from currency.
Related Issues (20)
- Tag v1.0.0 HOT 1
- IsValid() should consider empty values valid
- Handle minor amount values HOT 3
- Amount should implement driver.Valuer and sql.Scanner interfaces
- The calculation precision (16) is sometimes not enough
- Formatter uses wrong symbol after locale fallback HOT 3
- NoSql Support HOT 3
- allow more uses of the zero value HOT 3
- support banker's rounding HOT 2
- Optimized version of roundingContext is wrong HOT 2
- unsupported type []unit8 with pq driver HOT 2
- Introduce currency.ForCountryCode() for getting a country's currency HOT 4
- Number() gives exponent formatting sometimes HOT 3
- Add support for the accounting formatter style (negative amounts in parenthesis) HOT 4
- Negative currency converted to `BigInt` becomes positive HOT 3
- Why does this code work? What is the purpose of Locale? HOT 2
- Why does this invalid price not give an error? HOT 1
- Rework locale data filtering (-modern is going away)
- Support `pq` driver HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from currency.