1 (* Copyright (C) 2000, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
38 exception SVarUnbound of string;;
39 exception RVarUnbound of string;;
40 exception VVarUnbound of string;;
41 exception PathUnbound of (string * string list);;
43 exception InvalidConnection
44 exception ConnectionFailed of string
46 exception BooleExpTrue
48 (* valuta una MathQL.set_exp e ritorna un MathQL.resource_set *)
53 let execute_aux log m x =
54 let module M = MathQL in
55 let module X = MQueryMisc in
56 let rec exec_set_exp c = function
59 List.assoc svar c.svars
61 raise (SVarUnbound svar))
64 [List.assoc rvar c.rvars]
66 raise (RVarUnbound rvar))
67 | M.Ref vexp -> List.map (fun s -> (s,[])) (exec_val_exp c vexp)
68 | M.Pattern vexp -> pattern_ex (exec_val_exp c vexp)
69 | M.Intersect (sexp1, sexp2) ->
70 let before = X.start_time() in
71 let rs1 = exec_set_exp c sexp1 in
72 let rs2 = exec_set_exp c sexp2 in
73 let res = intersect_ex rs1 rs2 in
74 let diff = X.stop_time before in
75 let ll1 = string_of_int (List.length rs1) in
76 let ll2 = string_of_int (List.length rs2) in
77 if String.contains m stat_char then
78 log ("INTERSECT(" ^ ll1 ^ "," ^ ll2 ^ ") = " ^ string_of_int (List.length res) ^
81 | M.Union (sexp1, sexp2) ->
82 let before = X.start_time () in
83 let res = union_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2) in
84 let diff = X.stop_time before in
85 if String.contains m stat_char then log ("UNION: " ^ diff ^ "\n");
87 | M.LetSVar (svar, sexp1, sexp2) ->
88 let before = X.start_time() in
89 let c1 = upd_svars c ((svar, exec_set_exp c sexp1) :: c.svars) in
90 let res = exec_set_exp c1 sexp2 in
91 if String.contains m stat_char then begin
92 log ("LETIN " ^ svar ^ " = " ^ string_of_int (List.length res) ^ ": ");
93 log (X.stop_time before ^ "\n");
96 | M.LetVVar (vvar, vexp, sexp) ->
97 let before = X.start_time() in
98 let c1 = upd_vvars c ((vvar, exec_val_exp c vexp) :: c.vvars) in
99 let res = exec_set_exp c1 sexp in
100 if String.contains m stat_char then begin
101 log ("LETIN " ^ vvar ^ " = " ^ string_of_int (List.length res) ^ ": ");
102 log (X.stop_time before ^ "\n");
105 | M.Relation (inv, rop, path, sexp, assl) ->
106 let before = X.start_time() in
107 if String.contains m galax_char then begin
108 let res = relation_galax_ex inv rop path (exec_set_exp c sexp) assl in
109 if String.contains m stat_char then begin
110 log ("RELATION-GALAX " ^ (fst path) ^ " = " ^ string_of_int(List.length res) ^ ": ");
111 log (X.stop_time before ^ "\n")
115 let res = relation_ex inv rop path (exec_set_exp c sexp) assl in
116 if String.contains m stat_char then begin
117 log ("RELATION " ^ (fst path) ^ " = " ^ string_of_int(List.length res) ^ ": ");
118 log (X.stop_time before ^ "\n")
122 | M.Select (rvar, sexp, bexp) ->
123 let before = X.start_time() in
124 let rset = (exec_set_exp c sexp) in
129 let c1 = upd_rvars c ((rvar,r)::c.rvars) in
130 if (exec_boole_exp c1 bexp) then
135 let res = select_ex rset in
136 if String.contains m stat_char then begin
137 log ("SELECT " ^ rvar ^ " = " ^ string_of_int (List.length res) ^ ": ");
138 log (X.stop_time before ^ "\n");
141 | M.Diff (sexp1, sexp2) -> diff_ex (exec_set_exp c sexp1) (exec_set_exp c sexp2)
143 (* valuta una MathQL.boole_exp e ritorna un boole *)
145 and exec_boole_exp c =
149 | M.Not x -> not (exec_boole_exp c x)
150 | M.And (x, y) -> (exec_boole_exp c x) && (exec_boole_exp c y)
151 | M.Or (x, y) -> (exec_boole_exp c x) || (exec_boole_exp c y)
152 | M.Sub (vexp1, vexp2) ->
153 sub_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
154 | M.Meet (vexp1, vexp2) ->
155 meet_ex (exec_val_exp c vexp1) (exec_val_exp c vexp2)
156 | M.Eq (vexp1, vexp2) -> (exec_val_exp c vexp1) = (exec_val_exp c vexp2)
159 (exec_boole_exp c bexp)
166 List.assoc uri c.rvars
167 with Not_found -> assert false)
170 ) l (*latt = l + attributi*)
175 [] -> if (exec_boole_exp c bexp) then raise BooleExpTrue
176 | (uri,attl)::tail1 ->
177 (*per ogni el. di attl devo andare in ric. su tail1*)
178 let rec sub_prod attl =
182 let c1 = upd_groups c ((uri,att)::c.groups) in
183 prod c1 tail1; sub_prod tail2
189 with BooleExpTrue -> true
191 (* valuta una MathQL.val_exp e ritorna un MathQL.value *)
193 and exec_val_exp c = function
195 ol = List.sort compare x in
196 let rec edup = function
199 | s::tl -> if tl <> [] then
200 if s = (List.hd tl) then edup tl
205 | M.Record (rvar, path) ->
209 List.assoc rvar c.groups
211 raise (RVarUnbound rvar))
213 raise (PathUnbound path))
218 raise (VVarUnbound s))
219 | M.RefOf sexp -> List.map (fun (s,_) -> s) (exec_set_exp c sexp)
220 | M.Fun (s, vexp) -> fun_ex s (exec_val_exp c vexp)
221 | M.Property (inv, rop, path, vexp) -> property_ex rop path inv (exec_val_exp c vexp)
223 (* valuta una MathQL.set_exp nel contesto vuoto e ritorna un MathQL.resource_set *)
225 exec_set_exp {svars = []; rvars = []; groups = []; vvars = []} x
227 (* new interface ***********************************************************)
229 module type Callbacks =
231 val log : string -> unit (* logging function *)
234 module Make (C: Callbacks) =
243 let execute m x = execute_aux C.log m x
246 let default_connection_string =
247 "host=mowgli.cs.unibo.it dbname=helm_mowgli_new_schema user=helm"
249 let connection_string =
250 try Sys.getenv "POSTGRESQL_CONNECTION_STRING"
251 with Not_found -> default_connection_string
253 if String.contains m galax_char then true else
254 try Dbconn.init connection_string; true
255 with ConnectionFailed s -> false
258 if String.contains m galax_char then () else Dbconn.close ()
261 if String.contains m galax_char then false else
262 try ignore (Dbconn.pgc ()); true with InvalidConnection -> false