diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f0fe8d..a1778e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -## v4.0.0 - Unreleased +## Unreleased + +- Added a `numeric_decoder` to decode numeric types coming from postgres. + +## v4.0.0 - 2025-07-07 - Starting a pool no longer generates an atom, instead a name is taken as an argument. diff --git a/src/pog.gleam b/src/pog.gleam index 11f35fe..b15f9a2 100644 --- a/src/pog.gleam +++ b/src/pog.gleam @@ -904,3 +904,7 @@ fn seconds_decoder() -> decode.Decoder(#(Int, Int)) { } decode.one_of(int, [float]) } + +pub fn numeric_decoder() -> decode.Decoder(Float) { + decode.one_of(decode.float, [decode.int |> decode.map(int.to_float)]) +} diff --git a/test/pog_test.gleam b/test/pog_test.gleam index 728ec0e..3a6f7ad 100644 --- a/test/pog_test.gleam +++ b/test/pog_test.gleam @@ -333,6 +333,27 @@ pub fn float_test() { |> disconnect } +pub fn numeric_test() { + let db = + start_default() + |> assert_roundtrip(0.0, "numeric", pog.float, pog.numeric_decoder()) + |> assert_roundtrip(10.0, "numeric", pog.float, pog.numeric_decoder()) + |> assert_roundtrip(1.1, "numeric", pog.float, pog.numeric_decoder()) + |> assert_roundtrip(1.0, "numeric", pog.float, pog.numeric_decoder()) + + assert pog.query("select 1::numeric") + |> pog.returning(decode.at([0], pog.numeric_decoder())) + |> pog.execute(db.data) + == Ok(pog.Returned(count: 1, rows: [1.0])) + + assert pog.query("select 0::numeric") + |> pog.returning(decode.at([0], pog.numeric_decoder())) + |> pog.execute(db.data) + == Ok(pog.Returned(count: 1, rows: [0.0])) + + disconnect(db) +} + pub fn text_test() { start_default() |> assert_roundtrip("", "text", pog.text, decode.string)