Docs GODI Archive
Projects Blog Link DB

Search GODI:


More options
File lib/ocaml/pkg-lib/dbi/dbi.mli GODI Package godi-ocamldbi
Library dbi
 
   Dbi.html    dbi.cmi_pretty    dbi.mli    Sources  
(* Generic database interface for mod_caml programs.
 * Copyright (C) 2003-2004 Merjis Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: dbi.mli,v 1.25 2005/01/25 17:59:10 ChriS Exp $
 *)

(** Generic database interface.
  *
  * Making a connection to a specific type of database:
  *
 {[  module DB = Dbi_postgres
  *  let dbh = new DB.connection "database_name"  			]}
  *
  * Simple usage, returning one row:
  *
 {[  let sth = dbh#prepare "SELECT name FROM employees WHERE empid = ?" in
  *  sth#execute [`Int 100];
  *  let [`String name] = sth#fetch1 in ...    				]}
  *
  * Simple usage, returning multiple rows:
  *
 {[  let sth = dbh#prepare "SELECT firstname, name FROM employees
  *                         WHERE salary > ?" in
  *  sth#execute [`Int 10000];
  *  sth#iter(function
  *           | [(`Null | `String _) as fname, `String name] ->
  *               do_something_with fname name
  *           | _ -> assert false);                                	]}
  *
  * Advanced usage, reusing prepared statements:
  *
 {[  let sth =
  *    dbh#prepare "INSERT INTO employees(name, salary) VALUES (?, ?)" in
  *  List.iter(fun (name, salary) ->
  *              sth#execute [`String name; `Int salary];
  *              let id = sth#serial "" in
  *              Printf.printf "Employee %s has been assigned ID %d\n" name id
  *           ) employees_list;                                         ]}
  *)


(** {1 Caml mappings of SQL types.} *)

type date = { year : int; month : int; day : int; }

type time = { hour : int; min : int; sec : int; microsec : int;
	      timezone : int option }

type datetime = date * time

module Decimal :
sig
  (** Module to handle arbitrary precision decimal numbers.

    A decimal number is a number of the form n 10^e with n, e
    integers.  It characterized by its precision (i.e., its total
    number of digits) and its scale.  For example, 103.12 has
    precision 5 (or more) and scale 2.  In this implementation, the
    precision is taken as +infinity and the scale adapts dynamically.
  *)

  type t
    (** Abstract type for decimal numbers *)

  val to_string : t -> string
    (** [to_string n] returns a string representation of the decimal
      number [n]. *)
  val to_float : t -> float
    (** [to_float n] returns the closer float to [n]. *)
  val of_string : ?scale:int -> string -> t
    (** [of_string ?scale s] returns the decimal number represented by
      the string [s].  If the option [scale] is not set, the scale
      will be the one of the string representation.  If [scale] is
      given, it will be enforced, possibly truncating the number.

      @raise Invalid_argument if [scale < 0].
    *)
  val of_int : ?scale:int -> int -> t
    (** [of_int ?scale i] returns the decimal number [i * 10**(-scale)].

      @param scale Scaling of [i] (default: 0).
      @raise Invalid_argument if [scale < 0].
    *)

  val add : t -> t -> t
    (** [add n m] returns the sum of [n] and [m]. *)
  val sub : t -> t -> t
    (** [sub n m] returns the difference of [n] by [m]. *)
  val mul : t -> t -> t
    (** [mul n m] returns the product of [n] and [m]. *)
  val div : t -> t -> t
    (** [div n m] returns the quotient of the division of [n] by [m]. *)

  val compare : t -> t -> int
    (** [compare n m] returns [0] if [x=y], a negative integer if
      [x<y], and a positive integer if [x>y]. *)
end


(* Some types not yet implemented. XXX *)
type sql_t = [ `Null			(* NULL value *)
	     | `Int of int		(* integer, smallint *)
             | `Float of float		(* double precision, real *)
	     | `String of string	(* char, varchar, text *)
	     | `Bool of bool		(* boolean *)
	     | `Bigint of Big_int.big_int (* bigint *)
	     | `Decimal of Decimal.t	(* numeric, decimal *)
	     | `Date of date		(* date *)
	     | `Time of time		(* time (with/without TZ) *)
	     | `Timestamp of datetime	(* timestamp (with/without TZ) *)
	     | `Interval of datetime	(* interval (no TZ) *)
          (* | `Blob of blob            (* blob *) *)
	     | `Binary of string        (* Postgres's BYTEA and equivalent *)
	     | `Unknown of string	(* cannot be represented by any above*)
	     ]

val sql_t_to_string : sql_t -> string
(** [sql_t_to_string t] returns a string representation of [t]
  * following the Ocaml conventions.  The aim is to offer an easy way
  * to print [sql_t] values.
  *)

val sdebug : sql_t list -> string
(** [sdebug ss] can be used to debug the return value from a [#fetch1],
  * [#map] or other query.  It converts the [sql_t list] type into a
  * printable form which may be printed on [stderr] to aid in debugging
  * the actual types returned by the database.
  *)

val intoption : int option -> sql_t
(** [intoption(Some i)] returns [`Int i] and
  [intoption None] returns [`Null]. *)
val stringoption : string option -> sql_t
(** [stringoption(Some s)] returns [`String s] and
  * [stringoption None] returns [`Null]. *)

type precommit_handle
(** See {!Dbi.connection.register_precommit}. *)
type postrollback_handle
(** See {!Dbi.connection.register_postrollback}. *)


(** {1 SQL utility functions.} *)

val string_escaped : string -> string
(** [escape_string s] escapes the string [s] according to SQL rules
  * and surrounds it with single quotes.  This should be hardly needed
  * as the data provided through the sql_t types will automatically be
  * escaped for you.
  *)

val placeholders : int -> string
(** [placeholders n] returns a string of the form "(?, ?, ..., ?)" containing
  * [n] question marks.
  * @raise Invalid_argument if [n <= 0].
  *)

exception SQL_error of string
(** Exceptions thrown by subclasses on SQL errors. *)

class virtual statement :
  connection ->
object
  method virtual execute : sql_t list -> unit
    (** Execute the statement with the given list of arguments substituted
      * for [?] placeholders in the query string.  This method should
      * be executed before trying to fetch data.
      *
      * This command can throw a variety of SQL-specific exceptions.
      *)

  method virtual fetch1 : unit -> sql_t list
    (** Fetches one row from the result set and returns it.
      * @raise Not_found if no tuple is returned by the database.
      * @raise Failure if [#execute] has not been issued before.  *)

  method fetch1int : unit -> int
    (** This fetches a single integer field.
      * @raise Not_found if no tuples are remaining.
      * @raise Invalid_argument if the tuple does not contain a single integer.
      * @raise Failure if [#execute] has not been issued before.  *)

  method fetch1string : unit -> string
    (** This fetches a single string field.
      * @raise Not_found if no tuples are remaining.
      * @raise Invalid_argument if the tuple does not contain a single string.
      * @raise Failure if [#execute] has not been issued before.  *)

  method fetch1bool : unit -> bool
    (** This fetches a single string field.
      * @raise Not_found if no tuples are remaining.
      * @raise Invalid_argument if the tuple does not contain a single boolean.
      * @raise Failure if [#execute] has not been issued before.  *)

  method fetchall : unit -> sql_t list list
    (** This returns a list of all tuples returned from the query. Note
      * that this may be less efficient than reading them one at a time.
      * @raise Failure if [#execute] has not been issued before.  *)

  method iter : (sql_t list -> unit) -> unit
    (** Iterate over the result tuples.
      * @raise Failure if [#execute] has not been issued before.  *)

  method map : 'a . (sql_t list -> 'a) -> 'a list
    (** Map over the result tuples.
      * @raise Failure if [#execute] has not been issued before.  *)

  method fold_left : 'a . ('a -> sql_t list -> 'a) -> 'a -> 'a
    (** Fold left over the result tuples.
      * @raise Failure if [#execute] has not been issued before.  *)

  method fold_right : 'a . (sql_t list -> 'a -> 'a) -> 'a -> 'a
    (** Fold right over the result tuples.  Not tail-recursive.
      * @raise Failure if [#execute] has not been issued before.  *)

  method virtual names :