Index: MDRepository/trunk/xquery/cmd-model.xqm
===================================================================
--- MDRepository/trunk/xquery/cmd-model.xqm	(revision 815)
+++ MDRepository/trunk/xquery/cmd-model.xqm	(revision 825)
@@ -10,6 +10,6 @@
 declare variable $cmd-model:cmdiDatabaseURI as xs:string := "xmldb:exist:///db";
 
-declare variable $cmd-model:commonFreqsPath as xs:string := "/db/common/clarin/freqs";
 declare variable $cmd-model:cmdiMirrorPath as xs:string := "/db/cmdi-mirror";
+declare variable $cmd-model:cachePath as xs:string := "/db/cache";
 
 declare variable $cmd-model:getCollections as xs:string := "getCollections";
@@ -41,5 +41,15 @@
 :)
 declare function cmd-model:query-model($cmd-index-path as xs:string, $collection as xs:string+, $format as xs:string, $max-depth as xs:integer) as item()? {
-	cmd-model:serialise-as(cmd-model:get-result-doc($collection, $cmd-index-path, $max-depth), $format)
+	
+	let $name := cmd-model:gen-cache-id("model", ($collection, $cmd-index-path), xs:string($max-depth)),
+ 	$doc := 
+    if (cmd-model:is-in-cache($name)) then
+      cmd-model:get-from-cache($name)
+    else
+    	let $data := cmd-model:elem($collection, $cmd-index-path, $max-depth)
+		return cmd-model:store-in-cache($name, $data)
+
+	return 
+  	cmd-model:serialise-as($doc, $format)	
 };
 
@@ -48,20 +58,13 @@
 :)
 declare function cmd-model:get-collections($collections as xs:string+, $format as xs:string, $max-depth as xs:integer) as item() {
-  let $names := ($cmd-model:commonFreqsPath, cmd-model:make-compound-doc-name($collections, "collection", xs:string($max-depth))),
- 	$dummy := 
-      if (cmd-model:is-doc-available($names[1], $names[2])) then
-	()
-      else
-	let $children := 
-	  for $collection-item in $collections
-	    return
-	    for $collection-doc in cmd-model:get-resource-by-handle($collection-item) 
-	      return cmd-model:recurse-collections($collection-doc, cmd-model:get-md-collection-name($collection-doc), $collection-doc//MdSelfLink, "", $max-depth)
-	    let $res-count := sum($children/@cnt)
-	    let $coll-count := sum($children/@cnt_subcolls) + count($children) 
-	      return cmd-model:store-collection-data(<Collections cnt="{$res-count}" cnt_subcolls="{$coll-count}" cnt_children="{count($children)}" root="{$collections}">{$children}</Collections>, $names[1], $names[2])
-
+  let $name := cmd-model:gen-cache-id("collection", $collections, xs:string($max-depth)),
+ 	$doc := 
+    if (cmd-model:is-in-cache($name)) then
+       cmd-model:get-from-cache($name)
+    else
+	   	let $data := cmd-model:colls($collections, $max-depth)
+		return cmd-model:store-in-cache($name, $data)
 	return 
-  	cmd-model:serialise-as(cmd-model:get-doc($names[1], $names[2]), $format)
+  	cmd-model:serialise-as($doc, $format)
 };
 
@@ -97,6 +100,5 @@
 (: **********************
 	queryModel - subfunctions
-:)
-
+C:)
 
 declare function cmd-model:elem($collections as xs:string+, $path as xs:string, $depth as xs:integer) as element() {
@@ -153,25 +155,43 @@
 };
 
