* [Caml-list] Re: New Features (Common Database Interface)
@ 2003-02-14 22:35 Matt Boyd
2003-02-15 13:56 ` cashin
0 siblings, 1 reply; 2+ messages in thread
From: Matt Boyd @ 2003-02-14 22:35 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: text/plain, Size: 338 bytes --]
This is what I've been using. It has been useful for creating a common
database interface that, at least, meets my basic needs. I've written
bindings for ODBC, PostgreSQL, and Sybase(dblib). The bindparam stuff
hasn't been worked on too much, but I haven't really needed it.
If anyone thinks this is a starting point, let me know.
[-- Attachment #2: camlDB.mli --]
[-- Type: text/plain, Size: 11817 bytes --]
(**
{b Caml Database Interface}
Common interface for connecting to databases.
*)
(** {3 Exceptions} *)
exception End_of_rows
(** Raised when query results ends. *)
exception Row_failure of string * string
(**
{b Row_failure ({e table}, {e row-as-string})}
{ul
{li {e table}: Table query failed.}
{li {e row-as-string}: Actual row contents changed to a string}}
*)
(** {3 Data Types} *)
(** {4 Date and Time Types} *)
(** Basic date components *)
type date = {
year : int;
month : int;
day : int
}
(** Basic time components *)
type time = {
hour : int;
minute : int;
second : int
}
(** Database timestamp type *)
type timestamp = {
date : date;
time : time;
fraction : int
}
(** {4 Fields and rows} *)
(** Database field data types *)
type data =
| Null
| String of string
| Integer of int
| Float of float
| Date of date
| Time of time
| Timestamp of timestamp
(** A row is a list of fields *)
type row = data list
(** {4 Conversion to String} *)
val string_of_date : date -> string
val string_of_time : time -> string
val string_of_timestamp : timestamp -> string
val string_of_data : data -> string
val string_of_row : row -> string
val raise_row_failure : string -> row -> 'a
(**
{b raise_row_failure {e table row}}
{ul
{li {e table}: Name of the table}
{li {e row}: Row that was actually retrieved}}
@raise Row_failure Raised when this function is called.
@return
Nothing. Raises {e Row_failure} with the parameters.
*)
(** {4 Conversion from Unix Time} *)
val timestamp_of_unix_time : float -> timestamp
val date_of_unix_time : float -> date
val time_of_unix_time : float -> time
(** {4 Conversion to Unix Time} *)
val unix_time : Unix.tm -> float
val unix_time_of_timestamp : timestamp -> float
val unix_time_of_date : date -> float
val unix_time_of_time : time -> float
(** Bind parameter direction *)
type bind_io =
| Input
| Output
(** {3 Caml Database Signatures} *)
(** Basic database interface *)
module type ELT =
sig
(**
Implement this signature for a type of database and you can
use it interchangeably in applications.
*)
type args (** Connection arguments *)
type connection (** Connection type *)
type result (** Result set *)
(** {5 Connection functions} *)
val connect : args -> connection
(**
{b connect {e connection-args}}
{ul
{li {e connection-args}: Arguments needed to initiate a connection}}
@return
A connection. An exception that is database-specific will be
raised if a connection cannot be established.
*)
val disconnect : connection -> unit
(**
{b disconnect {e connection}}
{ul
{li {e connection}: A valid connection}}
@return
Nothing. If the connection has already been disconnected, then
it's unspecified how this will behave (It may just return or it
may raise an exception)
*)
val useConn : (connection -> 'a) -> args -> 'a
(**
{b useConn {e conn-function conn-args}}
{ul
{li {e conn-function}: A function which takes a {e connection}
argument}
{li {e conn-args}: Arguments to the {e connect} function which
can be used to create a connection.}}
@return
The result of applying {e conn-function} to the connection established
with {e conn-args}.
*)
(** {5 Query functions} *)
val direct : string -> connection -> unit
(**
{b direct {e query connection}}
{ul
{li {e query}: The query string.}
{li {e connection}: The connection.}}
@return
Nothing. Executes the query. Any results will be
discarded.
*)
val execute : string -> connection -> result
(**
{b execute {e query connection}}
{ul
{li {e query}: Query string.}
{li {e connection}: Connection}}
@return
A result set. The query is executed and the results are returned
as a result type.
*)
val cancel : result -> unit
(**
{b cancel {e result}}
{ul
{li {e result}: The result set.}}
@return
Nothing. The result information is cleaned-up if there is any.
This may raise an exception or may not. In most cases it should
just return even if the result has already been cancelled.
*)
val useQuery : (result -> 'a) -> string -> connection -> 'a
(**
{b useQuery {e result-fun query conn}}
{ul
{li {e result-fun}:
Function to pass the result returned by executing {e query}
using {e connection}.}
{li {e query}: The query string}
{li {e conn}: The connection.}}
@return
The result of applying {e result-fun} to the result returned by
executing {e query} with {e conn}.
*)
(** {5 Row Information Functions} *)
val numberOfColumns : result -> int
(**
{b numberOfColumns {e result}}
{ul {li {e result}: The result set.}}
@return The number of columns in each row
*)
val numberOfRows : result -> int
(**
{b numberOfRows {e result}}
{ul {li {e result}: The result set.}}
@return the number of rows returned by the query.
*)
val nextRow : result -> row
(**
{b nextRow {e result}}
{ul {li {e result}: The result set.}}
@return the next row in the set of rows.
*)
(** {5 Higher-level Functions} *)
val iter : string -> (row -> unit) -> connection -> unit
(**
{b iter {e query iter-fun conn}}
{ul
{li {e query}: The query string.}
{li {e iter-fun}:
Function to execute for each row in the query set.}
{li {e conn}: The connection}}
@return
Nothing. Executes {e query} and then iterates over the
rows returned with {e iter-fun}.
*)
val map : string -> (row -> 'b) -> connection -> 'b list
(**
{b map {e query map-fun conn}}
{ul
{li {e query}: The query string.}
{li {e map-fun}: Function to run on each row.}
{li {e conn}: Connection to use.}}
@return
A list of all elements returned by applying {e map-fun} to
every row returned by executing {e query}.
*)
val stream : string -> connection -> data Stream.t
(**
{b stream {e query conn}}
{ul
{li {e query}: The query string.}
{li {e conn}: Connection.}}
@return
A stream that will return the next row when used with
{e Stream.next}.
*)
end
(** Bind Signature Interface *)
module type BIND =
sig
type result
(** Bind result columns *)
module Col :
sig
type t
val bind : result -> int -> data ->t
(**
{b bind {e result column data}}
{ul
{li {e result}: Result returned by executing a query.}
{li {e column}: Column number.}
{li {e data}: Initialized data value.}}
@return A column binding value.
*)
val free : t -> unit
(**
{b free {e binding}}
{ul {li {e binding}: Binding to free}}
@return Nothing. The binding is undone.
*)
val replace : t -> data -> unit
(**
{b replace {e binding data}}
{ul
{li {e binding}: Binding to use.}
{li {e data}: Data to replace in the binding.}}
@return. Nothing. Replace the data in {e binding}
*)
val get : t -> data
(**
{b get {e binding}}
{ul {li {e binding}: Binding to extract from.}}
@return. The information contained in {e binding}
*)
val use : (t -> 'a) -> result -> int -> data -> 'a
(**
{b use {e bind-fun result col init}}
{ul
{li {e bind-fun}: Function which uses binding.}
{li {e result}: Used to create binding.}
{li {e col}: Used to create binding.}
{li {e init}: Initial binding value.}}
@return
The result returned by applying {e bind-fun} to
the binding created with the other parameters.
*)
end
(** Bind query parameters *)
module Param :
sig
type t
val bind : result -> int -> bind_io -> data ->t
(**
{b bind {e result param-num bind-dir data}}
{ul
{li {e result}: The query result set.}
{li {e param-num}: The parameter number to bind to.}
{li {e bind-dir}: The parameter direction.}
{li {e data}: Initial binding value.}}
@return A bound value.
*)
val free : t -> unit
(**
{b free {e binding}}
{ul {li {e binding}: Binding to free}}
@return Nothing. The binding is undone.
*)
val replace : t -> data -> unit
(**
{b replace {e binding data}}
{ul
{li {e binding}: Binding to use.}
{li {e data}: Data to replace in the binding.}}
@return. Nothing. Replace the data in {e binding}
*)
val get : t -> data
(**
{b get {e binding}}
{ul {li {e binding}: Binding to extract from.}}
@return. The information contained in {e binding}
*)
val use : (t -> 'a) -> result -> int -> bind_io -> data -> 'a
(**
{b use {e bind-fun result param-num bind-dir init}}
{ul
{li {e bind-fun}: Function which uses binding.}
{li {e result}: Used to create binding.}
{li {e param-num}: Used to create binding.}
{li {e bind-dir}: The parameter direction.}
{li {e init}: Initial binding value.}}
@return
The result returned by applying {e bind-fun} to
the binding created with the other parameters.
*)
end
end
(** {4 Row Manipulation Signatures} *)
(** Row Constructor *)
module type ROW =
sig
type t
val of_row : row -> t
(**
{b of_row {e row}}
{ul {li {e row}: Row to convert.}}
@raise Row_failure if it cannot convert the row.
@return the result of constructing {e t} from a {e row}.
*)
end
(** Row Stream Interface *)
module type ROW_STREAM =
sig
type t
type connection
type result
val of_row : row -> t
(**
{b of_row {e row}}
{ul {li {e row}: Row to convert.}}
@raise Row_failure if it cannot convert the row.
@return the result of constructing {e t} from a {e row}.
*)
val next_row : result -> t
(**
{b next_row {e result}}
{ul
{li {e result}; Result to convert.}}
@return the construction of a {e t} from the next row in {e result}.
*)
val iter : string -> (t -> unit) -> connection -> unit
val map : string -> (t -> 'a) -> connection -> 'a list
val stream : string -> connection -> t Stream.t
val fold : string -> (t -> 'a -> 'a) -> 'a -> connection -> 'a
end
module MakeRow (Elt : ELT)(Row : ROW) :
ROW_STREAM
with type t = Row.t
and type connection = Elt.connection
and type result = Elt.result
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-02-15 13:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-14 22:35 [Caml-list] Re: New Features (Common Database Interface) Matt Boyd
2003-02-15 13:56 ` cashin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox