fixed the paging of last page display

fixed the paging of last page display

xquery version "1.0";

(: ~
: Module Name:             Data element tabular listing
:
: Module Version           2.0
:
: Date                     13 October 2009
:
: Copyright                The cancergrid consortium
:
: Module overview          Returns a reduced, tabular view on administered items
:
:)

(:~
:    @author Steve Harris
:    @version 2.0
~ :)

declare namespace openMDR = "http://www.cagrid.org/schema/openMDR";
declare namespace ISO11179= "http://www.cagrid.org/schema/ISO11179";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace session="http://exist-db.org/xquery/session";
declare namespace util="http://exist-db.org/xquery/util";

import module namespace
lib-util="http://www.cagrid.org/xquery/library/util"
at "../library/m-lib-util.xquery";

import module namespace
administered-item="http://www.cagrid.org/xquery/library/administered-item"
at "../library/m-administered-item.xquery";

import module namespace
value-domain="http://www.cagrid.org/xquery/library/value-domain"
at "../library/m-value-domain.xquery";

import module namespace
value-meaning="http://www.cagrid.org/xquery/library/value-meaning"
at "../library/m-value-meaning.xquery";

import module namespace
lib-rendering="http://www.cagrid.org/xquery/library/rendering"
at "../web/m-lib-rendering.xquery";

(: declare option exist:serialize "media-type=text/html method=xhtml doctype-public=-//W3C//DTD XHTML 1.0 Transitional//EN doctype-system=http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-transitional.dtd"; :)

session:create(),

let $letter := request:get-parameter("letter", ())
let $start as xs:integer := xs:integer(request:get-parameter("start", 1))
let $extent as xs:integer := xs:integer(request:get-parameter("extent", 5))
let $type as xs:string := request:get-parameter("type", "data_element")
let $title as xs:string := concat(lib-util:sentence-case(lib-util:mdrElementTypeFriendly($type)), " Listing")

