Skip to content

Commit d8ae224

Browse files
The goal of the patch is to enable the use of non-blocking
connections, to make async integration easier. To that end, we made the following changes: - For putline, putnbytes and endcopy, don't throw exceptions on non-blocking connections. - Return meaningful status code from flush Also, we added a binding for the server_version call. Written by Max Wolter
1 parent 36cf1d3 commit d8ae224

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

lib/postgresql.ml

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ type polling_status =
254254
| Polling_writing
255255
| Polling_ok
256256

257+
type flush_status =
258+
| Successful
259+
| Data_left_to_send
260+
257261
type conninfo_option =
258262
{
259263
cio_keyword : string;
@@ -340,7 +344,7 @@ module Stub = struct
340344

341345
external error_message : connection -> string = "PQerrorMessage_stub"
342346
external backend_pid : connection -> int = "PQbackendPID_stub" "noalloc"
343-
347+
external server_version : connection -> int = "PQserverVersion_stub" "noalloc"
344348

345349
(* Command Execution Functions *)
346350

@@ -773,6 +777,20 @@ object (self)
773777
method status = wrap_conn Stub.connection_status
774778
method error_message = wrap_conn Stub.error_message
775779
method backend_pid = wrap_conn Stub.backend_pid
780+
method server_version = wrap_conn (fun conn ->
781+
let v = Stub.server_version conn in
782+
if v = 0 then begin
783+
let message = if Stub.connection_status conn = Bad
784+
then "server_version failed because the connection was bad"
785+
else "server_version failed for an unknown reason"
786+
in
787+
raise (Error (Connection_failure message))
788+
end;
789+
let revision = v mod 100 in
790+
let minor = (v / 100) mod 100 in
791+
let major = v / (100 * 100) in
792+
major, minor, revision
793+
)
776794

777795

778796
(* Commands and Queries *)
@@ -882,18 +900,26 @@ object (self)
882900
| _ -> assert false)
883901

884902
method putline buf =
885-
wrap_conn (fun conn -> if Stub.putline conn buf <> 0 then signal_error conn)
903+
wrap_conn (fun conn ->
904+
if (Stub.putline conn buf <> 0) && not (Stub.is_nonblocking conn) then
905+
signal_error conn
906+
)
886907

887908
method putnbytes ?(pos = 0) ?len buf =
888909
let buf_len = String.length buf in
889910
let len = match len with Some len -> len | None -> buf_len - pos in
890911
if len < 0 || pos < 0 || pos + len > buf_len then
891912
invalid_arg "Postgresql.connection#putnbytes";
892913
wrap_conn (fun conn ->
893-
if Stub.putnbytes conn buf pos len <> 0 then signal_error conn)
914+
if (Stub.putnbytes conn buf pos len <> 0) && not (Stub.is_nonblocking conn) then
915+
signal_error conn
916+
)
894917

895918
method endcopy =
896-
wrap_conn (fun conn -> if Stub.endcopy conn <> 0 then signal_error conn)
919+
wrap_conn (fun conn ->
920+
if (Stub.endcopy conn <> 0) && not (Stub.is_nonblocking conn) then
921+
signal_error conn
922+
)
897923

898924

899925
(* High level *)
@@ -948,7 +974,12 @@ object (self)
948974
method is_busy = wrap_conn Stub.is_busy
949975

950976
method flush =
951-
wrap_conn (fun conn -> if Stub.flush conn <> 0 then signal_error conn)
977+
wrap_conn (fun conn ->
978+
match Stub.flush conn with
979+
| 0 -> Successful
980+
| 1 -> Data_left_to_send
981+
| _ -> signal_error conn
982+
)
952983

953984
method socket =
954985
wrap_conn (fun conn ->

lib/postgresql.mli

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,11 @@ type polling_status =
380380
| Polling_writing
381381
| Polling_ok
382382

383+
(** Result of a call to flush on nonblocking connections. *)
384+
type flush_status =
385+
| Successful
386+
| Data_left_to_send
387+
383388
(** Record of connection options *)
384389
type conninfo_option =
385390
{
@@ -526,6 +531,7 @@ object
526531
@raise Error if there is a connection error.
527532
*)
528533

534+
method server_version : int * int * int (* major, minor, revision *)
529535

530536
(** Commands and Queries *)
531537

@@ -801,7 +807,7 @@ object
801807
@raise Error if there is a connection error.
802808
*)
803809

804-
method flush : unit
810+
method flush : flush_status
805811
(** [flush] attempts to flush any data queued to the backend.
806812
807813
@raise Error if there is a connection error.

lib/postgresql_stubs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ conn_info(PQoptions, make_string)
369369
noalloc_conn_info(PQstatus, Val_int)
370370
conn_info(PQerrorMessage, make_string)
371371
noalloc_conn_info(PQbackendPID, Val_int)
372-
372+
noalloc_conn_info(PQserverVersion, Val_int)
373373

374374
/* Command Execution Functions */
375375

0 commit comments

Comments
 (0)