Skip to content

Commit

Permalink
Break out a new pgx_value_core module
Browse files Browse the repository at this point in the history
This will let people using the Lwt or Unix backends still
have access to the Core_kernel.{Date,Time} converters.

See #73
  • Loading branch information
brendanlong committed Apr 27, 2020
1 parent 66596db commit e87e43e
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
name: Pin packages
command: |
for p in *.opam; do
opam pin add -y -n ${p%.opam} .
opam pin add -y -n ${p%.opam}.~dev .
done
- run:
name: Install system dependencies
Expand Down
2 changes: 1 addition & 1 deletion pgx_async/src/dune
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ let () = Jbuild_plugin.V1.send @@ {|
(library
(public_name pgx_async)
(wrapped false)
(libraries pgx async)
(libraries async pgx_value_core)
|} ^ preprocess ^ {|)
|}
65 changes: 1 addition & 64 deletions pgx_async/src/pgx_async.ml
Original file line number Diff line number Diff line change
Expand Up @@ -186,67 +186,4 @@ let execute_pipe ?params db query =
execute_iter ?params db query ~f:(fun row -> Pipe.write_if_open writer row)
;;

module Value = struct
include Pgx.Value

let of_time t =
(*
Postgres behaves differently depending on whether the timestamp data type
includes the timezone or not:
Without timezone all inserted timezones are ignored
2016-06-07 15:37:46 (no timezone)
2016-06-07 15:37:46Z (utc timezone)
2016-06-07 15:37:46-04 (local timezone)
Get inserted as
2016-06-07 15:37:46
With timezones:
2016-06-07 15:37:46 (no timezone) -> 2016-06-07 15:37:46-04
2016-06-07 15:37:46Z (utc timezone) -> 2016-06-07 11:37:46-04
2016-06-07 15:37:46-04 (local timezone) -> 2016-06-07 15:37:46-04
*)
Some (Time.to_string_abs ~zone:Time.Zone.utc t)
;;

let to_time' =
(*
The time string can come in various forms depending on whether the
Postgres timestamp used includes the time zone:
Without timezone
2016-06-07 15:37:46
2016-06-07 15:37:46.962425
With timezone
2016-06-07 15:37:46-04
2016-06-07 15:37:46.962425-04
For the first one we need to indicate that it's a UTC time by appending
a 'Z'. For the second one we need to append the minutes to the timezone.
Without these formattings Time.of_string fails spectacularly
*)
let open Re in
let tz = seq [ alt [ char '-'; char '+' ]; digit; digit ] in
let utctz = seq [ char 'Z'; eol ] |> compile in
let localtz_no_min = seq [ tz; eol ] |> compile in
let localtz = seq [ tz; char ':'; digit; digit; eol ] |> compile in
fun s ->
Time.of_string
@@
match matches utctz s, matches localtz s, matches localtz_no_min s with
| [], [], [] -> s ^ "Z"
| _, [], [] -> s
| [], _, [] -> s
| [], [], _ -> s ^ ":00"
(* It either finishes in one of the patterns above or it doesn't *)
| _ -> convert_failure "time" s
;;

let to_time_exn = required to_time'
let to_time = Option.map ~f:to_time'
let of_date d = Some (Date.to_string d)
let to_date' = Date.of_string
let to_date_exn = required to_date'
let to_date = Option.map ~f:to_date'
end
module Value = Pgx_value_core
15 changes: 3 additions & 12 deletions pgx_async/src/pgx_async.mli
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
(** Async based Postgres client based on Pgx. *)
open Core

open Async

include Pgx.S with type 'a monad = 'a Deferred.t

(* for testing purposes *)
Expand All @@ -24,13 +23,5 @@ val with_conn
as much overhead. *)
val execute_pipe : ?params:Pgx.row -> t -> string -> Pgx.row Pipe.Reader.t

module Value : sig
include Pgx_value_intf.S

val of_date : Date.t -> t
val to_date_exn : t -> Date.t
val to_date : t -> Date.t option
val of_time : Time.t -> t
val to_time_exn : t -> Time.t
val to_time : t -> Time.t option
end
(** Exposed for backwards compatiblity. New code should use [Pgx_value_core] directly. *)
module Value = Pgx_value_core
2 changes: 1 addition & 1 deletion pgx_async/test/dune
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
(tests
(names test_pgx_async test_pgx_async_conversions)
(names test_pgx_async)
(libraries alcotest alcotest-async pgx_async pgx_test))
1 change: 1 addition & 0 deletions pgx_value_core.descr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pgx_value converters for Core types like Date and Time
20 changes: 20 additions & 0 deletions pgx_value_core.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
opam-version: "2.0"
authors: ["Arena Developers <silver-snakes@arena.io>"]
maintainer: "Arena Developers <silver-snakes@arena.io>"
homepage: "https://github.com/arenadotio/pgx"
dev-repo: "git+https://github.com/arenadotio/pgx.git"
bug-reports: "https://github.com/arenadotio/pgx/issues"
doc: "https://arenadotio.github.io/pgx/doc"

build: [
["dune" "build" "-p" name "-j" jobs]
["dune" "runtest" "-p" name "-j" jobs] {with-test}
]

depends: [
"core_kernel" {>= "v0.13.0"}
"pgx" {= version}

"alcotest" {with-test & >= "1.0.0"}
"base64" {with-test & >= "3.0.0"}
]
15 changes: 15 additions & 0 deletions pgx_value_core/src/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(* -*- tuareg -*- *)

let preprocess =
match Sys.getenv "BISECT_ENABLE" with
| "yes" -> "(preprocess (pps bisect_ppx))"
| _ -> ""
| exception Not_found -> ""

let () = Jbuild_plugin.V1.send @@ {|

(library
(public_name pgx_value_core)
(libraries core_kernel pgx)
|} ^ preprocess ^ {|)
|}
63 changes: 63 additions & 0 deletions pgx_value_core/src/pgx_value_core.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
open Core_kernel
include Pgx.Value

let of_time t =
(*
Postgres behaves differently depending on whether the timestamp data type
includes the timezone or not:
Without timezone all inserted timezones are ignored
2016-06-07 15:37:46 (no timezone)
2016-06-07 15:37:46Z (utc timezone)
2016-06-07 15:37:46-04 (local timezone)
Get inserted as
2016-06-07 15:37:46
With timezones:
2016-06-07 15:37:46 (no timezone) -> 2016-06-07 15:37:46-04
2016-06-07 15:37:46Z (utc timezone) -> 2016-06-07 11:37:46-04
2016-06-07 15:37:46-04 (local timezone) -> 2016-06-07 15:37:46-04
*)
Some (Time.to_string_abs ~zone:Time.Zone.utc t)
;;

let to_time' =
(*
The time string can come in various forms depending on whether the
Postgres timestamp used includes the time zone:
Without timezone
2016-06-07 15:37:46
2016-06-07 15:37:46.962425
With timezone
2016-06-07 15:37:46-04
2016-06-07 15:37:46.962425-04
For the first one we need to indicate that it's a UTC time by appending
a 'Z'. For the second one we need to append the minutes to the timezone.
Without these formattings Time.of_string fails spectacularly
*)
let open Re in
let tz = seq [ alt [ char '-'; char '+' ]; digit; digit ] in
let utctz = seq [ char 'Z'; eol ] |> compile in
let localtz_no_min = seq [ tz; eol ] |> compile in
let localtz = seq [ tz; char ':'; digit; digit; eol ] |> compile in
fun s ->
Time.of_string
@@
match matches utctz s, matches localtz s, matches localtz_no_min s with
| [], [], [] -> s ^ "Z"
| _, [], [] -> s
| [], _, [] -> s
| [], [], _ -> s ^ ":00"
(* It either finishes in one of the patterns above or it doesn't *)
| _ -> convert_failure "time" s
;;

let to_time_exn = required to_time'
let to_time = Option.map ~f:to_time'
let of_date d = Some (Date.to_string d)
let to_date' = Date.of_string
let to_date_exn = required to_date'
let to_date = Option.map ~f:to_date'
11 changes: 11 additions & 0 deletions pgx_value_core/src/pgx_value_core.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(** Pgx_value types using Core_kernel's Date and Time modules *)
open Core_kernel

include Pgx_value_intf.S

val of_date : Date.t -> t
val to_date_exn : t -> Date.t
val to_date : t -> Date.t option
val of_time : Time.t -> t
val to_time_exn : t -> Time.t
val to_time : t -> Time.t option
3 changes: 3 additions & 0 deletions pgx_value_core/test/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(tests
(names test_pgx_value_core)
(libraries alcotest pgx_value_core))
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
open Core
module Value = Pgx_async.Value
open Core_kernel
module Value = Pgx_value_core

let time_roundtrip str = Value.to_time_exn (Some str)
let printer = Time.to_string_abs ~zone:Time.Zone.utc
Expand Down

0 comments on commit e87e43e

Please sign in to comment.