xquery version "1.0-ml";
(:
: Content Query Tool (cq)
:
: Copyright (c) 2002-2010 Mark Logic Corporation. All Rights Reserved.
:
: Licensed under the Apache License, Version 2.0 (the "License");
: you may not use this file except in compliance with the License.
: You may obtain a copy of the License at
:
: http://www.apache.org/licenses/LICENSE-2.0
:
: Unless required by applicable law or agreed to in writing, software
: distributed under the License is distributed on an "AS IS" BASIS,
: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
: See the License for the specific language governing permissions and
: limitations under the License.
:
: The use of the Apache License does not indicate that this project is
: affiliated with the Apache Software Foundation.
:
: explore.xqy - fancy list of up to N documents, including root node type.
:
: TODO use cts:uris(), if available? interferes with element-display...
:
:)
import module namespace admin = "http://marklogic.com/xdmp/admin"
at "/MarkLogic/admin.xqy";
import module namespace c = "com.marklogic.developer.cq.controller"
at "lib-controller.xqy";
import module namespace d = "com.marklogic.developer.cq.debug"
at "lib-debug.xqy";
import module namespace v = "com.marklogic.developer.cq.view"
at "lib-view.xqy";
import module namespace x = "com.marklogic.developer.cq.xquery"
at "lib-xquery.xqy";
declare option xdmp:mapping "false";
declare variable $FILTER as xs:string external;
declare variable $FILTER-TEXT as xs:string external;
declare variable $SIZE as xs:integer external;
declare variable $START as xs:integer external;
declare variable $FILTER-QUERY as cts:query? :=
let $d := d:debug(('explore-invokable: FILTER =', $FILTER))
let $filter as cts:query? :=
if ($FILTER eq '') then () else cts:query(xdmp:unquote($FILTER)/*)
let $d := d:debug(('explore-invokable: FILTER-TEXT =', $FILTER-TEXT))
let $filter-text as cts:query? :=
if ($FILTER-TEXT eq '') then () else cts:word-query($FILTER-TEXT)
return
if (exists($filter) and exists($filter-text))
then cts:and-query(($filter, $filter-text))
else if (exists($filter-text)) then $filter-text
else $filter
;
d:check-debug(),
d:debug(('explore-invokable:', $START, $SIZE)),
c:set-content-type(),
xdmp:query-trace($d:DEBUG),
d:debug(('explore-invokable:', $FILTER, $FILTER-TEXT)),
(: make sure we will not lock all the documents :)
c:assert-read-only(),
let $stop := $START + $SIZE - 1
let $query := $FILTER-QUERY
let $d := d:debug(('explore-invokable: query =', $query))
(: no point in trying cts:uris(), as we will retrieve N fragments anyhow :)
let $result := (
if (exists($query)) then cts:search(doc(), $query, 'unfiltered')
else doc()
)[$START to $stop]
let $count :=
if (empty($query)) then xdmp:estimate(doc())
else if ($result) then cts:remainder($result[1])
else 0
let $database-name := xdmp:database-name($c:FORM-EVAL-DATABASE-ID)
let $actual-stop := min(($stop, $START + count($result) - 1))
return {
element head { v:get-html-head() },
element body {
element p {
attribute class { 'head2' },
'Database ', element b { $database-name }, ' contains ',
$count, 'document(s) total',
if ($count) then (
' (viewing', $START, '-', concat(string($actual-stop), ')')
)
else ()
},
(: TODO display any filters in effect? :)
for $i in $result
let $uri := xdmp:node-uri($i)
(: make sure we can handle oddball docs -
: what if the root is a processing instruction?
: empty doc is also possible, in XQuery 1.0
:)
let $n as node()* := $i/node()
let $n as node()? :=
if ($n instance of binary()) then $n
else if ($n instance of text()) then $n
else if ($n/self::*) then $n/self::*[1]
(: comment, processing instruction, etc.
: but if only text is present, a previous rule already matched
:)
else $n[not(. instance of text())][1]
order by $uri
return (
element a {
attribute href { c:build-form-eval-query('view.xqy', 'uri', $uri) },
$uri
},
– ,
{ if ($n) then xdmp:node-kind($n) else '(empty document)' },
(: why not node-name? because this is a human-readable context :)
{ name($n) } ,
element span {
if (not($i/property::node())) then element i { '(no properties)' }
else element a {
attribute href {
c:build-form-eval-query(
'view.xqy', ('uri', 'properties'), ($uri, 1)
)
},
'(properties)'
}
},
,
element span {
let $collections := xdmp:document-get-collections($uri)
return
if (not($collections)) then element i { '(no collections)' }
else (
element i { 'collections' }, ':',
let $count := count($collections)
let $filters :=
if (empty($query)) then ()
else if ($query instance of cts:collection-query)
then $query
else cts:and-query-queries($query)
[. instance of cts:collection-query]
let $filters :=
for $i in $filters return xdmp:quote( document { $i })
for $c at $x in $collections
let $term := xdmp:quote( document { cts:collection-query($c) })
(: check for duplicate terms :)
let $is-duplicate := ($filters = $term)
let $filters :=
($filters, if ($is-duplicate) then () else $term)
let $keys := for $i in $filters return 'filter'
return (
if ($is-duplicate) then element span { $c }
else element a {
attribute href {
c:pagination-href($START, $keys, $filters)
},
$c
},
if ($x ne $count) then '; ' else ()
)
)
},
(: TODO permissions? :)
),
v:display-results-pagination($START, count($result), $count, $SIZE)
}
}
(: explore-invokable.xqy :)