let $all-items :=
   for $sorted in lib-util:mdrElements($type)[.//openMDR:registration_status ne 'Superseded'
   and starts-with(lower-case(.//openMDR:containing[openMDR:preferred_designation='true']/openMDR:name), $letter)]
   let $preferred-name := administered-item:preferred-name($sorted)
   order by lower-case($preferred-name)
   return $sorted

let $count-all-items as xs:integer := xs:integer(count($all-items))

let $displayed-items :=
   for $item at $record-id in $all-items
   where $record-id >= $start and $record-id < $start + $extent
   return $item

let $content as element()* :=
    (
        if ($type='data_element')
        then lib-rendering:data-element-reduced($displayed-items)
        else (),
        if ($type='value_domain')
        then lib-rendering:value-domain-reduced($displayed-items)
        else (),
        if ($type='conceptual_domain')
        then lib-rendering:conceptual-domain-reduced($displayed-items)
        else (),
        if ($type='data_element_concept')
        then lib-rendering:admin-item($displayed-items)
        else(),
        if ($type='object_class')
        then lib-rendering:admin-item($displayed-items)
        else(),
        if ($type='property')
        then lib-rendering:admin-item($displayed-items)
        else(),
        if ($type='organisation')
        then lib-rendering:admin-item($displayed-items)
        else()
    )

return
    lib-rendering:txfrm-webpage($title,
        element content-by-letter {
        element tabular-content {
        $content,
        element index {
            element action {'contents.xquery'},
            element previous {if ($start - $extent < 1) then (1) else ($start - $extent)},
            element next {$start + $extent},
            element last { if( ($count-all-items mod $extent)=0) then ((($count-all-items idiv $extent) - 1) * $extent + 1) else( ( ($count-all-items idiv $extent) * $extent) + 1) },
            element type {$type},
            element letter {$letter},
            element start {$start},
            element extent {$extent},
            element count {$count-all-items},
            element recordlimit {if ($start + $extent <= $count-all-items) then ($start + $extent - 1) else ($count-all-items)}
        }
        }}
    )

xquery version "1.0";

(: ~
: Module Name:             Data element tabular listing
:
: Module Version           2.0
:
: Date                     13 October 2009
:
: Copyright                The cancergrid consortium
:
: Module overview          Returns a reduced, tabular view on administered items
:
:)

(:~
:    @author Steve Harris
:    @version 2.0
~ :)

declare namespace openMDR = "http://www.cagrid.org/schema/openMDR";
declare namespace ISO11179= "http://www.cagrid.org/schema/ISO11179";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace session="http://exist-db.org/xquery/session";
declare namespace util="http://exist-db.org/xquery/util";

import module namespace
lib-util="http://www.cagrid.org/xquery/library/util"
at "../library/m-lib-util.xquery";

import module namespace
administered-item="http://www.cagrid.org/xquery/library/administered-item"
at "../library/m-administered-item.xquery";

import module namespace
value-domain="http://www.cagrid.org/xquery/library/value-domain"
at "../library/m-value-domain.xquery";

import module namespace
value-meaning="http://www.cagrid.org/xquery/library/value-meaning"
at "../library/m-value-meaning.xquery";

import module namespace
lib-rendering="http://www.cagrid.org/xquery/library/rendering"
at "../web/m-lib-rendering.xquery";

(: declare option exist:serialize "media-type=text/html method=xhtml doctype-public=-//W3C//DTD XHTML 1.0 Transitional//EN doctype-system=http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-transitional.dtd"; :)

session:create(),

let $letter := request:get-parameter("letter", ())
let $start as xs:integer := xs:integer(request:get-parameter("start", 1))
let $extent as xs:integer := xs:integer(request:get-parameter("extent", 5))
let $type as xs:string := request:get-parameter("type", "data_element")
let $title as xs:string := concat(lib-util:sentence-case(lib-util:mdrElementTypeFriendly($type)), " Listing")

let $all-items :=
   for $sorted in lib-util:mdrElements($type)[.//openMDR:registration_status ne 'Superseded'
   and starts-with(lower-case(.//openMDR:containing[openMDR:preferred_designation='true']/openMDR:name), $letter)]
   let $preferred-name := administered-item:preferred-name($sorted)
   order by lower-case($preferred-name)
   return $sorted

let $count-all-items as xs:integer := xs:integer(count($all-items))

let $displayed-items :=
   for $item at $record-id in $all-items
   where $record-id >= $start and $record-id < $start + $extent
   return $item

let $content as element()* :=
    (
        if ($type='data_element')
        then lib-rendering:data-element-reduced($displayed-items)
        else (),
        if ($type='value_domain')
        then lib-rendering:value-domain-reduced($displayed-items)
        else (),
        if ($type='conceptual_domain')
        then lib-rendering:conceptual-domain-reduced($displayed-items)
        else (),
        if ($type='data_element_concept')
        then lib-rendering:admin-item($displayed-items)
        else(),
        if ($type='object_class')
        then lib-rendering:admin-item($displayed-items)
        else(),
        if ($type='property')
        then lib-rendering:admin-item($displayed-items)
        else(),
        if ($type='organisation')
        then lib-rendering:admin-item($displayed-items)
        else()
    )

return
    lib-rendering:txfrm-webpage($title,
        element content-by-letter {
        element tabular-content {
        $content,
        element index {
            element action {'contents.xquery'},
            element previous {if ($start - $extent < 1) then (1) else ($start - $extent)},
            element next {$start + $extent},
            element last { ($count-all-items mod $extent) * $extent +1},
            element type {$type},
            element letter {$letter},
            element start {$start},
            element extent {$extent},
            element count {$count-all-items},
            element recordlimit {if ($start + $extent <= $count-all-items) then ($start + $extent - 1) else ($count-all-items)}
        }
        }}
    )


fixup

fixup

(:~
: This is a module conttaining configuration options for the openinfoman webap
: @version 1.0
: @see https://github.com/openhie/openinfoman @see http://ihe.net
:
:)

module namespace csd_webui = "https://github.com/openhie/openinfoman/csd_webui";
import module namespace functx = "http://www.functx.com";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace request = "http://exquery.org/ns/request";

declare function csd_webui:generateURL() {
  csd_webui:generateURL(())
};

declare function csd_webui:generateURL($end) {
  let $cend :=
    string-join(
      for $e in $end
      return replace(replace(string($e),'^/+',''),'/+$','')
      ,'/')

  let $cbegin :=
    if (functx:all-whitespace($csd_webconf:baseurl))
    then concat(request:scheme(),"://",request:hostname(),":",request:port())
    else replace($csd_webconf:baseurl, '/+$', '')

  return concat($cbegin,'/',$cend)

};

declare function csd_webui:nocache($response)
{(
  <rest:response>
    <http:response >
      <http:header name="Cache-Control" value="must-revalidate,no-cache,no-store"/>
    </http:response>
  </rest:response>
  ,
  $response
)};

declare function csd_webui:redirect() as element(restxq:redirect) {
  csd_webui:redirect(())
};

declare function csd_webui:redirect($end ) as element(restxq:redirect)
{
  <restxq:redirect>{ csd_webui:generateURL($end) }</restxq:redirect>
};

declare function csd_webui:redirect_out() as element(restxq:redirect) {
  csd_webui:redirect_out(())
};

declare function csd_webui:redirect_out($end ) as element(restxq:redirect)
{
  db:output(<restxq:redirect>{ csd_webui:generateURL($end)}</restxq:redirect>)
};

declare function csd_webui:wrapper($content) {
  csd_webui:wrapper($content,())
};

declare function csd_webui:wrapper($content,$headers) {

    <link href="{csd_webui:generateURL('static/bootstrap/css/bootstrap.css')}" rel="stylesheet"/>
    <link href="{csd_webui:generateURL('static/bootstrap/css/bootstrap-theme.css')}" rel="stylesheet"/>
    <link rel="shortcut icon" href="{csd_webui:generateURL('static/favicon.ico')}"/>

(:~
: This is a module conttaining configuration options for the openinfoman webap
: @version 1.0
: @see https://github.com/openhie/openinfoman @see http://ihe.net
:
:)

module namespace csd_webui = "https://github.com/openhie/openinfoman/csd_webui";
import module namespace functx = "http://www.functx.com";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace request = "http://exquery.org/ns/request";

declare function csd_webui:generateURL() {
  csd_webui:generateURL(())
};

declare function csd_webui:generateURL($end) {
  let $cend :=
    string-join(
      for $e in $end
      return replace(replace(string($e),'^/+',''),'/+$','')
      ,'/')

  let $cbegin :=
    if (functx:all-whitespace($csd_webconf:baseurl))
    then concat(request:scheme(),"://",request:hostname(),":",request:port())
    else replace($csd_webconf:baseurl, '/+$', '')

  return concat($cbegin,'/',$cend)

};

declare function csd_webui:nocache($response)
{(
  <rest:response>
    <http:response >
      <http:header name="Cache-Control" value="must-revalidate,no-cache,no-store"/>
    </http:response>
  </rest:response>
  ,
  $response
)};

declare function csd_webui:redirect() as element(restxq:redirect) {
  csd_webui:redirect(())
};

declare function csd_webui:redirect($end ) as element(restxq:redirect)
{
  <restxq:redirect>{ csd_webui:generateURL($end) }</restxq:redirect>
};

declare function csd_webui:redirect_out() as element(restxq:redirect) {
  csd_webui:redirect_out(())
};

declare function csd_webui:redirect_out($end ) as element(restxq:redirect)
{
  db:output(<restxq:redirect>{ csd_webui:generateURL($end)}</restxq:redirect>)
};

declare function csd_webui:wrapper($content) {
  csd_webui:wrapper($content,())
};

declare function csd_webui:wrapper($content,$headers) {

    <link href="{$csd_webui:generateURL('static/bootstrap/css/bootstrap.css')}" rel="stylesheet"/>
    <link href="{$csd_webui:generateURL('static/bootstrap/css/bootstrap-theme.css')}" rel="stylesheet"/>
    <link rel="shortcut icon" href="{$csd_webui:generateURL(,'static/favicon.ico')}"/>


relax check of csd:careServicesRequest//(csd:\?)requestParams on updating functions

(:~
: This is the Care Services Discovery RESTful document processor
: @version 1.0
: @see https://github.com/his-interop/openinfoman
:
:)
module namespace csr_proc = "https://github.com/his-interop/openinfoman/csr_proc";

(:import module namespace csd_bsq = "https://github.com/his-interop/openinfoman/csd_bsq" at "csd_base_stored_queries.xqm";
import module namespace csd_hwr = "https://github.com/his-interop/openinfoman-hwr/csd_hwr" at "csd_health_worker_registry.xqm";
import module namespace csd_hwru = "https://github.com/his-interop/openinfoman-hwr/csd_hwru" at "csd_health_worker_registry_updating.xqm";
:)

declare   namespace   csd = "urn:ihe:iti:csd:2013";

(:this should proabably be moved to the database :)
declare variable $csr_proc:stored_query_dir := "../resources/stored_query_definitions";
declare variable $csr_proc:stored_updating_query_dir := "../resources/stored_updating_query_definitions";

declare variable $csr_proc:stored_functions_doc := 'stored_functions.xml';
declare variable $csr_proc:stored_updating_functions_doc := 'stored_updating_functions.xml';

declare function csr_proc:stored_functions($db) {
 db:open($db,$csr_proc:stored_functions_doc)/careServicesFunctions/csd:careServicesFunction
};

declare function csr_proc:stored_updating_functions($db) {
 db:open($db,$csr_proc:stored_updating_functions_doc)/careServicesFunctions/csd:careServicesFunction
};

declare updating function csr_proc:init($db) {
  (
    if (not (db:is-xml($db,$csr_proc:stored_updating_functions_doc))) then
      db:add($db, <careServicesFunctions/>,$csr_proc:stored_updating_functions_doc)
    else
      ()
      ,
    if (not (db:is-xml($db,$csr_proc:stored_functions_doc))) then
      db:add($db, <careServicesFunctions/>,$csr_proc:stored_functions_doc)
    else
      ()
  )
};

declare updating function csr_proc:clear_stored_functions($db) {
  (
    db:delete($db,$csr_proc:stored_functions_doc)
    ,db:delete($db,$csr_proc:stored_updating_functions_doc)
    ,csr_proc:init($db)
    )

};

declare updating function csr_proc:load_functions_from_files($db) {
  (
    if (file:is-dir($csr_proc:stored_query_dir)) then
      for $file in file:list($csr_proc:stored_query_dir,boolean('false'),"*.xml")
      let $func := doc(concat($csr_proc:stored_query_dir,'/',$file))/csd:careServicesFunction
      return if (exists($func)) then csr_proc:load_stored_function($db,$func) else ()
    else()
      ,
    if (file:is-dir($csr_proc:stored_updating_query_dir)) then
      for $file in file:list($csr_proc:stored_updating_query_dir,boolean('false'),"*.xml")
      let $func := doc(concat($csr_proc:stored_updating_query_dir,'/',$file))/csd:careServicesFunction
      return if (exists($func)) then csr_proc:load_stored_updating_function($db,$func) else ()
    else ()
  )
};

declare updating function csr_proc:delete_stored_function($db,$uuid) {
  let $stored_updating_functions := db:open($db,$csr_proc:stored_updating_functions_doc)/careServicesFunctions/*
  let $stored_functions := db:open($db,$csr_proc:stored_functions_doc)/careServicesFunctions/*
  let $functions := ($stored_functions,$stored_updating_functions)

  let $old := $functions[@uuid = $uuid]
  return if ($old) then delete node $old else ()

};

declare updating function csr_proc:load_stored_updating_function($db,$func) {
  let $stored_updating_functions := db:open($db,$csr_proc:stored_updating_functions_doc)/careServicesFunctions
  let $uuid := $func/@uuid
  let $old := $stored_updating_functions/csd:careServicesFunction[@uuid = $uuid]
  return
    if (exists($uuid)) then
      if (exists($old))
	then
	(delete node $old,
	insert node $func into $stored_updating_functions
	)
      else
	insert node $func into $stored_updating_functions
  else ()
};

declare updating function csr_proc:load_stored_function($db,$func) {
  let $stored_functions := db:open($db,$csr_proc:stored_functions_doc)/careServicesFunctions
  let $uuid := $func/@uuid
  let $old := $stored_functions/csd:careServicesFunction[@uuid = $uuid]
  return
    if (exists($uuid) and exists($stored_functions)) then
      if (exists($old))
	then
	(delete node $old,
	insert node $func into $stored_functions
	)
      else
	insert node $func into $stored_functions
    else ()
};

declare function csr_proc:process_CSR($db,$careServicesRequest, $doc)
{
let $func :=$careServicesRequest/csd:function
let $adhoc :=$careServicesRequest/csd:expression
return if (exists($func))
then
  csr_proc:process_CSR_stored($db,$func,$doc)
else if (exists($adhoc))
then
  csr_proc:process_CSR_adhoc($adhoc,$doc)
else
 (:
  <rest:response>
    <http:response status="400" message="Invalid care services request.">
      <http:header name="Content-Language" value="en"/>
      <http:header name="Content-Type" value="text/html; charset=utf-8"/>
    </http:response>
  </rest:response>
  :)
  $careServicesRequest

};

declare function csr_proc:process_CSR_adhoc($expression,$doc)
{

let $expr :=string($expression)
return if ($expr) then
  let $result := xquery:eval($expr,map{"":=$doc})
  return(
   <rest:response>
   <http:response status="200" >
      <http:header name="Content-Type" value="{$expression/@content-type}"/>
    </http:response>
  </rest:response>
  ,$result
 )
else
   <rest:response>
     <http:response status="400" message="No ad-hoc expression" />
  </rest:response>
};

declare function csr_proc:process_CSR_stored($db,$function,$doc)
{
let $uuid := $function/@uuid
let $stored_functions := csr_proc:stored_functions($db)
let $definition := $stored_functions[@uuid = $uuid][1]/csd:definition/text()
let $content_type := csr_proc:lookup_stored_content_type($db,$function/@uuid)
let $requestParams :=
  if ($function/requestParams) then $function/requestParams
  else if ($function/csd:requestParams) then $function/csd:requestParams
  else <requestParams/>
let $result0 :=
  if (exists($definition)) then
    xquery:eval($definition,map{'':=$doc,'careServicesRequest':=$requestParams})
  else
    ()
let $result1:=
  if ($function/@encapsulated) then
    csr_proc:wrap_result($result0,$content_type)
  else $result0
return if ($result0) then
  (
  <rest:response>
    <http:response status="200" >
      <http:header name="Content-Type" value="{$content_type}"/>
    </http:response>
  </rest:response>
  ,
  $result1
  )
else
  <rest:response>
    <http:response status="404" message="No registered function with UUID='{$function/@uuid}'.">
      <http:header name="Content-Language" value="en"/>
      <http:header name="Content-Type" value="text/html; charset=utf-8"/>
    </http:response>
  </rest:response>

};

declare function csr_proc:wrap_result($result,$content-type) {
 <csd:careServicesResponse content-type="{$content-type}"><csd:result>{$result}</csd:result></csd:careServicesResponse>
};

declare function csr_proc:create_adhoc_doc($adhoc_query,$content_type) {
let $content := if ($content_type) then $content_type else "application/xml"
return
 <csd:careServicesRequest xmlns:csd='urn:ihe:iti:csd:2013'>
  <csd:expression content-type='{$content}'>
  {$adhoc_query}
  </csd:expression>
</csd:careServicesRequest>

};

declare function csr_proc:get_function_definition($db,$uuid) {
  csr_proc:stored_functions($db)[@uuid = $uuid][1]
};

declare function csr_proc:get_updating_function_definition($db,$uuid) {
  csr_proc:stored_updating_functions($db)[@uuid = $uuid][1]
};

declare updating function csr_proc:process_updating_CSR($db,$careServicesRequest, $doc)
{
(:not allowing ad-hoc updates:)
let $function :=$careServicesRequest//csd:function
let $uuid := $function/@uuid
let $stored_updating_functions := csr_proc:stored_updating_functions($db)
let $definition := $stored_updating_functions[@uuid = $uuid][1]/csd:definition/text()
let $content_type := csr_proc:lookup_stored_content_type($db,$function/@uuid)
let $requestParams :=
  if ($function/requestParams) then $function/requestParams
  else if ($function/csd:requestParams) then $function/csd:requestParams
  else <requestParams/>
return if (exists($definition)) then
  xquery:update($definition,map{'':=$doc,'careServicesRequest':=$requestParams})
else
    db:output(
    <rest:response>
      <http:response status="404" message="No registered updating function with UUID='{$function/@uuid} ">
	<http:header name="Content-Language" value="en"/>
	<http:header name="Content-Type" value="text/html; charset=utf-8"/>
      </http:response>
    </rest:response>
       )
};

declare function csr_proc:lookup_stored_content_type($db,$uuid)
{
  let $stored_updating_functions := csr_proc:stored_updating_functions($db)
  let $stored_functions := csr_proc:stored_functions($db)
  return string(($stored_functions[@uuid = $uuid]/@content-type, $stored_updating_functions[@uuid = $uuid]/@content-type  , "text/xml")[1])
};

(:~
: This is the Care Services Discovery RESTful document processor
: @version 1.0
: @see https://github.com/his-interop/openinfoman
:
:)
module namespace csr_proc = "https://github.com/his-interop/openinfoman/csr_proc";

(:import module namespace csd_bsq = "https://github.com/his-interop/openinfoman/csd_bsq" at "csd_base_stored_queries.xqm";
import module namespace csd_hwr = "https://github.com/his-interop/openinfoman-hwr/csd_hwr" at "csd_health_worker_registry.xqm";
import module namespace csd_hwru = "https://github.com/his-interop/openinfoman-hwr/csd_hwru" at "csd_health_worker_registry_updating.xqm";
:)

declare   namespace   csd = "urn:ihe:iti:csd:2013";

(:this should proabably be moved to the database :)
declare variable $csr_proc:stored_query_dir := "../resources/stored_query_definitions";
declare variable $csr_proc:stored_updating_query_dir := "../resources/stored_updating_query_definitions";

declare variable $csr_proc:stored_functions_doc := 'stored_functions.xml';
declare variable $csr_proc:stored_updating_functions_doc := 'stored_updating_functions.xml';

declare function csr_proc:stored_functions($db) {
 db:open($db,$csr_proc:stored_functions_doc)/careServicesFunctions/csd:careServicesFunction
};

declare function csr_proc:stored_updating_functions($db) {
 db:open($db,$csr_proc:stored_updating_functions_doc)/careServicesFunctions/csd:careServicesFunction
};

declare updating function csr_proc:init($db) {
  (
    if (not (db:is-xml($db,$csr_proc:stored_updating_functions_doc))) then
      db:add($db, <careServicesFunctions/>,$csr_proc:stored_updating_functions_doc)
    else
      ()
      ,
    if (not (db:is-xml($db,$csr_proc:stored_functions_doc))) then
      db:add($db, <careServicesFunctions/>,$csr_proc:stored_functions_doc)
    else
      ()
  )
};

declare updating function csr_proc:clear_stored_functions($db) {
  (
    db:delete($db,$csr_proc:stored_functions_doc)
    ,db:delete($db,$csr_proc:stored_updating_functions_doc)
    ,csr_proc:init($db)
    )

};

declare updating function csr_proc:load_functions_from_files($db) {
  (
    if (file:is-dir($csr_proc:stored_query_dir)) then
      for $file in file:list($csr_proc:stored_query_dir,boolean('false'),"*.xml")
      let $func := doc(concat($csr_proc:stored_query_dir,'/',$file))/csd:careServicesFunction
      return if (exists($func)) then csr_proc:load_stored_function($db,$func) else ()
    else()
      ,
    if (file:is-dir($csr_proc:stored_updating_query_dir)) then
      for $file in file:list($csr_proc:stored_updating_query_dir,boolean('false'),"*.xml")
      let $func := doc(concat($csr_proc:stored_updating_query_dir,'/',$file))/csd:careServicesFunction
      return if (exists($func)) then csr_proc:load_stored_updating_function($db,$func) else ()
    else ()
  )
};

declare updating function csr_proc:delete_stored_function($db,$uuid) {
  let $stored_updating_functions := db:open($db,$csr_proc:stored_updating_functions_doc)/careServicesFunctions/*
  let $stored_functions := db:open($db,$csr_proc:stored_functions_doc)/careServicesFunctions/*
  let $functions := ($stored_functions,$stored_updating_functions)

  let $old := $functions[@uuid = $uuid]
  return if ($old) then delete node $old else ()

};

declare updating function csr_proc:load_stored_updating_function($db,$func) {
  let $stored_updating_functions := db:open($db,$csr_proc:stored_updating_functions_doc)/careServicesFunctions
  let $uuid := $func/@uuid
  let $old := $stored_updating_functions/csd:careServicesFunction[@uuid = $uuid]
  return
    if (exists($uuid)) then
      if (exists($old))
	then
	(delete node $old,
	insert node $func into $stored_updating_functions
	)
      else
	insert node $func into $stored_updating_functions
  else ()
};

declare updating function csr_proc:load_stored_function($db,$func) {
  let $stored_functions := db:open($db,$csr_proc:stored_functions_doc)/careServicesFunctions
  let $uuid := $func/@uuid
  let $old := $stored_functions/csd:careServicesFunction[@uuid = $uuid]
  return
    if (exists($uuid) and exists($stored_functions)) then
      if (exists($old))
	then
	(delete node $old,
	insert node $func into $stored_functions
	)
      else
	insert node $func into $stored_functions
    else ()
};

declare function csr_proc:process_CSR($db,$careServicesRequest, $doc)
{
let $func :=$careServicesRequest/csd:function
let $adhoc :=$careServicesRequest/csd:expression
return if (exists($func))
then
  csr_proc:process_CSR_stored($db,$func,$doc)
else if (exists($adhoc))
then
  csr_proc:process_CSR_adhoc($adhoc,$doc)
else
 (:
  <rest:response>
    <http:response status="400" message="Invalid care services request.">
      <http:header name="Content-Language" value="en"/>
      <http:header name="Content-Type" value="text/html; charset=utf-8"/>
    </http:response>
  </rest:response>
  :)
  $careServicesRequest

};

declare function csr_proc:process_CSR_adhoc($expression,$doc)
{

let $expr :=string($expression)
return if ($expr) then
  let $result := xquery:eval($expr,map{"":=$doc})
  return(
   <rest:response>
   <http:response status="200" >
      <http:header name="Content-Type" value="{$expression/@content-type}"/>
    </http:response>
  </rest:response>
  ,$result
 )
else
   <rest:response>
     <http:response status="400" message="No ad-hoc expression" />
  </rest:response>
};

declare function csr_proc:process_CSR_stored($db,$function,$doc)
{
let $uuid := $function/@uuid
let $stored_functions := csr_proc:stored_functions($db)
let $definition := $stored_functions[@uuid = $uuid][1]/csd:definition/text()
let $content_type := csr_proc:lookup_stored_content_type($db,$function/@uuid)
let $requestParams :=
  if ($function/requestParams) then $function/requestParams
  else if ($function/csd:requestParams) then $function/csd:requestParams
  else <requestParams/>
let $result0 :=
  if (exists($definition)) then
    xquery:eval($definition,map{'':=$doc,'careServicesRequest':=$requestParams})
  else
    ()
let $result1:=
  if ($function/@encapsulated) then
    csr_proc:wrap_result($result0,$content_type)
  else $result0
return if ($result0) then
  (
  <rest:response>
    <http:response status="200" >
      <http:header name="Content-Type" value="{$content_type}"/>
    </http:response>
  </rest:response>
  ,
  $result1
  )
else
  <rest:response>
    <http:response status="404" message="No registered function with UUID='{$function/@uuid}'.">
      <http:header name="Content-Language" value="en"/>
      <http:header name="Content-Type" value="text/html; charset=utf-8"/>
    </http:response>
  </rest:response>

};

declare function csr_proc:wrap_result($result,$content-type) {
 <csd:careServicesResponse content-type="{$content-type}"><csd:result>{$result}</csd:result></csd:careServicesResponse>
};

declare function csr_proc:create_adhoc_doc($adhoc_query,$content_type) {
let $content := if ($content_type) then $content_type else "application/xml"
return
 <csd:careServicesRequest xmlns:csd='urn:ihe:iti:csd:2013'>
  <csd:expression content-type='{$content}'>
  {$adhoc_query}
  </csd:expression>
</csd:careServicesRequest>

};

declare function csr_proc:get_function_definition($db,$uuid) {
  csr_proc:stored_functions($db)[@uuid = $uuid][1]
};

declare function csr_proc:get_updating_function_definition($db,$uuid) {
  csr_proc:stored_updating_functions($db)[@uuid = $uuid][1]
};

declare updating function csr_proc:process_updating_CSR($db,$careServicesRequest, $doc)
{
(:not allowing ad-hoc updates:)
let $function :=$careServicesRequest//csd:function
let $uuid := $function/@uuid
let $stored_updating_functions := csr_proc:stored_updating_functions($db)
let $definition := $stored_updating_functions[@uuid = $uuid][1]/csd:definition/text()
let $content_type := csr_proc:lookup_stored_content_type($db,$function/@uuid)
return if (exists($definition)) then
  xquery:update($definition,map{'':=$doc,'careServicesRequest':=$function/requestParams})
else
    db:output(
    <rest:response>
      <http:response status="404" message="No registered updating function with UUID='{$function/@uuid} ">
	<http:header name="Content-Language" value="en"/>
	<http:header name="Content-Type" value="text/html; charset=utf-8"/>
      </http:response>
    </rest:response>
       )
};

declare function csr_proc:lookup_stored_content_type($db,$uuid)
{
  let $stored_updating_functions := csr_proc:stored_updating_functions($db)
  let $stored_functions := csr_proc:stored_functions($db)
  return string(($stored_functions[@uuid = $uuid]/@content-type, $stored_updating_functions[@uuid = $uuid]/@content-type  , "text/xml")[1])
};