source: MDService/trunk/xquery/cmd-model.xqm @ 258

Last change on this file since 258 was 258, checked in by ljo, 14 years ago

cmd-model - Rudimentary version of API function getCollections

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1module namespace cmd-model = "http://spraakbanken.gu.se/clarin/xquery/model";
2
3(:
4 $Id: cmd-model.xqm 258 2010-03-19 14:32:10Z ljo $
5:)
6
7import module namespace xdb="http://exist-db.org/xquery/xmldb";
8import module namespace util="http://exist-db.org/xquery/util";
9
10declare variable $cmd-model:cmdiDatabaseURI as xs:string := "xmldb:exist:///db";
11
12declare variable $cmd-model:commonFreqsPath as xs:string := "/db/common/clarin/freqs";
13declare variable $cmd-model:cmdiMirrorPath as xs:string := "/db/cmdi-mirror";
14
15declare variable $cmd-model:getCollections as xs:string := "getCollections";
16declare variable $cmd-model:queryModel as xs:string := "queryModel";
17declare variable $cmd-model:searchRetrieve as xs:string := "searchRetrieve";
18
19declare variable $cmd-model:typeActorPath as xs:string := "MDGroup/Actors/Actor";
20declare variable $cmd-model:typeActorPath0 as xs:string := "Actor";
21declare variable $cmd-model:typeActorRolePath as xs:string := "MDGroup/Actors/Actor/Role";
22
23declare variable $cmd-model:docTypeTerms as xs:string := "Terms";
24declare variable $cmd-model:docTypeSuffix as xs:string := "Values";
25
26declare variable $cmd-model:responseFormatXml as xs:string := "xml";
27declare variable $cmd-model:responseFormatJSon as xs:string := "json";
28declare variable $cmd-model:responseFormatText as xs:string := "text";
29
30declare variable $cmd-model:xmlExt as xs:string := ".xml";
31
32declare function cmd-model:elem($collection as xs:string, $path as xs:string, $depth as xs:integer) as element() {
33  let $path-nodes := util:eval(fn:concat("collection('", $collection, "')//", $path))
34  let $path-count := count($path-nodes)
35   
36  let $subs := distinct-values($path-nodes/child::element()/name())
37  let $text-nodes := $path-nodes//text()
38  let $text-count := count($text-nodes)
39  let $text-count-distinct := count(distinct-values($text-nodes))
40  return 
41        <Term path="{fn:concat("//", $path)}" count="{$path-count}" count_text="{$text-count}"  count_distinct_text="{$text-count-distinct}">{
42          if ($depth > 0) then
43            for $elname in $subs[. != '']
44            return
45              cmd-model:elem($collection, concat($path, '/', $elname), $depth - 1)
46          else 'maxdepth'
47        }</Term>
48};
49
50declare function cmd-model:paths($n) {
51        for $el in $n
52        return <Term name="{$el/name()}"> {
53        for $anc in $el/parent::element()
54        return util:node-xpath($anc)
55        }</Term>
56};
57
58(:
59
60:)
61declare function cmd-model:recurse-collections-model($collection as xs:string, $type-name as xs:string, $depth as xs:integer) as item()* {
62    let $children := xdb:get-child-collections($collection)
63    return
64      if (fn:exists($children)) then
65          let $child-results :=
66            for $child in $children
67            return
68              cmd-model:recurse-collections-model(fn:concat($collection, '/', xs:string($child)), $type-name, $depth),
69              $current := cmd-model:create-doc($collection, $type-name, $depth)
70          return ($current, $child-results)
71      else
72        cmd-model:create-doc($collection, $type-name, $depth)
73};
74
75(:
76  Recurse for collections
77:)
78declare function cmd-model:recurse-collections($collection as xs:string, $depth as xs:integer) as item()* {
79    let $children := xdb:get-child-collections($collection)
80    return
81      if (fn:exists($children)) then
82          let $child-results :=
83            for $child in $children
84            return
85              cmd-model:recurse-collections(concat($collection, '/', xs:string($child)), $depth),
86              $current := <Collection>{$collection}</Collection>
87          return ($current, $child-results)
88      else
89      <Collection>{$collection}</Collection>
90};
91
92(:
93
94:)
95declare function cmd-model:create-doc($collection as xs:string, $type-name as xs:string, $depth as xs:integer) as xs:string* {
96  (: if newer data available :)
97    cmd-model:store-result($collection, cmd-model:elem($collection, $type-name, $depth), $type-name, $depth)
98  (:else () :)
99};
100
101(:
102
103:)
104declare function cmd-model:get-result-doc($collection as xs:string, $type-name as xs:string, $depth as xs:integer) as item()* {
105  let $name-last := text:groups($type-name, "/(\w+)$")[last()],
106    $new-name := if (fn:empty($name-last)) then $type-name else $name-last,
107    $dummy := if (cmd-model:is-result-available($collection, fn:concat("/", $new-name, xs:string($depth)))) then
108    ()
109    else
110      cmd-model:create-doc($collection, $type-name, $depth)
111    return
112      fn:doc(fn:concat($collection, "/", $new-name, xs:string($depth), $cmd-model:xmlExt))
113};
114
115(:
116  Function for telling wether the result is already available or not.
117:)
118declare function cmd-model:is-result-available($collection as xs:string, $result-ref as xs:string) as xs:boolean {
119  fn:doc-available(fn:concat($collection, $result-ref, $cmd-model:xmlExt))
120};
121
122(:
123  Store the calculated frequencies for reuse.
124  If more than one collection is given the result is stored in the common
125  collection for reuse.
126:)
127declare 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 {
128  let $clarin-writer := fn:doc("/db/clarin/writer.xml"),
129    $dummy := xdb:login($cmd-model:cmdiDatabaseURI, $clarin-writer//write-user/text(), $clarin-writer//write-user-cred/text())
130    return
131   
132      if (fn:exists($coll-names[2])) then
133        (: Det gÀller fler Àn en samling. :)
134        xdb:store($cmd-model:commonFreqsPath, cmd-model:make-compound-doc-name($coll-names, $type-name, $depth), cmd-model:make-doc-element-of-type($type-name, $coll-names, $entries, $depth))
135      else
136        (: Det gÀller endast en samling. :)
137        let $dummy := util:log('debug', fn:concat('Stores ', $type-name, ' in ', $coll-names))
138        return xdb:store($coll-names, cmd-model:make-doc-name($coll-names, $type-name, xs:string($depth), fn:false()), cmd-model:make-doc-element-of-type($type-name, (), $entries, xs:string($depth)))
139};
140
141(:
142  Create document name for type () with or without collection path.
143:)
144declare 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 {
145  let $doc-name := fn:concat($type-name, $depth, $cmd-model:xmlExt)
146  return
147    if ($incl-path) then
148      fn:concat($coll-name, "/", $doc-name)
149    else
150      $doc-name
151};
152
153(:
154  Create document name with md5-hash for selected collections (or types) for reuse.
155:)
156declare function cmd-model:make-compound-doc-name($coll-names as xs:string+, $type-name as xs:string, $depth as xs:string) as xs:string {
157  let $name-prefix := fn:concat($type-name, $depth)
158    return
159    fn:concat($name-prefix, "-", util:hash(string-join($coll-names, ""), "MD5"), $cmd-model:xmlExt)
160};
161
162(:
163  Skapa ett element av angiven typ.
164:)
165declare 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() {
166  element {$type-name} {
167
168      attribute count {$freq},
169      attribute text-count {$rank},
170      attribute text-types-count {$text-types},
171      text {$value} 
172  }
173};
174
175(:
176  Skapa ett dokumentelement av angiven typ.
177:)
178declare 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() {
179      let $depth-value := attribute depth {$depth},
180      $coll-names-value := if (fn:empty($coll-names)) then () else attribute colls {fn:string-join($coll-names, ",")}
181      return
182        element {cmd-model:get-doc-type-element-name($type-name)} {
183          $depth-value,
184          $coll-names-value,
185          attribute created {fn:current-dateTime()},
186          $entries
187        }
188};
189
190(:
191  Skapa elementnamn för dokumentet av typ.
192:)
193declare function cmd-model:get-doc-type-element-name($type-name as xs:string) as xs:string {
194  $cmd-model:docTypeTerms
195};
196
197(:
198  Seraliseringsformat.
199:)
200declare function cmd-model:serialise-as($item as node(), $format as xs:string) as item()? {
201      if ($format eq $cmd-model:responseFormatJSon) then
202        let $option := util:declare-option("exist:serialize", "method=text media-type=application/json")
203          return
204           (: json:xml-to-json($item) :) $item
205      else (: $cmd-model:responseFormatXml, $cmd-model:responseFormatText:)
206        $item
207};
208
209
210(:~
211  API function queryModel.
212:)
213declare 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() {
214        cmd-model:serialise-as(cmd-model:get-result-doc($collection, $cmd-index-path, $max-depth), $format)
215};
216
217(:~
218  API function getCollections.
219:)
220declare function cmd-model:get-collections($collections as xs:string+, $format as xs:string, $max-depth as xs:integer) as item() {
221  let $children := for $collection-item in $collections
222                    return 
223                      cmd-model:recurse-collections($collection-item, $max-depth)
224   return
225     cmd-model:serialise-as(<Collections count="{count($children)}" root="{$collections}">{$children}</Collections>, $format) 
226
227};
Note: See TracBrowser for help on using the repository browser.