(* * <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 * * *)