diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc0542..3419371 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # CHANGELOG +## Unreleased + +- Squirrel now uses the `gleam_time` time types for `time`, `date` and + `timestamp`s. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + +- Updated the `pog` dependency to `>= 4.0.0 and < 5.0.0`. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ## 3.1.0 - 2025-07-04 - You can now use the `PGCONNECT_TIMEOUT` variable to set the maximum time in diff --git a/README.md b/README.md index bf26967..ec47331 100644 --- a/README.md +++ b/README.md @@ -191,19 +191,19 @@ This is needed in two places: The types that are currently supported are: -| postgres type | encoded as | decoded as | -| ------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| `bool` | `Bool` | `Bool` | -| `text`, `char`, `bpchar`, `varchar` | `String` | `String` | -| `float4`, `float8`, `numeric` | `Float` | `Float` | -| `int2`, `int4`, `int8` | `Int` | `Int` | -| `json`, `jsonb` | [`Json`](https://hexdocs.pm/gleam_json/gleam/json.html#Json) | `String` | -| `uuid` | [`Uuid`](https://hexdocs.pm/youid/youid/uuid.html#Uuid) | [`Uuid`](https://hexdocs.pm/youid/youid/uuid.html#Uuid) | -| `bytea` | `BitArray` | `BitArray` | -| `date` | `#(Int, Int, Int)` with `#(year, month, day)` | `#(Int, Int, Int)` with `#(year, month, day)` | -| `timestamp` | `#(#(Int, Int, Int), (#(Int, Int, Int))` with `#(#(year, month, day), #(hour, minute, second))` | `#(#(Int, Int, Int), (#(Int, Int, Int))` with `#(#(year, month, day), #(hour, minute, second))` | -| `[]` (where `` is any supported type) | `List()` | `List()` | -| user-defined enum | [Gleam custom type](https://tour.gleam.run/data-types/custom-types/) | [Gleam custom type](https://tour.gleam.run/data-types/custom-types/) | +| postgres type | encoded as | decoded as | +| ------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| `bool` | `Bool` | `Bool` | +| `text`, `char`, `bpchar`, `varchar` | `String` | `String` | +| `float4`, `float8`, `numeric` | `Float` | `Float` | +| `int2`, `int4`, `int8` | `Int` | `Int` | +| `json`, `jsonb` | [`json.Json`](https://hexdocs.pm/gleam_json/gleam/json.html#Json) | `String` | +| `uuid` | [`uuid.Uuid`](https://hexdocs.pm/youid/youid/uuid.html#Uuid) | [`uuid.Uuid`](https://hexdocs.pm/youid/youid/uuid.html#Uuid) | +| `bytea` | `BitArray` | `BitArray` | +| `date` | [`calendar.Date`](https://hexdocs.pm/gleam_time/gleam/time/calendar.html#Date) | [`calendar.Date`](https://hexdocs.pm/gleam_time/gleam/time/calendar.html#Date) | +| `timestamp` | [`timestamp.Timestamp`](https://hexdocs.pm/gleam_time/gleam/time/timestamp.html#Timestamp) | [`timestamp.Timestamp`](https://hexdocs.pm/gleam_time/gleam/time/timestamp.html#Timestamp) | +| `[]` (where `` is any supported type) | `List()` | `List()` | +| user-defined enum | [Gleam custom type](https://tour.gleam.run/data-types/custom-types/) | [Gleam custom type](https://tour.gleam.run/data-types/custom-types/) | ### Enums diff --git a/birdie_snapshots/date_decoding.accepted b/birdie_snapshots/date_decoding.accepted index 51f8a08..7dea757 100644 --- a/birdie_snapshots/date_decoding.accepted +++ b/birdie_snapshots/date_decoding.accepted @@ -1,10 +1,11 @@ --- -version: 1.3.0 +version: 1.3.1 title: date decoding file: ./test/squirrel_test.gleam test_name: date_decoding_test --- import gleam/dynamic/decode +import gleam/time/calendar.{type Date} import pog /// A row you get from running the `query` query @@ -14,7 +15,7 @@ import pog /// > [squirrel package](https://github.com/giacomocavalieri/squirrel). /// pub type QueryRow { - QueryRow(res: pog.Date) + QueryRow(res: Date) } /// Runs the `query` query @@ -25,7 +26,7 @@ pub type QueryRow { /// pub fn query(db) { let decoder = { - use res <- decode.field(0, pog.date_decoder()) + use res <- decode.field(0, pog.calendar_date_decoder()) decode.success(QueryRow(res:)) } diff --git a/birdie_snapshots/date_encoding.accepted b/birdie_snapshots/date_encoding.accepted index 81a802c..58bd39e 100644 --- a/birdie_snapshots/date_encoding.accepted +++ b/birdie_snapshots/date_encoding.accepted @@ -1,5 +1,5 @@ --- -version: 1.3.0 +version: 1.3.1 title: date encoding file: ./test/squirrel_test.gleam test_name: date_encoding_test @@ -31,7 +31,7 @@ pub fn query(db, arg_1) { "select true as res where $1 = 'Jan-2-1970'::date" |> pog.query - |> pog.parameter(pog.date(arg_1)) + |> pog.parameter(pog.calendar_date(arg_1)) |> pog.returning(decoder) |> pog.execute(db) } diff --git a/birdie_snapshots/query_that_needs_more_than_a_single_helper_function.accepted b/birdie_snapshots/query_that_needs_more_than_a_single_helper_function.accepted index d5bd83c..2e6484c 100644 --- a/birdie_snapshots/query_that_needs_more_than_a_single_helper_function.accepted +++ b/birdie_snapshots/query_that_needs_more_than_a_single_helper_function.accepted @@ -1,10 +1,11 @@ --- -version: 1.3.0 +version: 1.3.1 title: query that needs more than a single helper function file: ./test/squirrel_test.gleam test_name: query_that_needs_more_than_a_single_helper_function_test --- import gleam/dynamic/decode +import gleam/time/calendar.{type Date} import pog import youid/uuid.{type Uuid} @@ -15,7 +16,7 @@ import youid/uuid.{type Uuid} /// > [squirrel package](https://github.com/giacomocavalieri/squirrel). /// pub type QueryRow { - QueryRow(gen_random_uuid: Uuid, date: pog.Date) + QueryRow(gen_random_uuid: Uuid, date: Date) } /// Runs the `query` query @@ -27,7 +28,7 @@ pub type QueryRow { pub fn query(db) { let decoder = { use gen_random_uuid <- decode.field(0, uuid_decoder()) - use date <- decode.field(1, pog.date_decoder()) + use date <- decode.field(1, pog.calendar_date_decoder()) decode.success(QueryRow(gen_random_uuid:, date:)) } diff --git a/birdie_snapshots/query_that_needs_utils_and_enums_has_two_sections.accepted b/birdie_snapshots/query_that_needs_utils_and_enums_has_two_sections.accepted index 6a73562..65c4ec4 100644 --- a/birdie_snapshots/query_that_needs_utils_and_enums_has_two_sections.accepted +++ b/birdie_snapshots/query_that_needs_utils_and_enums_has_two_sections.accepted @@ -1,10 +1,11 @@ --- -version: 1.3.0 +version: 1.3.1 title: query that needs utils and enums has two sections file: ./test/squirrel_test.gleam test_name: query_that_needs_utils_and_enums_has_two_sections_test --- import gleam/dynamic/decode +import gleam/time/calendar.{type Date} import pog /// A row you get from running the `query` query @@ -14,7 +15,7 @@ import pog /// > [squirrel package](https://github.com/giacomocavalieri/squirrel). /// pub type QueryRow { - QueryRow(squirrel_colour: SquirrelColour, date: pog.Date) + QueryRow(squirrel_colour: SquirrelColour, date: Date) } /// Runs the `query` query @@ -26,7 +27,7 @@ pub type QueryRow { pub fn query(db) { let decoder = { use squirrel_colour <- decode.field(0, squirrel_colour_decoder()) - use date <- decode.field(1, pog.date_decoder()) + use date <- decode.field(1, pog.calendar_date_decoder()) decode.success(QueryRow(squirrel_colour:, date:)) } diff --git a/birdie_snapshots/timestamp_decoding.accepted b/birdie_snapshots/timestamp_decoding.accepted index cf5fc4b..4ba5bfb 100644 --- a/birdie_snapshots/timestamp_decoding.accepted +++ b/birdie_snapshots/timestamp_decoding.accepted @@ -1,10 +1,11 @@ --- -version: 1.3.0 +version: 1.3.1 title: timestamp decoding file: ./test/squirrel_test.gleam test_name: timestamp_decoding_test --- import gleam/dynamic/decode +import gleam/time/timestamp.{type Timestamp} import pog /// A row you get from running the `query` query @@ -14,7 +15,7 @@ import pog /// > [squirrel package](https://github.com/giacomocavalieri/squirrel). /// pub type QueryRow { - QueryRow(res: pog.Timestamp) + QueryRow(res: Timestamp) } /// Runs the `query` query diff --git a/gleam.toml b/gleam.toml index 833f2b7..c5bb359 100644 --- a/gleam.toml +++ b/gleam.toml @@ -18,7 +18,6 @@ gleam_regexp = ">= 1.0.0 and < 2.0.0" gleam_stdlib = ">= 0.51.0 and < 2.0.0" justin = ">= 1.0.1 and < 2.0.0" non_empty_list = ">= 2.1.0 and < 3.0.0" -pog = ">= 3.1.0 and < 4.0.0" simplifile = ">= 2.0.1 and < 3.0.0" term_size = ">= 1.0.1 and < 2.0.0" tom = ">= 2.0.0 and < 3.0.0" @@ -26,6 +25,8 @@ tote = ">= 1.0.2 and < 2.0.0" youid = ">= 1.2.0 and < 2.0.0" glexer = ">= 2.1.0 and < 3.0.0" mug = ">= 3.0.0 and < 4.0.0" +pog = ">= 4.0.0 and < 5.0.0" +gleam_time = ">= 1.2.0 and < 2.0.0" [dev-dependencies] birdie = ">= 1.1.8 and < 2.0.0" diff --git a/manifest.toml b/manifest.toml index 47c6450..a2f0d62 100644 --- a/manifest.toml +++ b/manifest.toml @@ -8,7 +8,7 @@ packages = [ { name = "edit_distance", version = "2.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "edit_distance", source = "hex", outer_checksum = "A1E485C69A70210223E46E63985FA1008B8B2DDA9848B7897469171B29020C05" }, { name = "envoy", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "envoy", source = "hex", outer_checksum = "95FD059345AA982E89A0B6E2A3BF1CF43E17A7048DCD85B5B65D3B9E4E39D359" }, { name = "eval", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "eval", source = "hex", outer_checksum = "264DAF4B49DF807F303CA4A4E4EBC012070429E40BE384C58FE094C4958F9BDA" }, - { name = "exception", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "F5580D584F16A20B7FCDCABF9E9BE9A2C1F6AC4F9176FA6DD0B63E3B20D450AA" }, + { name = "exception", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "329D269D5C2A314F7364BD2711372B6F2C58FA6F39981572E5CA68624D291F8C" }, { name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" }, { name = "glam", version = "2.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glam", source = "hex", outer_checksum = "4932A2D139AB0389E149396407F89654928D7B815E212BB02F13C66F53B1BBA1" }, { name = "glance", version = "5.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "FAA3DAC74AF71D47C67D88EB32CE629075169F878D148BB1FF225439BE30070A" }, @@ -17,6 +17,7 @@ packages = [ { name = "gleam_crypto", version = "1.5.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "50774BAFFF1144E7872814C566C5D653D83A3EBF23ACC3156B757A1B6819086E" }, { name = "gleam_erlang", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "F91CE62A2D011FA13341F3723DB7DB118541AAA5FE7311BD2716D018F01EF9E3" }, { name = "gleam_json", version = "3.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "874FA3C3BB6E22DD2BB111966BD40B3759E9094E05257899A7C08F5DE77EC049" }, + { name = "gleam_otp", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "7020E652D18F9ABAC9C877270B14160519FA0856EE80126231C505D719AD68DA" }, { name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" }, { name = "gleam_stdlib", version = "0.61.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3DC407D6EDA98FCE089150C11F3AD892B6F4C3CA77C87A97BAE8D5AB5E41F331" }, { name = "gleam_time", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_time", source = "hex", outer_checksum = "D71F1AFF7FEB534FF55E5DC58E534E9201BA75A444619788A2E4DEA4EBD87D16" }, @@ -26,9 +27,9 @@ packages = [ { name = "mug", version = "3.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "mug", source = "hex", outer_checksum = "49AD2B71690C6A615453D272300951C4BDE19FBF55B167D9C951F5CD89FEC820" }, { name = "non_empty_list", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "non_empty_list", source = "hex", outer_checksum = "3BF1496B475F3F2CE2EA18157587329812493369B2A7C5B9DCFEA5C007670A3B" }, { name = "opentelemetry_api", version = "1.4.0", build_tools = ["rebar3", "mix"], requirements = [], otp_app = "opentelemetry_api", source = "hex", outer_checksum = "3DFBBFAA2C2ED3121C5C483162836C4F9027DEF469C41578AF5EF32589FCFC58" }, - { name = "pg_types", version = "0.4.0", build_tools = ["rebar3"], requirements = [], otp_app = "pg_types", source = "hex", outer_checksum = "B02EFA785CAECECF9702C681C80A9CA12A39F9161A846CE17B01FB20AEEED7EB" }, - { name = "pgo", version = "0.14.0", build_tools = ["rebar3"], requirements = ["backoff", "opentelemetry_api", "pg_types"], otp_app = "pgo", source = "hex", outer_checksum = "71016C22599936E042DC0012EE4589D24C71427D266292F775EBF201D97DF9C9" }, - { name = "pog", version = "3.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "pgo"], otp_app = "pog", source = "hex", outer_checksum = "35CBBE8F844DE9E5676CF306CDE2BD98AA6A25920D2EBE771FD5A293EB454161" }, + { name = "pg_types", version = "0.5.0", build_tools = ["rebar3"], requirements = [], otp_app = "pg_types", source = "hex", outer_checksum = "A3023B464AA960BC1628635081E30CCA4F676F2D4C23CCD6179C1C11C9B4A642" }, + { name = "pgo", version = "0.15.0", build_tools = ["rebar3"], requirements = ["backoff", "opentelemetry_api", "pg_types"], otp_app = "pgo", source = "hex", outer_checksum = "4B883D751B8D4247F4D8A6FBAE58EDB6FA9DBC183371299BF84975EE36406388" }, + { name = "pog", version = "4.0.0", build_tools = ["gleam"], requirements = ["exception", "gleam_erlang", "gleam_otp", "gleam_stdlib", "gleam_time", "pgo"], otp_app = "pog", source = "hex", outer_checksum = "E495AAD2C4FD0BB3A92C505682705FA2460053B2D3ABC6F9024C3FED6868417D" }, { name = "rank", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "rank", source = "hex", outer_checksum = "5660E361F0E49CBB714CC57CC4C89C63415D8986F05B2DA0C719D5642FAD91C9" }, { name = "shellout", version = "1.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "shellout", source = "hex", outer_checksum = "1BDC03438FEB97A6AF3E396F4ABEB32BECF20DF2452EC9A8C0ACEB7BDDF70B14" }, { name = "simplifile", version = "2.3.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0A868DAC6063D9E983477981839810DC2E553285AB4588B87E3E9C96A7FB4CB4" }, @@ -53,12 +54,13 @@ gleam_erlang = { version = ">= 1.0.0 and < 2.0.0" } gleam_json = { version = ">= 1.0.0 and < 4.0.0" } gleam_regexp = { version = ">= 1.0.0 and < 2.0.0" } gleam_stdlib = { version = ">= 0.51.0 and < 2.0.0" } +gleam_time = { version = ">= 1.2.0 and < 2.0.0" } gleeunit = { version = ">= 1.0.0 and < 2.0.0" } glexer = { version = ">= 2.1.0 and < 3.0.0" } justin = { version = ">= 1.0.1 and < 2.0.0" } mug = { version = ">= 3.0.0 and < 4.0.0" } non_empty_list = { version = ">= 2.1.0 and < 3.0.0" } -pog = { version = ">= 3.1.0 and < 4.0.0" } +pog = { version = ">= 4.0.0 and < 5.0.0" } shellout = { version = ">= 1.6.0 and < 2.0.0" } simplifile = { version = ">= 2.0.1 and < 3.0.0" } temporary = { version = ">= 1.0.0 and < 2.0.0" } diff --git a/src/squirrel/internal/query.gleam b/src/squirrel/internal/query.gleam index 01913fa..5110d40 100644 --- a/src/squirrel/internal/query.gleam +++ b/src/squirrel/internal/query.gleam @@ -234,7 +234,7 @@ fn gleam_type_to_decoder( let #(state, inner_decoder) = gleam_type_to_decoder(state, type_) #(state, call_doc("decode.optional", [inner_decoder])) } - gleam.Date -> #(state, doc.from_string("pog.date_decoder()")) + gleam.Date -> #(state, doc.from_string("pog.calendar_date_decoder()")) gleam.Timestamp -> #(state, doc.from_string("pog.timestamp_decoder()")) gleam.Int -> #(state, doc.from_string("decode.int")) gleam.Float -> #(state, doc.from_string("decode.float")) @@ -284,7 +284,7 @@ fn gleam_type_to_encoder( let doc = call_doc("pog.text", [call_doc("json.to_string", [name])]) #(state, doc) } - gleam.Date -> #(state, call_doc("pog.date", [name])) + gleam.Date -> #(state, call_doc("pog.calendar_date", [name])) gleam.Timestamp -> #(state, call_doc("pog.timestamp", [name])) gleam.Int -> #(state, call_doc("pog.int", [name])) gleam.Float -> #(state, call_doc("pog.float", [name])) @@ -322,8 +322,15 @@ fn gleam_type_to_field_type( state |> import_qualified("youid/uuid", "type Uuid"), doc.from_string("Uuid"), ) - gleam.Date -> #(state, doc.from_string("pog.Date")) - gleam.Timestamp -> #(state, doc.from_string("pog.Timestamp")) + gleam.Date -> { + let state = state |> import_qualified("gleam/time/calendar", "type Date") + #(state, doc.from_string("Date")) + } + gleam.Timestamp -> { + let state = + state |> import_qualified("gleam/time/timestamp", "type Timestamp") + #(state, doc.from_string("Timestamp")) + } gleam.Int -> #(state, doc.from_string("Int")) gleam.Float -> #(state, doc.from_string("Float")) gleam.Bool -> #(state, doc.from_string("Bool")) diff --git a/test/integration_test.gleam b/test/integration_test.gleam index df59e00..515526b 100644 --- a/test/integration_test.gleam +++ b/test/integration_test.gleam @@ -67,12 +67,9 @@ const integration_tests = [ // Bytea TestType("bytea", [TestValue("<<1, 2, 3>>")]), // Date - TestType("date", [TestValue("pog.Date(1998, 10, 11)")]), + TestType("date", [TestValue("calendar.Date(1998, calendar.October, 11)")]), // Timestamp - TestType( - "timestamp", - [TestValue("pog.Timestamp(pog.Date(1998, 10, 11), pog.Time(22, 10, 0, 0))")], - ), + TestType("timestamp", [TestValue("timestamp.from_unix_seconds(1000)")]), // Array TestType("int[]", [TestValue("[1, 2, 3]")]), TestType("squirrel_colour[]", [TestValue("[sql.Red, sql.Grey]")]), @@ -274,23 +271,28 @@ let assert Ok(pog.Returned(1, [])) = sql.(db) /// fn write_main(assertions: String, to dir: String) -> Nil { let main = " +import gleam/erlang/process import gleam/io +import gleam/json import gleam/string +import gleam/time/calendar +import gleam/time/timestamp import pog -import gleam/json -import youid/uuid import sql +import youid/uuid pub fn main() { -let config = - pog.Config( - ..pog.default_config(), - port: 5432, - user: \"squirrel_test\", - host: \"localhost\", - database: \"squirrel_test\", - ) -let db = pog.connect(config) + let name = process.new_name(\"test\") + let config = + pog.Config( + ..pog.default_config(name), + port: 5432, + user: \"squirrel_test\", + host: \"localhost\", + database: \"squirrel_test\", + ) + let assert Ok(actor) = pog.start(config) + let db = actor.data " <> assertions <> " }" diff --git a/test/squirrel_test.gleam b/test/squirrel_test.gleam index d90cc9b..b8c9695 100644 --- a/test/squirrel_test.gleam +++ b/test/squirrel_test.gleam @@ -1,6 +1,7 @@ import birdie import filepath import glam/doc +import gleam/erlang/process import gleam/list import gleam/string import gleeunit @@ -28,7 +29,9 @@ const database = "squirrel_test" const port = 5432 pub fn test_config() -> pog.Config { - pog.default_config() + let name = process.new_name("test") + + pog.default_config(name) |> pog.port(port) |> pog.user(user) |> pog.host(host) @@ -36,7 +39,8 @@ pub fn test_config() -> pog.Config { } fn setup_database() { - let db = pog.connect(test_config()) + let assert Ok(actor) = pog.start(test_config()) + let db = actor.data let assert Ok(_) = " @@ -176,7 +180,7 @@ create table if not exists items_categories_issue75 ( |> pog.query |> pog.execute(db) - pog.disconnect(db) + Nil } // --- ASSERTION HELPERS -------------------------------------------------------