-(:
-OBSOLETE??
-:)
-declare function cmd-model:recurse-collections-model($collection as xs:string, $type-name as xs:string, $depth as xs:integer, $name as xs:string) as item()* {
-    let $children := xdb:get-child-collections($collection)
+
+(: **********************
+	getCollections - subfunctions   :)
+
+declare function cmd-model:colls($collections as xs:string+, $max-depth as xs:integer) as element() {
+		let $children := 
+	  	for $collection-item in $collections
+	   		return
+	   			for $collection-doc in cmd-model:get-resource-by-handle($collection-item) 
+	     			return cmd-model:colls-r($collection-doc, cmd-model:get-md-collection-name($collection-doc), $collection-doc//MdSelfLink, "", $max-depth)
+		let $res-count := sum($children/@cnt)
+		let $coll-count := sum($children/@cnt_subcolls) + count($children) 
+		let $data := <Collections cnt="{$res-count}" cnt_subcolls="{$coll-count}" cnt_children="{count($children)}" root="{$collections}">{$children}</Collections>			
+		return $data
+};
+
+(:
+  Recurse down in collections.
+:)
+declare function cmd-model:colls-r($collection as node(), $name as xs:string, $handle as xs:string, $proxy-id as xs:string, $depth as xs:integer) as item()* {
+  let $children :=  if ($depth eq 1) then () else cmd-model:get-children-colls($collection)
+  (: let $dummy := util:log('debug', fn:concat(cmd-model:get-md-collection-name($collection), " ", $collection//MdSelfLink, " ", xs:string($depth), " CHILDREN = ", string-join(for $child in $children return $child//MdSelfLink, "#"))) :)
     return
       if (fn:exists($children)) then
-	  let $child-results :=
-	    for $child in $children
-            return
-              cmd-model:recurse-collections-model(fn:concat($collection, '/', xs:string($child)), $type-name, $depth, $name),
-	      $current := cmd-model:create-doc($collection, $type-name, $depth, $name)
-	  return ($current, $child-results)
+	let $child-results :=
+	  for $child in $children
+	    (: let $child-doc := if (empty($child/unresolvable-uri)) then
+		cmd-model:get-resource-by-handle($child/ResourceRef) else (), :)
+            let $child-name := cmd-model:get-md-collection-name($child)
+	    let $proxyid := ($collection//ResourceProxy[ResourceRef = $child//MdSelfLink]/@id, concat("UNKNOWN proxy id:", $child//MdSelfLink))[1] 
+	    return
+	      cmd-model:colls-r($child, $child-name, $child//Header/MdSelfLink, $proxyid, $depth - 1)
+
+	  return
+	  <c n="{$name}" handle="{$handle}" proxy-id="{$proxy-id}" cnt="{sum($child-results/@cnt)}" cnt_subcolls="{if ($handle eq '') then '-1' else cmd-model:get-collection-count($handle)}" cnt_children="{count($child-results)}" >{$child-results}</c>
       else
-	cmd-model:create-doc($collection, $type-name, $depth, $name)
-};
-
-
-(: **********************
-	getCollections - subfunctions
-:)
+      	<c n="{$name}" handle="{$handle}" proxy-id="{$proxy-id}" cnt_subcolls="{if ($handle eq '') then '-1' else cmd-model:get-collection-count($handle)}" cnt="{if ($handle eq '') then '-1' else cmd-model:get-resource-count($handle)}"></c>
+
+};
 
 (:
@@ -186,33 +206,7 @@
     util:eval(concat("$collection/ft:query(descendant::MdSelfLink, <term>", xdb:decode($id), "</term>)/ancestor::CMD"))
  (: $collection/descendant::MdSelfLink[. = xdb:decode($id)]/ancestor::CMD :)
-
-};
-
-(:
-  Recurse down in collections.
-:)
-declare function cmd-model:recurse-collections($collection as node(), $name as xs:string, $handle as xs:string, $proxy-id as xs:string, $depth as xs:integer) as item()* {
-  let $children :=  if ($depth eq 0) then () else cmd-model:get-children-colls($collection)
-  let $dummy := util:log('debug', fn:concat(cmd-model:get-md-collection-name($collection), " ", $collection//MdSelfLink, " ", xs:string($depth), " CHILDREN = ", string-join(for $child in $children return $child//MdSelfLink, "#")))
-    return
-      if (fn:exists($children)) then
-	let $child-results :=
-	  for $child in $children
-	    (: let $child-doc := if (empty($child/unresolvable-uri)) then
-		cmd-model:get-resource-by-handle($child/ResourceRef) else (), :)
-            let $child-name := cmd-model:get-md-collection-name($child)
-	    let $proxyid := ($collection//ResourceProxy[ResourceRef = $child//MdSelfLink]/@id, concat("UNKNOWN proxy id:", $child//MdSelfLink))[1] 
-	    return
-	      cmd-model:recurse-collections($child, $child-name, $child//Header/MdSelfLink, $proxyid, $depth - 1)
-
-	  return
-	  <c n="{$name}" handle="{$handle}" proxy-id="{$proxy-id}" cnt="{sum($child-results/@cnt)}" cnt_subcolls="{if ($handle eq '') then '-1' else cmd-model:get-collection-count($handle)}" cnt_children="{count($child-results)}" >{$child-results}</c>
-      else
-      	<c n="{$name}" handle="{$handle}" proxy-id="{$proxy-id}" cnt_subcolls="{if ($handle eq '') then '-1' else cmd-model:get-collection-count($handle)}" cnt="{if ($handle eq '') then '-1' else cmd-model:get-resource-count($handle)}"></c>
-
-};
-
-(:
-  Get the next level collection-records (ResourceType='Metadata')
+};
+
+(:  Get the next level collection-records (ResourceType='Metadata')
   rely on the ResourceProxy of the parent (param)
 :)
@@ -238,6 +232,5 @@
 };
 
-(:
- Try to derive a name from the collection-record (more-or-less agnostic about the actual schema.
+(: Try to derive a name from the collection-record (more-or-less agnostic about the actual schema.
 :)
 declare function cmd-model:get-md-collection-name($collection-doc as node()) as xs:string {
@@ -249,43 +242,7 @@
 :)
 
-(:
-
-:)
-declare function cmd-model:create-doc($collections as xs:string+, $type-name as xs:string, $depth as xs:integer, $name as xs:string) as xs:string* {
-  (: if newer data available :)
-    cmd-model:store-result($collections, cmd-model:elem($collections, $type-name, $depth), $name, $depth)
-  (:else () :)
-};
-
-(:
-
-:)
-declare function cmd-model:get-result-doc($collections as xs:string+, $type-name as xs:string, $depth as xs:integer) as item()* {
-  let $name := cmd-model:make-compound-doc-name(($collections, $type-name), "values", xs:string($depth)),
-    $dummy := if (cmd-model:is-result-available($cmd-model:commonFreqsPath, $name)) then
-    ()
-    else
-      cmd-model:create-doc($collections, $type-name, $depth, $name)
-    return
-      cmd-model:get-doc($cmd-model:commonFreqsPath, $name)
-};
-
-(:
- Generic get-doc(collection, docname) 
-:)
-declare function cmd-model:get-doc($collection as xs:string, $doc-name as xs:string) as item()* {
-      fn:doc(fn:concat($collection, "/", $doc-name))
-};
-
-
-(:
-  Function for telling wether the result is already available or not.
-:)
-declare function cmd-model:is-result-available($collection as xs:string, $result-ref as xs:string) as xs:boolean {
-  fn:doc-available(fn:concat($collection, "/", $result-ref))
-};
-
-(:
-  Function for telling wether the document is available or not.
+
+(: Function for telling wether the document is available or not.
+generic, currently not used
 :)
 declare function cmd-model:is-doc-available($collection as xs:string, $doc-name as xs:string) as xs:boolean {
@@ -293,24 +250,19 @@
 };
 
-(:
-  Store the calculated frequencies for reuse.
-  If more than one collection is given the result is stored in the common 
-  collection for reuse.
-:)
-declare function cmd-model:store-result($coll-names as xs:string+, $entries as element()*, $type-name as xs:string, $depth as xs:integer) as xs:string {
+declare function cmd-model:is-in-cache($doc-name as xs:string) as xs:boolean {
+  fn:doc-available(fn:concat($cmd-model:cachePath, "/", $doc-name))
+};
+
+declare function cmd-model:get-from-cache($doc-name as xs:string) as item()* {
+      fn:doc(fn:concat($cmd-model:cachePath, "/", $doc-name))
+};
+
+(:  Store the collection listing for given collection.
+:)
+declare function cmd-model:store-in-cache($doc-name as xs:string, $data as node()) as item()* {
   let $clarin-writer := fn:doc("/db/clarin/writer.xml"),
-    $dummy := xdb:login($cmd-model:cmdiDatabaseURI, $clarin-writer//write-user/text(), $clarin-writer//write-user-cred/text())
-    return
-	xdb:store($cmd-model:commonFreqsPath, $type-name, cmd-model:make-doc-element-of-type($type-name, $coll-names, $entries, xs:string($depth)))
-};
-
-(:
-  Store the collection listing for given collection.
-:)
-declare function cmd-model:store-collection-data($data as node(), $collection-path as xs:string, $doc-name as xs:string) as xs:string? {
-  let $clarin-writer := fn:doc("/db/clarin/writer.xml"),
-  $dummy := xdb:login($cmd-model:cmdiDatabaseURI, $clarin-writer//write-user/text(), $clarin-writer//write-user-cred/text()),
-  $store := (: util:catch("org.exist.xquery.XPathException", :) xdb:store($collection-path, $doc-name, $data),(: , ()) :)
-  $stored-doc := doc(concat($collection-path, "/", $doc-name))
+  $dummy := xdb:login($cmd-model:cachePath, $clarin-writer//write-user/text(), $clarin-writer//write-user-cred/text())
+  let $store := (: util:catch("org.exist.xquery.XPathException", :) xdb:store($cmd-model:cachePath, $doc-name, $data), (: , ()) :)
+  $stored-doc := fn:doc(concat($cmd-model:cachePath, "/", $doc-name))
   return $stored-doc
   (: moved to get-collection
@@ -323,58 +275,11 @@
 
 (:
-  Create document name for type () with or without collection path.
-:)
-declare function cmd-model:make-doc-name($coll-name as xs:string?, $type-name as xs:string, $depth as xs:string, $incl-path as xs:boolean) as xs:string {
-  let $doc-name := fn:concat($type-name, $depth, $cmd-model:xmlExt)
-  return
-    if ($incl-path) then
-      fn:concat($coll-name, "/", $doc-name)
-    else
-      $doc-name
-};
-
-(:
   Create document name with md5-hash for selected collections (or types) for reuse.
 :)
-declare function cmd-model:make-compound-doc-name($coll-names as xs:string+, $type-name as xs:string, $depth as xs:string) as xs:string {
+declare function cmd-model:gen-cache-id($type-name as xs:string, $keys as xs:string+, $depth as xs:string) as xs:string {
   let $name-prefix := fn:concat($type-name, $depth),
-    $sorted-names := for $coll in $coll-names order by $coll ascending return $coll
+    $sorted-names := for $key in $keys order by $key ascending return $key
     return
     fn:concat($name-prefix, "-", util:hash(string-join($sorted-names, ""), "MD5"), $cmd-model:xmlExt)
-};
-
-(:
-  Skapa ett element av angiven typ. 
-:)
-declare function cmd-model:make-element-of-type($type-name as xs:string, $count as xs:string, $text-count as xs:string, $text-types-count as xs:string, $value as xs:string) as element() {
-  element {$type-name} {
-
-      attribute count {$freq},
-      attribute text-count {$rank},
-      attribute text-types-count {$text-types},
-      text {$value} 
-  }
-};
-
-(:
-  Skapa ett dokumentelement av angiven typ. 
-:)
-declare function cmd-model:make-doc-element-of-type($type-name as xs:string, $coll-names as xs:string*, $entries as element()*, $depth as xs:string) as element() {
-      let $depth-value := attribute depth {$depth},
-      $coll-names-value := if (fn:empty($coll-names)) then () else attribute colls {fn:string-join($coll-names, ",")}
-      return
-	element {cmd-model:get-doc-type-element-name($type-name)} {
-	  $depth-value,
-	  $coll-names-value,
-	  attribute created {fn:current-dateTime()},
-	  $entries
-	}
-};
-
-(:
-  Get element name for document type. 
-:)
-declare function cmd-model:get-doc-type-element-name($type-name as xs:string) as xs:string {
-  $cmd-model:docTypeTerms
 };
 
@@ -391,42 +296,2 @@
 };
 
-
-(:
-{cmdComponent} 	 //{cmdComponent} 	 Actor 	 //Actor
-{cmdPath}. 	//{cmdPath}/{cmdComponent}	Actor.Contact.Phone 	//Actor/Contact/Phone
-{cmdIndex} {rel} {term} 	//{cmdIndex}[\. {rel} '{term}'] 	Actors.Actor.Sex=f 	//Actors/Actor/Sex[.='f']
-{cmdIndex} any {term} 	//{cmdIndex}[contains(. '{term}')] 	Organisation.Name any University 	//Organisation/Name[contains(.,'University')]
-and, or, and not 	?! 	Organisation.Name any University and Actor.gender=m 	?! 
-
-//MDGroup[Actors/Actor/Role[.='sponsor'] and Actors/Actor/Name[contains(.,'a')]]
-//Title[starts-with(.,'a')]
-//Title[starts-with(.,'A')]
-//Title[contains(.,'analysis')]
-http://demo.spraakdata.gu.se/clarin/cmd/model/stats?operation=searchRetrieve&query=//Title[contains(.,'analysis')]&collection=
-
-<record>
-  <recordSchema>info:srw/schema/1/dc-v1.1</recordSchema>
-  <recordPacking>xml</recordPacking>
-  <recordData>
-    <srw_dc:dc xmlns:srw_dc="info:srw/schema/1/dc-v1.1">
-     <dc:title>This is a Sample Record</dc:title>
-    </srw_dc:dc>
-  </recordData>
-  <recordPosition>1</recordPosition>
-  <extraRecordData>
-    <rel:score xmlns:rel="info:srw/extensions/2/rel-1.0">
-      0.965
-    </rel:rank>
-   </extraRecordData>
-</record>
-
-<searchRetrieveResponse>
-	<numberOfRecords>integer</numberOfRecords>
-	<echoedSearchRetrieveRequest>query itself (together with the context-collection) </echoedSearchRetrieveRequest>
-	<diagnostics>if necessary</diagnostics>
-	<records>
-		....
-	</records>
-</searchRetrieveResponse>
-
-:)
