Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file postgres_async_intf.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156open!CoreopenAsyncmoduletypeS=sigtypecolumn_metadatatypessl_mode(** In order to provide an [Expert] interface that uses [Pgasync_error.t] to represent
its errors, alongside a normal interface that just uses Core's [Error.t], the
interface is defined in this [module type S], with a type [error] that we erase when
we include it in [postgres_async.mli]. *)typeerrortypet[@@derivingsexp_of](** [gss_krb_token] will be sent in response to a server's request to initiate GSSAPI
authentication. We don't support GSS/SSPI authentication that requires multiple
steps; if the server sends us a "GSSContinue" message in response to
[gss_krb_token], login will fail. Kerberos should not require this.
[ssl_mode] defaults to [Ssl_mode.Disable].
[buffer_age_limit] sets the age limit on the outgoing Writer.t. The default limit
is 2m to preserve existing behavior, but you likely want [`Unlimited] to avoid
application crashes when the database is loaded---and this may become the default at
some point in the future.
[buffer_byte_limit] is only used during a COPY---it pauses inserting more rows and
flushes the entire Writer.t if its buffer contains this many bytes or more. *)valconnect:?interrupt:unitDeferred.t->?ssl_mode:ssl_mode->?server:_Tcp.Where_to_connect.t->?user:string->?password:string->?gss_krb_token:string->?buffer_age_limit:Async_unix.Writer.buffer_age_limit->?buffer_byte_limit:Byte_units.t->database:string->unit->(t,error)Result.tDeferred.t(** [close] returns an error if there were any problems gracefully tearing down the
connection. For sure, when it is determined, the connection is gone.
[try_cancel_statement_before_close] defaults to false. If set to true, [close]
will first attempt to cancel any query in progress on [t] before closing the
connection, which provides more 'graceful' closing behavior.
*)valclose:?try_cancel_statement_before_close:bool->t->(unit,error)Result.tDeferred.tvalclose_finished:t->(unit,error)Result.tDeferred.ttypestate=|Open|Closing|Failedof{error:error;resources_released:bool}|Closed_gracefully[@@derivingsexp_of]valstatus:t->statevalwith_connection:?interrupt:unitDeferred.t->?ssl_mode:ssl_mode->?server:_Tcp.Where_to_connect.t->?user:string->?password:string->?gss_krb_token:string->?buffer_age_limit:Async_unix.Writer.buffer_age_limit->?buffer_byte_limit:Byte_units.t->?try_cancel_statement_before_close:bool->database:string->on_handler_exception:[`Raise]->(t->'resDeferred.t)->('res,error)Result.tDeferred.t(** [handle_columns] can provide column information even if 0 rows are found.
[handle_columns] is guaranteed to be called before the first invocation of
[handle_row] *)valquery:t->?parameters:stringoptionarray->?pushback:(unit->unitDeferred.t)->?handle_columns:(column_metadataarray->unit)->string->handle_row:(column_names:stringarray->values:stringoptionarray->unit)->(unit,error)Result.tDeferred.tvalquery_expect_no_data:t->?parameters:stringoptionarray->string->(unit,error)Result.tDeferred.ttype'afeed_data_result=|Abortof{reason:string}|WaitofunitDeferred.t|Dataof'a|Finishedvalcopy_in_raw:t->?parameters:stringoptionarray->string->feed_data:(unit->stringfeed_data_result)->(unit,error)Result.tDeferred.t(** Note that [table_name] and [column_names] must be escaped before calling
[copy_in_rows]. *)valcopy_in_rows:?schema_name:string->t->table_name:string->column_names:stringlist->feed_data:(unit->stringoptionarrayfeed_data_result)->(unit,error)Result.tDeferred.t(** [listen_to_notifications] executes a query to subscribe you to notifications on
[channel] (i.e., "LISTEN $channel") and stores [f] inside [t], calling it when the
server sends us any such notifications.
Calling it multiple times is fine: the "LISTEN" query is idempotent, and both
callbacks will be stored in [t].
However, be careful. The interaction between postgres notifications and transactions
is very subtle. Here are but some of the things you need to bear in mind:
- LISTEN executed during a transaction that is rolled back has no effect. As such,
if you're in the middle of a transaction when you call [listen_to_notifications]
and then roll said transaction back, [f] will be stored in [t] but you will not
actually receive any notifications from the server.
- Notifications that happen while you are in a transaction are only delivered by the
server after the end of the transaction. In particular, if you're doing a big
[query] and you're pushing-back on the server, you're also potentially delaying
delivery of notifications.
- You need to pay attention to [close_finished] in case the server kicks you off.
- The postgres protocol has no heartbeats. If the server disappears in
a particularly bad way it might be a while before we notice. The empty query makes
a rather effective heartbeat (i.e. [query_expect_no_data t ""]), but this is your
responsibility if you want it. *)vallisten_to_notifications:t->channel:string->f:(pid:Pid.t->payload:string->unit)->(unit,error)Result.tDeferred.tend