Plasma GitLab Archive
Projects Blog Knowledge

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

This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml