(*
* <COPYRIGHT>
* Copyright 2003 Gerd Stolpmann
*
* <GPL>
* This file is part of WTimer.
*
* WTimer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* WTimer 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WDialog; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* </>
*)
(* $Id: db.mli,v 1.8 2003/03/23 11:59:13 gerd Exp $
* ----------------------------------------------------------------------
*
*)
module Types : sig
open Db_types.Types
type user_name = User of string
(* User name *)
val string_of_user_name : user_name -> string
(* Extract the name of the user as string *)
type user = { u_name : user_name;
u_description : string;
u_password : string option; (* MD5 checksum as hex string *)
u_login : bool;
u_admin : bool;
}
(* The user record for the user called [u_name] with a [u_description].
* More fields may be added.
*)
exception No_such_user of user_name
exception User_already_exists of user_name
(* The string is the errorneous user name *)
type inst_name = Instance of string
(* Instance name *)
val string_of_inst_name : inst_name -> string
(* Extract the name of the instance as string *)
type instance = { i_name : inst_name;
i_description : string;
}
(* The instance record for the instance called [i_name] with an
* [i_description]. More fields may be added.
*)
exception No_such_instance of inst_name
exception Instance_already_exists of inst_name
(* The string is the errorneous instance name *)
type perm_type = [ `Write | `Read | `Owner ]
(* Permission types:
* `Read: The user can view the instance
* `Write: The user can change the instance
* `Owner: The user can set permissions and delete the whole instance
*)
type perm_set = { p_instance : inst_name;
p_set : (user_name * perm_type) list;
}
(* The set of permissions for the instance called [p_instance].
* The [p_set] component enumerates all users that have at least
* one permission, and lists the granted permissions.
*)
type entry = { mutable e_id : int option;
e_instance : inst_name;
e_day : date;
e_index : int;
e_start : time option;
e_end : time option;
e_duration : interval option;
e_project : string;
e_description : string;
}
type day = { d_instance : inst_name;
d_day : date;
d_entries : entry list;
}
end
module Connection : sig
(* This module is about the application-specific way to open and close
* database connections, and to begin and end transactions.
*)
type connection
val create : unit -> connection
(* Creates a new connection handle. Initially the handle is unconnected.
*)
val bind : db_name:string -> user_name:string -> passwd:string ->
connection -> unit
(* Binds the handle to the database identified by the named arguments.
* When the first db request is executed the handle will be connected
* to the database.
*)
val unbind : connection -> unit
(* Rollback the current transaction, and close the connection, if any.
* The handle is now in the same state as after [create].
*)
val close_after_timeout : connection -> int -> unit
(* The connection is closed when there was no query after
* the passed timeout (in seconds). The timeout period begins after
* [commit] or [rollback] are executed. The connection is still bound,
* so any query will automatically reconnect to the database server.
*
* This function only checks whether the timeout period is over,
* and if so, it closes the connection. It does not wait, nor installs
* a signal handler or any other means that actually watches for timeouts.
* Call this function regularly to detect timeouts.
*)
val is_connected : connection -> bool
(* Returns whether the handle is connected or not. *)
val commit : connection -> unit
(* Commit the current transaction, and begin a new one *)
val rollback : connection -> unit
(* Rollback the current transaction, and begin a new one *)
end
module User : sig
open Db_types.Types
open Types
open Connection
val list : connection -> user list
(* List the users *)
val get : connection -> user_name -> user
(* Get the entry for a user *)
val exists : connection -> user_name -> bool
(* Checks whether the user exists *)
val insert : connection -> user -> unit
(* Add a new user. May raise User_already_exists *)
val update : connection -> user -> unit
(* Change the properties of a user. May raise No_such_user *)
val delete : connection -> user_name -> unit
(* Delete a user. Deletes the user from permission tables, too.
* May raise No_such_user
*)
val encrypt_password : string -> string
(* Encrypts a password, normally by applying a one-way hash function *)
end
module Instance : sig
open Db_types.Types
open Types
open Connection
val list : connection -> instance list
(* List the instances *)
val get : connection -> inst_name -> instance
(* Get the entry for an instance *)
val exists : connection -> inst_name -> bool
(* Checks whether the instance exists *)
val insert : connection -> instance -> unit
(* Add a new instance. May raise Instance_already_exists *)
val update : connection -> instance -> unit
(* Change the properties of an instance. May raise No_such_instance *)
val delete : connection -> inst_name -> unit
(* Delete the instance, and all permissions, and all entries for
* that instance. May raise No_such_instance.
*)
end
module Permission : sig
open Db_types.Types
open Types
open Connection
val check : connection -> inst_name -> user_name -> perm_type -> bool
(* Checks whether the passed user has the permission to access the
* passed instance in the way indicated by the perm_type value.
* Returns [true] if permission is granted, and [false] otherwise.
* Returns [false] if the user or the instance does not exist.
*)
val get : connection -> inst_name -> perm_set
(* Returns the permission set for the passed instance.
* Raises No_such_instance if the instance does not exist.
*)
val update : connection -> perm_set -> unit
(* Updates the permission set for the passed instance
* Raises No_such_instance if the instance does not exist.
*)
end
module Entry : sig
open Db_types.Types
open Types
open Connection
val list : connection -> inst_name -> date -> date -> date list
(* Return the list of dates that fall into a certain period of time
* and that actually have entries:
* let dates = list conn iname start end
* The period begins with the date [start] and ends with [end]
* (inclusive). All dates are returned in the list [dates] if
* there are entries in the instance [iname] for them. The dates
* are returned in ascending order.
*)
val get : connection -> inst_name -> date -> day
(* Query the passed date of the passed instance, and return the whole
* [day] structure.
*)
val update : connection -> day -> unit
(* Update the passed day.
* Note that e_id fields may be changed from [None] to [Some id].
*)
end
module Session : sig
(* Wdialog sessions stored in database *)
open Connection
exception Invalid_session_checksum
(* The state as stored in the database does not match the state as
* expected by the last user request; this is checked by comparing
* checksums. The most likely reason is that the user has submitted
* a historic form. There should be a nice error message explaining
* that it is not possible to go back and submit pages again.
*)
exception Session_not_found
(* The session could not be found. A possible reason is that the
* session is too old and has been removed in the mean time.
*)
class db_session_manager : connection -> Wd_types.session_manager_type
(* Note: The current transaction is comitted when the session is
* written back into the database. This normally only happens as
* the very last action of an otherwise successful activation.
*)
end
(* ======================================================================
* History:
*
* $Log: db.mli,v $
* Revision 1.8 2003/03/23 11:59:13 gerd
* GPL
*
* Revision 1.7 2003/02/04 01:42:40 gerd
* The code does no longer use signals to get rid of inactive
* database connections. Instead, new features of ocamlnet are used
* (js_idle_worker).
*
* Revision 1.6 2003/02/03 01:28:59 gerd
* Continued.
*
* Revision 1.5 2003/01/16 00:39:25 gerd
* Continued.
*
* Revision 1.4 2002/11/20 21:32:46 gerd
* Added u_password, u_login, u_admin
*
* Revision 1.3 2002/11/16 12:34:41 gerd
* Moved date, time, interval to Db_types
*
* Revision 1.2 2002/10/12 23:08:32 gerd
* Moved date_rec, time_rec, interval_rec to Types module
*
* Revision 1.1 2002/10/05 23:37:20 gerd
* Initial revision
*
*
*)