Fix util test cases

Fix util test cases

xquery version "3.1";

(:~
 : Tests for reading and parsing.
 :)
module namespace test = 'http://xokomola.com/xquery/origami/tests';

import module namespace o = 'http://xokomola.com/xquery/origami'
    at '../origami.xqm';

declare %unit:test function test:select-keys()
{
    unit:assert-equals(
        o:select-keys((),()),
        map {},
        "Empty $map and $keys arguments produces an empty map"
    ),
    unit:assert-equals(
        o:select-keys(map {},('a')),
        map {},
        "Empty $map argument produces an empty map"
    ),
    unit:assert-equals(
        o:select-keys(map {'a': 1},('a')),
        map {'a': 1},
        "Single $key produces a new map with that key"
    ),
    unit:assert-equals(
        o:select-keys(map {'b': 2},('a')),
        map {},
        "Single $key that is not in map produces an empty map"
    ),
    unit:assert-equals(
        o:select-keys(map {'a': 1, 'b': 2, 'c': 3},('a','b')),
        map {'a': 1, 'b': 2},
        "Multiple keys produce a new map with only these keys"
    )
};

xquery version "3.1";

(:~
 : Tests for reading and parsing.
 :)
module namespace test = 'http://xokomola.com/xquery/origami/tests';

import module namespace u = 'http://xokomola.com/xquery/origami/utils' at '../utils.xqm';

declare %unit:test function test:select-keys()
{
    unit:assert-equals(
        u:select-keys((),()),
        map {},
        "Empty $map and $keys arguments produces an empty map"
    ),
    unit:assert-equals(
        u:select-keys(map {},('a')),
        map {},
        "Empty $map argument produces an empty map"
    ),
    unit:assert-equals(
        u:select-keys(map {'a': 1},('a')),
        map {'a': 1},
        "Single $key produces a new map with that key"
    ),
    unit:assert-equals(
        u:select-keys(map {'b': 2},('a')),
        map {},
        "Single $key that is not in map produces an empty map"
    ),
    unit:assert-equals(
        u:select-keys(map {'a': 1, 'b': 2, 'c': 3},('a','b')),
        map {'a': 1, 'b': 2},
        "Multiple keys produce a new map with only these keys"
    )
};


Update eval.xql

Update eval.xql

xquery version "3.0";

module namespace eval="http://exist-db.org/mongodb/test/eval";

import module namespace xqjson = "http://xqilla.sourceforge.net/lib/xqjson";

import module namespace test="http://exist-db.org/xquery/xqsuite"
                at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql";

import module namespace mongodb = "http://exist-db.org/xquery/mongodb"
                at "java:org.exist.mongodb.xquery.MongodbModule";

import module namespace support = "http://exist-db.org/ext/mongodb/test/support"
                at "./support.xqm";

(: Connect to mongodb, store token :)
declare %test:setUp function eval:setup()
{
    support:setup()
};

(: Disconnect from mongodb, cleanup token :)
declare %test:tearDown function eval:cleanup()
{
    support:cleanup()
};

(: ----------------------------
 : Actual tests below this line
 : ----------------------------:)

(:
 : collection#eval(two params)  integer -> double
 :)
declare
    %test:assertEquals(7)
function eval:eval_numbers() {
    let $mongodbClientId := support:getToken()
    let $eval:= mongodb:eval($mongodbClientId, $support:database,

    (: Javascript :)
    'function( x, y ) { return x + y; }',

    (: Parameters :)
    (2, 5)   )

    return $eval
};

(:
 : collection#eval(one parameter) string
 :)
declare
    %test:assertEquals("test")
function eval:eval_string() {
    let $mongodbClientId := support:getToken()
    let $eval:= mongodb:eval($mongodbClientId, $support:database,

    (: Javascript :)
    'function( value ) { return value; }',

    (: Parameters :)
    ("test")   )

    return $eval
};

(:
 : collection#eval()
 : <json type="object">
 : <pair name="x" type="number">1.0</pair>
 : <pair name="y" type="number">2.0</pair>
 : </json>
 :)
declare
    %test:assertEquals(2)
function eval:eval_json() {
    let $mongodbClientId := support:getToken()
    let $eval:= mongodb:eval($mongodbClientId, $support:database,

    (: Javascript :)
    'function() { return { x : 1 ,  y : 2 } }' )

    return count(xqjson:parse-json($eval)//pair)
};

xquery version "3.0";

module namespace eval="http://exist-db.org/mongodb/test/eval";

import module namespace xqjson = "http://xqilla.sourceforge.net/lib/xqjson";

import module namespace test="http://exist-db.org/xquery/xqsuite"
                at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql";

import module namespace mongodb = "http://exist-db.org/xquery/mongodb"
                at "java:org.exist.mongodb.xquery.MongodbModule";

import module namespace support = "http://exist-db.org/ext/mongodb/test/support"
                at "./support.xqm";

(: Connect to mongodb, store token :)
declare %test:setUp function eval:setup()
{
    support:setup()
};

(: Disconnect from mongodb, cleanup token :)
declare %test:tearDown function eval:cleanup()
{
    support:cleanup()
};

(: ----------------------------
 : Actual tests below this line
 : ----------------------------:)

(:
 : collection#eval(two params)  integer -> double
 :
 : TODO: Check why only text "7.0" works
 :)
declare
    %test:assertEquals(7)
function eval:eval_numbers() {
    let $mongodbClientId := support:getToken()
    let $eval:= mongodb:eval($mongodbClientId, $support:database,

    (: Javascript :)
    'function( x, y ) { return x + y; }',

    (: Parameters :)
    (2, 5)   )

    return $eval
};

(:
 : collection#eval(one parameter) string
 :)
declare
    %test:assertEquals("test")
function eval:eval_string() {
    let $mongodbClientId := support:getToken()
    let $eval:= mongodb:eval($mongodbClientId, $support:database,

    (: Javascript :)
    'function( value ) { return value; }',

    (: Parameters :)
    ("test")   )

    return $eval
};

(:
 : collection#eval()
 : <json type="object">
 : <pair name="x" type="number">1.0</pair>
 : <pair name="y" type="number">2.0</pair>
 : </json>
 :)
declare
    %test:assertEquals(2)
function eval:eval_json() {
    let $mongodbClientId := support:getToken()
    let $eval:= mongodb:eval($mongodbClientId, $support:database,

    (: Javascript :)
    'function() { return { x : 1 ,  y : 2 } }' )

    return count(xqjson:parse-json($eval)//pair)
};


improved work uris script

improved work uris script

xquery version "3.1";

(:Have attempted to strip LTR override characters in @n using \p{Cf} but this doesn't seem to work.
  This doesn't seem to be able to correctly update all items -- does about 600 then doesn't tag the rest.
  Maybe has something to do with lists inside lists?
  Could try doing smaller batches at a time or doing find/replace for titles and then incrementing URIs somehow. :)

declare default element namespace "http://www.tei-c.org/ns/1.0";

let $collection := collection("/db/apps/usaybianet/data/texts/tei")
let $next-limit := 500

for $item at $i in ($collection//list/item)[position()<=$next-limit]
return if ($item[not(title)]) then
let $section-number := $item/parent::list/preceding-sibling::p[hi][1]/hi/text()[1]
let $section-number-sanitized := normalize-space(replace(replace(replace($section-number,".*\[", ""),"\].*",""),"\p{Cf}",""))
let $item-number := replace(concat("no",replace($item/preceding-sibling::label[1]/text()[1],"(\d+).*","$1")),"\p{Cf}","")
let $title :=
    element title {
        attribute ref {concat("https://usaybia.net/work/",$i)},
        attribute n {replace(concat($section-number-sanitized,$item-number),"\p{Cf}","")},
        attribute change {"#change-1"},
        attribute cert {"low"},
        $item/node()
    }

let $item-new :=
    element item {
        $item/@*,
        $title
    }

return
    (update insert $item-new following $item, update delete $item)
else ()

xquery version "3.1";

(:Have attempted to strip LTR override characters in @n using \p{Cf} but this doesn't seem to work.
  This doesn't seem to be able to correctly update all items -- does about 600 then doesn't tag the rest.
  Maybe has something to do with lists inside lists?
  Could try doing smaller batches at a time or doing find/replace for titles and then incrementing URIs somehow. :)

declare default element namespace "http://www.tei-c.org/ns/1.0";

let $collection := collection("/db/apps/usaybianet/data/texts/tei")

for $item at $i in $collection//list/item
let $section-number := $item/parent::list/preceding-sibling::p[hi][1]/hi/text()[1]
let $section-number-sanitized := normalize-space(replace(replace(replace($section-number,".*\[", ""),"\].*",""),"\p{Cf}",""))
let $item-number := replace(concat("no",replace($item/preceding-sibling::label[1]/text()[1],"(\d+).*","$1")),"\p{Cf}","")
let $title :=
    element title {
        attribute ref {concat("https://usaybia.net/work/",$i)},
        attribute n {replace(concat($section-number-sanitized,$item-number),"\p{Cf}","")},
        attribute change {"#change-1"},
        attribute cert {"low"},
        $item/node()
    }

let $item-new :=
    element item {
        $item/@*,
        $title
    }

return
    (update insert $item-new following $item, update delete $item)


Fixed a bug

Fixed a bug

import module namespace csd_bl = "https://github.com/openhie/openinfoman/csd_bl";
declare default element  namespace   "urn:ihe:iti:csd:2013";
declare variable $careServicesRequest as item() external;

let $districts :=
<json type='object'>
    <districts type="array">
    {
      for $facility in  /CSD/facilityDirectory/facility
      let $distr := $facility/extension[@type='geographicZone']/text()
      return
	if (true())
       then
         <_  type="object">
	   <name>{$distr}</name>
         </_>
       else ()
    }
    </districts>
  </json>

return json:serialize($districts,map{"format":"direct"})

import module namespace csd_bl = "https://github.com/openhie/openinfoman/csd_bl";
declare default element  namespace   "urn:ihe:iti:csd:2013";
declare variable $careServicesRequest as item() external;

let $districts :=
<json type='object'>
    <districts type="array">
    {
      for $facility in  /CSD/facilityDirectory/facility
      let $distr := lower-case(string(facility/extension))
      return
	if (true())
       then
         <_  type="object">
	   <name>{$distr}</name>
         </_>
       else ()
    }
    </districts>
  </json>

return json:serialize($districts,map{"format":"direct"})


added /CSD/pollService/directory/{}/show_update_cache RestXQ endpoint to view soap result of polling a services directory (needed for CAT testing)

module namespace page = 'http://basex.org/modules/web-page';

import module namespace csd_psd = "https://github.com/openhie/openinfoman/csd_psd";
import module namespace csd_lsc = "https://github.com/openhie/openinfoman/csd_lsc";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace csd_qus =  "https://github.com/openhie/openinfoman/csd_qus";

declare function page:redirect($redirect as xs:string) as element(restxq:redirect)
{
  <restxq:redirect>{ $redirect }</restxq:redirect>
};

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

};

declare updating
  %rest:path("/CSD/registerService/init")
  function page:init()
{
  (
    csd_lsc:init_cache_meta($csd_webconf:db)
    ,csd_psd:init($csd_webconf:db)
    ,db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/named/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:register_named($name)
{

  (
    let $sample := $csd_webconf:remote_services//serviceDirectory[@name=$name]
    return if (exists($sample)) then
      csd_psd:register_service($csd_webconf:db,$name,text{$sample/@url},$sample/credentials)
    else ()
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/basic_auth")
  %output:method("xhtml")
  %rest:query-param("name", "{$name}")
  %rest:query-param("url", "{$url}")
  %rest:query-param("password", "{$password}")
  %rest:query-param("username", "{$username}")
  %rest:GET
  function page:register_basic_auth($name,$url,$username,$password)
{

  (
    let $credentials := <credentials type="basic_auth" username="{$username}" password="{$password}"/>
    return csd_psd:register_service($csd_webconf:db,$name,$url,$credentials)
      ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/cache_meta")
  %rest:GET
  function page:get_cache_meta()
{
  csd_lsc:get_cache_data($csd_webconf:db,())
};

declare
  %rest:path("/CSD/pollService/directory/{$name}")
  %rest:GET
  %output:method("xhtml")
  function page:get_service_menu($name)
{
  let $response :=
{$name}
{page:service_menu($name) }
  return page:nocache(csd_webconf:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/directory/{$name}/cache_meta")
  %rest:GET
  function page:get_service_cache_meta($name)
{
  csd_lsc:get_cache_data($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/create_cache")
  %rest:GET
  function page:create_cache($name)
{

  (
    if (csd_lsc:directory_exists($csd_webconf:db,$name))
    then csd_lsc:empty_cache($csd_webconf:db,$name)
    else csd_dm:empty($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/drop_cache_meta")
  %rest:GET
  function page:drop_service_cache_meta($name)
{
  (
  csd_lsc:drop_cache_data($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/directory/{$name}/get_cache")
  %rest:GET
  function page:get_cache($name)
{
 csd_lsc:get_cache($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/empty_cache")
  %rest:GET
  function page:empty_cache($name)
{
  (
  csd_lsc:empty_cache($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/update_cache")
  %rest:GET
  function page:update_cache($name)
{
(
  csd_lsc:update_cache($csd_webconf:db,$name)   ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
)

};

declare
  %rest:path("/CSD/pollService/directory/{$name}/show_update_cache")
  %rest:GET
  function page:show_update_cache($name)
{

  let $db := $csd_webconf:db
  let $mtime :=  csd_lsc:get_service_directory_mtime($db,$name)
  let $soap := csd_psd:generate_soap_request($db,$name,$mtime)
  let $result := http:send-request($soap)
  return <r>{$result}</r><s>{$soap}</s>

};

declare
  %rest:path("/CSD/pollService/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:display_service_menu($name)
{
  let $response :=

	{page:service_menu($name)}

  return page:nocache(page:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/{$name}/get")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_csd")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_csd($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_soap")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_soap($name,$mtime)
{
 let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
 return (
 <rest:response>
   <http:response status="200" >
     <http:header name="Content-Type" value="application/soap+xml"/>
     <http:header name="Content-Disposition"  value="inline; filename=soap_query_updated_services_{$name}"/>
   </http:response>
   </rest:response>
   ,
   if ($mtime) then
     csd_qus:create_last_update_request($url,$mtime)
   else
     csd_qus:create_last_update_request($url,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
 )

};

declare function page:wrapper($response) {
  let $headers :=
  (<link rel="stylesheet" type="text/css" media="screen"   href="{$csd_webconf:baseurl}static/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css"/>
  ,
  )
  return csd_webconf:wrapper($response,$headers)
};

declare
  %rest:path("/CSD/pollService")
  %rest:GET
  %output:method("xhtml")
  function page:poll_service_list()
{

if (not(csd_psd:dm_exists($csd_webconf:db))) then
   page:redirect(concat($csd_webconf:baseurl,"CSD/registerService/init"))
 else
   let $services := csd_psd:registered_directories($csd_webconf:db)
   let $unreg_services :=
     for $sample in  $csd_webconf:remote_services//serviceDirectory
     where not(csd_psd:is_registered($csd_webconf:db,$sample/text{@name}))
     return  $sample
    let $response :=

Add New Service (Basic Auth)

	 <form method='get' action="/CSD/registerService/basic_auth">

 Name<input class='pull-right'  size="35"      name='name' type="text" value=""/>

URL<input  class='pull-right' size="35"     name='url' type="text" value=""/>

User Name<input  class='pull-right' size="35"     name='username' type="text" value=""/>

Password<input  class='pull-right' size="35"     name='password' type="text" value=""/>

	   <input type='submit' />
	 </form>

	 {
	   if (count($unreg_services) > 0) then

Add New Default Service

	       {for $sample in $unreg_services
	       let $name := $sample/text{@name}
	       return

		 Register {$name}

	       }

	 else ()
}

Global Operations

 Get all cache Meta-Data

Registered Service Directories

	 {if (count($services) = 0)
	 then
No Services Registered

       else

	 {for $name in $services
	 let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
	 order by $name
	 return

	   {$name} last cached on {$mtime}

	 }

	 }

  return page:nocache(page:wrapper($response))

};

declare function page:service_menu($name) {
  let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
  let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
  return

{$url}

    modified: {$mtime}

Caching
{csd_lsc:get_document_name($name)}

    {if (not(csd_lsc:directory_exists($csd_webconf:db,$name))) then
      (

Create cache of {$name}

      )
  else
    (

Empty local cache of {$name}
,

Get local cache  of {$name}
,

      Update local cache  of {$name}

	WARNING:An InfoMan trying to cache its own service directory will result in a deadlock.  see this issue

,

Get cache Meta Data  for {$name}
,

Drop cache Meta Data  of {$name}

  )
    }

Testing

 Query  {$name} for Updated Services using stored last modified time (SOAP result)

 Query  {$name} for Updated Services using stored last modified time (CSD result)

 Get {$name}'s Soap Query for Updated Services Request using stored last modified time

    Query {$name} for Updated Services by time
    <form method='get' action="/CSD/pollService/{$name}/get">
      <input  size="35" id="datetimepicker_{$name}"    name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

    Get {$name}'s SOAP reuest for Query for Updated Services by time
    <form method='get' action="/CSD/pollService/soap_query_updated_services_{$name}">
      <input  size="35" id="soap_datetimepicker_{$name}"  name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

  To test submission on your machine you can do:

curl --header "content-type: application/soap+xml" --data "@soap_query_updated_services_{$name}.xml" {$url}

  where soap_updated_services_{$name}.xml is  the downloaded soap request document.  Add authorization parameters as neccesary.

};

module namespace page = 'http://basex.org/modules/web-page';

import module namespace csd_psd = "https://github.com/openhie/openinfoman/csd_psd";
import module namespace csd_lsc = "https://github.com/openhie/openinfoman/csd_lsc";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace csd_qus =  "https://github.com/openhie/openinfoman/csd_qus";

declare function page:redirect($redirect as xs:string) as element(restxq:redirect)
{
  <restxq:redirect>{ $redirect }</restxq:redirect>
};

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

};

declare updating
  %rest:path("/CSD/registerService/init")
  function page:init()
{
  (
    csd_lsc:init_cache_meta($csd_webconf:db)
    ,csd_psd:init($csd_webconf:db)
    ,db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/named/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:register_named($name)
{

  (
    let $sample := $csd_webconf:remote_services//serviceDirectory[@name=$name]
    return if (exists($sample)) then
      csd_psd:register_service($csd_webconf:db,$name,text{$sample/@url},$sample/credentials)
    else ()
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/basic_auth")
  %output:method("xhtml")
  %rest:query-param("name", "{$name}")
  %rest:query-param("url", "{$url}")
  %rest:query-param("password", "{$password}")
  %rest:query-param("username", "{$username}")
  %rest:GET
  function page:register_basic_auth($name,$url,$username,$password)
{

  (
    let $credentials := <credentials type="basic_auth" username="{$username}" password="{$password}"/>
    return csd_psd:register_service($csd_webconf:db,$name,$url,$credentials)
      ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/cache_meta")
  %rest:GET
  function page:get_cache_meta()
{
  csd_lsc:get_cache_data($csd_webconf:db,())
};

declare
  %rest:path("/CSD/pollService/directory/{$name}")
  %rest:GET
  %output:method("xhtml")
  function page:get_service_menu($name)
{
  let $response :=
{$name}
{page:service_menu($name) }
  return page:nocache(csd_webconf:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/directory/{$name}/cache_meta")
  %rest:GET
  function page:get_service_cache_meta($name)
{
  csd_lsc:get_cache_data($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/create_cache")
  %rest:GET
  function page:create_cache($name)
{

  (
    if (csd_lsc:directory_exists($csd_webconf:db,$name))
    then csd_lsc:empty_cache($csd_webconf:db,$name)
    else csd_dm:empty($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/drop_cache_meta")
  %rest:GET
  function page:drop_service_cache_meta($name)
{
  (
  csd_lsc:drop_cache_data($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/directory/{$name}/get_cache")
  %rest:GET
  function page:get_cache($name)
{
 csd_lsc:get_cache($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/empty_cache")
  %rest:GET
  function page:empty_cache($name)
{
  (
  csd_lsc:empty_cache($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/update_cache")
  %rest:GET
  function page:update_cache($name)
{
(
  csd_lsc:update_cache($csd_webconf:db,$name)   ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
)

};

declare
  %rest:path("/CSD/pollService/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:display_service_menu($name)
{
  let $response :=

	{page:service_menu($name)}

  return page:nocache(page:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/{$name}/get")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_csd")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_csd($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_soap")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_soap($name,$mtime)
{
 let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
 return (
 <rest:response>
   <http:response status="200" >
     <http:header name="Content-Type" value="application/soap+xml"/>
     <http:header name="Content-Disposition"  value="inline; filename=soap_query_updated_services_{$name}"/>
   </http:response>
   </rest:response>
   ,
   if ($mtime) then
     csd_qus:create_last_update_request($url,$mtime)
   else
     csd_qus:create_last_update_request($url,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
 )

};

declare function page:wrapper($response) {
  let $headers :=
  (<link rel="stylesheet" type="text/css" media="screen"   href="{$csd_webconf:baseurl}static/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css"/>
  ,
  )
  return csd_webconf:wrapper($response,$headers)
};

declare
  %rest:path("/CSD/pollService")
  %rest:GET
  %output:method("xhtml")
  function page:poll_service_list()
{

if (not(csd_psd:dm_exists($csd_webconf:db))) then
   page:redirect(concat($csd_webconf:baseurl,"CSD/registerService/init"))
 else
   let $services := csd_psd:registered_directories($csd_webconf:db)
   let $unreg_services :=
     for $sample in  $csd_webconf:remote_services//serviceDirectory
     where not(csd_psd:is_registered($csd_webconf:db,$sample/text{@name}))
     return  $sample
    let $response :=

Add New Service (Basic Auth)

	 <form method='get' action="/CSD/registerService/basic_auth">

 Name<input class='pull-right'  size="35"      name='name' type="text" value=""/>

URL<input  class='pull-right' size="35"     name='url' type="text" value=""/>

User Name<input  class='pull-right' size="35"     name='username' type="text" value=""/>

Password<input  class='pull-right' size="35"     name='password' type="text" value=""/>

	   <input type='submit' />
	 </form>

	 {
	   if (count($unreg_services) > 0) then

Add New Default Service

	       {for $sample in $unreg_services
	       let $name := $sample/text{@name}
	       return

		 Register {$name}

	       }

	 else ()
}

Global Operations

 Get all cache Meta-Data

Registered Service Directories

	 {if (count($services) = 0)
	 then
No Services Registered

       else

	 {for $name in $services
	 let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
	 order by $name
	 return

	   {$name} last cached on {$mtime}

	 }

	 }

  return page:nocache(page:wrapper($response))

};

declare function page:service_menu($name) {
  let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
  let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
  return

{$url}

    modified: {$mtime}

Caching
{csd_lsc:get_document_name($name)}

    {if (not(csd_lsc:directory_exists($csd_webconf:db,$name))) then
      (

Create cache of {$name}

      )
  else
    (

Empty local cache of {$name}
,

Get local cache  of {$name}
,

      Update local cache  of {$name}

	WARNING:An InfoMan trying to cache its own service directory will result in a deadlock.  see this issue

,

Get cache Meta Data  for {$name}
,

Drop cache Meta Data  of {$name}

  )
    }

Testing

 Query  {$name} for Updated Services using stored last modified time (SOAP result)

 Query  {$name} for Updated Services using stored last modified time (CSD result)

 Get {$name}'s Soap Query for Updated Services Request using stored last modified time

    Query {$name} for Updated Services by time
    <form method='get' action="/CSD/pollService/{$name}/get">
      <input  size="35" id="datetimepicker_{$name}"    name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

    Get {$name}'s SOAP reuest for Query for Updated Services by time
    <form method='get' action="/CSD/pollService/soap_query_updated_services_{$name}">
      <input  size="35" id="soap_datetimepicker_{$name}"  name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

  To test submission on your machine you can do:

curl --header "content-type: application/soap+xml" --data "@soap_query_updated_services_{$name}.xml" {$url}

  where soap_updated_services_{$name}.xml is  the downloaded soap request document.  Add authorization parameters as neccesary.

};


Cosmetic change.

Cosmetic change.

import module namespace ft = "http://www.zorba-xquery.com/modules/full-text";
import schema namespace fts = "http://www.zorba-xquery.com/modules/full-text";

let $doc := <msg>hello, world</msg>
let $tokens := ft:tokenize( $doc, xs:language("en") )
let $t1 := validate { $tokens[1] }
let $t2 := validate { $tokens[2] }

return  $t1/@value = "hello"
    and $t1/@lang = "en"
    and $t1/@paragraph = 1
    and $t1/@sentence = 1

    and $t2/@value = "world"
    and $t2/@lang = "en"
    and $t2/@paragraph = 1
    and $t2/@sentence = 1

(: vim:set et sw=2 ts=2: :)


Simplify output to make it more readable.  Early exploratory stages, known to be quite buggy.

declare function local:token($t)
{
  <w>{ string($t/@form) }</w>,
  $t/@presentation-after[. != ' '] ! <pc>{string(.)}</pc>
};

declare function local:unwrap($t, $stok)
{
  let $children :=  $stok[@head-id = $t/@id]
  let $seq := ($children | $t)/.
  return
    if ($children)
    then
      <wg relation="{$t/@relation}">
        {
          for $s in $seq
          return
            if ($s is $t)
            then local:token($t)
            else local:unwrap($s, $stok)
        }
      </wg>
    else local:token($t)
};

for $s in //sentence
return
  <sentence>
    {
      let $stok := $s//token
      for $t in $stok[not(@head-id)]
      return local:unwrap($t, $stok)
    }
  </sentence>

declare function local:unwrap($t, $stok)
{
  let $children :=  $stok[@head-id = $t/@id]
  let $seq := ($children | $t)/.
  return
    if ($children)
    then
      <wg relation="{$t/@relation}">
        {
          for $s in $seq
          return
            if ($s is $t)
            then $t
            else local:unwrap($s, $stok)
        }
      </wg>
    else $t
};

for $s in //sentence
let $stok := $s//token
let $t := $stok[not(@head-id)][1]  (: hack ... get rid of subscript :)
return
  <sentence>
    {
      local:unwrap($t, $stok)
    }
  </sentence>


İstatistik beklenen sayıda değilse hata veriyordu. Bu değişiklikle beklenen sayıdan daha az geçmiş run varsada sonuç üretebiliyoruz.

xquery version "1.0";
module namespace hs = "http://hs.tlos.com/";

import module namespace sq = "http://sq.tlos.com/" at "xmldb:exist://db/TLOSSW/modules/moduleSequenceOperations.xquery";

declare namespace com = "http://www.likyateknoloji.com/XML_common_types";
declare namespace dat="http://www.likyateknoloji.com/XML_data_types";
declare namespace state-types="http://www.likyateknoloji.com/state-types";
declare namespace rep="http://www.likyateknoloji.com/XML_report_types";
declare namespace fn="http://www.w3.org/2005/xpath-functions";

(:
Programmed by : Hakan Saribiyik
Version : 0.1
First Release Date : 2 Jan 2013
UpdateDate :
Purpose : Reporting of jobs and their duration and other time related things.
Usage : First step, get related Jobs with getJobsReport(
                 Number of runs that dealt with for the report,
                 Run Id for which we are focusing and take a referans point, if its value is 0 then it means we are focusing the last run,
				 Job Id if we focusing just a job, or enter 0 for all job related with the second argument,
				 true() if we choose the run id as a referance point, false() otherwise
				 ) function
example;
				 let $run := local:getJobsReport(1,1792,0, true())

Second step, get job array with requested data with getJobArray(
                 output of the getJobsReport function,
				 "ascending|descending" for ascending or descending ordered jobs based on real work time,
				 number of maksimum jobs in the array
                 ) function
example;
return local:getJobArray($run, "ascending", 15)

:)

declare function hs:calculateBaseStats($numberOfElement as xs:int, $runId as xs:int, $jobId as xs:int, $refRunIdBolean as xs:boolean) as node()*
{
  let $runIdx := if( $runId = 0 ) then sq:getId("runId") (: son run :)
    					 else $runId

  (: Burada son run i bilerek dikkate almiyoruz, ondan onceki 3 run in ortalamasi yeterli :)
  let $localStats :=
    let $arasonuc := <arasonuc> {
                      for $i in (1,2,3)
                       let $getPerStats := hs:getJobsReport($numberOfElement,$runIdx - $i ,$jobId, $refRunIdBolean)
                       let $getPerStatsExists := if(exists($getPerStats)) then $getPerStats else ()
                       let $hepsi := hs:getJobArray($getPerStatsExists,"descending",50)/@totalDurationInSec
                      return <stat> { $hepsi } </stat>
                     }
                     </arasonuc>

    let $temiz :=    for $i in $arasonuc/stat
                     where $i/@totalDurationInSec[string(.)]
                     return $i

    let $temizArasonuc := <arasonuc count="{count($temiz)}"> {
                     $temiz
    }
                     </arasonuc>
    let $max :=  round-half-to-even( max($temizArasonuc/stat/@totalDurationInSec), 2)
    let $min := round-half-to-even( min($temizArasonuc/stat/@totalDurationInSec), 2)
    let $ortalama := round-half-to-even( avg($temizArasonuc/stat/@totalDurationInSec), 2)
    return <rep:localStats> <rep:max> { $max } </rep:max><rep:min> { $min } </rep:min><rep:avg>{ $ortalama } </rep:avg>
           </rep:localStats>

  return $localStats
};

declare function hs:getJobsReport($numberOfElement as xs:int, $runId as xs:int, $jobId as xs:int, $refRunIdBolean as xs:boolean) as node()*
 {

    let $runIdFound := if ($runId = 0) then sq:getId("runId")
                       else if ($runId < 0) then sq:getId("runId") + $runId
	                   else $runId

    let $posUpper := max(for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
	                 where $runx[@id = $runIdFound] or not($refRunIdBolean)
	                 return $pos)

    let $posLower := if ($posUpper - $numberOfElement > 0) then $posUpper - $numberOfElement else 0

    let $sonuc := for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
		  where $pos > $posLower and $pos <=$posUpper and $runx//dat:jobProperties[(@ID = $jobId or $jobId = 0)]
		  order by $runx/@id descending
                  return $runx

    let $sonuc2 := for $runx in $sonuc//dat:jobProperties
		  where $runx[(@ID = $jobId or $jobId = 0) and (boolean(@agentId) and not(@agentId='0'))]
		  order by $runx/@id descending
                  return $runx

    return <all> { $sonuc2 } </all>
};

(: Special DateTime format; source : http://www.w3.org/TR/xpath-functions/#dt-dayTimeDuration
   format PnDTnHnMnS, where nD represents the number of days, T is the date/time separator, nH the number of hours, nM the number of minutes and nS the number of seconds.
   For example, to indicate a duration of 3 days, 10 hours and 30 minutes, one would write: P3DT10H30M.
:)

declare function hs:getJobArray($n as node()*, $order as xs:string, $maxNumOfListedJobs) as node()*
{
  let $resultArrayAsc := <rep:jobArray> {
    for $job in $n//dat:jobProperties[boolean(@agentId) and not(@agentId='0')]
	(: hs. is bazen transfering state de kalabiliyor. Bu durumda LSIDateTime dan baslama zamanini aliyoruz. Belkide N/A yapmak gerekir. Emin degilim :)
     let $startdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date else xs:string(xs:date(hs:stringToDateTime($job/@LSIDateTime)))
     let $starttime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time else xs:string(xs:time(hs:stringToDateTime($job/@LSIDateTime)))
     let $stopdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date else xs:string("N/A")
     let $stoptime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time else xs:string("N/A")

     let $startdatetime := fn:dateTime(xs:date($startdate),xs:time($starttime)) - xs:dateTime("1970-01-01T00:00:00-00:00")
     let $stopdatetime := if( hs:nACheck($stopdate) or hs:nACheck($stoptime) )
	                      then xs:dateTime("1970-01-01T00:00:00-00:00") - xs:dateTime("1970-01-01T00:00:00-00:01")
						  else fn:dateTime($stopdate,$stoptime) - xs:dateTime("1970-01-01T00:00:00-00:00")

     let $startdatetimeDTD := xs:dayTimeDuration($startdatetime) div xs:dayTimeDuration('PT1S')
     let $stopdatetimeDTD  := xs:dayTimeDuration($stopdatetime) div xs:dayTimeDuration('PT1S')
	 let $datetimeDTD := $stopdatetimeDTD - $startdatetimeDTD

	 let $ordertime := if( hs:nACheck($startdatetime) or hs:nACheck($stopdatetime) ) then xs:dateTime("1970-01-01T00:00:00-00:00") else $datetimeDTD

     let $startTimeFormatted := concat(substring($startdate, 1, 10), 'T', $starttime)
     let $stopTimeFormatted := if( hs:nACheck($stopdate) or hs:nACheck($stoptime))
	                           then xs:string("N/A")
							   else concat(substring($stopdate, 1, 10), 'T', $stoptime)

     let $diffInTime := if( hs:nACheck($stopdate) )
	                    then xs:dayTimeDuration('-PT1S')
					    else $datetimeDTD
    order by $ordertime
    return <rep:job id="{$job/@ID}" jname="{$job/dat:baseJobInfos/com:jsName}" startTime="{$startTimeFormatted}" stopTime="{$stopTimeFormatted}"> { $diffInTime }</rep:job>
    } </rep:jobArray>

  let $numberOfJobs := count($resultArrayAsc/rep:job)
  let $numberOfScenarios := count($n//dat:scenario)
  let $minStartDateTime := min(for $min in $resultArrayAsc/rep:job return if( hs:nACheck($min/@startTime) ) then current-dateTime() else xs:dateTime($min/@startTime))
  let $maxStopDateTime :=  max(for $max in $resultArrayAsc/rep:job return if( hs:nACheck($max/@stopTime) ) then xs:dateTime("1970-01-01T00:00:00-00:01") else xs:dateTime($max/@stopTime))
  (:
     let $maxStopDateTimeDTD := xs:dayTimeDuration($maxStopDateTime) div xs:dayTimeDuration('PT1S')
     let $minStartDateTimeDTD  := xs:dayTimeDuration($minStartDateTime) div xs:dayTimeDuration('PT1S')
	 let $totalDurationInSec := $maxStopDateTimeDTD - $minStartDateTimeDTD
  :)
  let $totalDuration := $maxStopDateTime - $minStartDateTime
  let $totalDurationInSec := fn:days-from-duration($totalDuration)*24*60*60+fn:hours-from-duration($totalDuration)*60*60+fn:minutes-from-duration($totalDuration)*60+fn:seconds-from-duration($totalDuration)

  return
    if(not(exists($n))) then <rep:jobArray totalDurationInSec = "0" overallStart="N/A" overallStop="N/A" numberOfJobs="0" maxNumOfListedJobs="0" numberOfScenarios="0">  </rep:jobArray>
    else if(compare($order, "ascending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { $resultArrayAsc/rep:job[position()<=$maxNumOfListedJobs]} </rep:jobArray>
    else if(compare($order, "descending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { reverse($resultArrayAsc/rep:job)[position()<=$maxNumOfListedJobs] } </rep:jobArray>
    else <rep:jobArray>-1</rep:jobArray>
};

declare function hs:getJobArrayXX($n as node()?, $order as xs:string, $maxNumOfListedJobs) as node()*
{
  let $resultArrayAsc := <rep:jobArray> {
    for $job in $n//dat:jobProperties[boolean(@agentId) and not(@agentId='0')]
	(: hs. is bazen transfering state de kalabiliyor. Bu durumda LSIDateTime dan baslama zamanini aliyoruz. Belkide N/A yapmak gerekir. Emin degilim :)
     let $startdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date else xs:string(xs:date(hs:stringToDateTime($job/@LSIDateTime)))
     let $starttime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time else xs:string(xs:time(hs:stringToDateTime($job/@LSIDateTime)))
     let $stopdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date else xs:string("N/A")
     let $stoptime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time else xs:string("N/A")

     let $startdatetime := fn:dateTime(xs:date($startdate),xs:time($starttime)) - xs:dateTime("1970-01-01T00:00:00-00:00")
     let $stopdatetime := if( hs:nACheck($stopdate) or hs:nACheck($stoptime) )
	                      then xs:dateTime("1970-01-01T00:00:00-00:00") - xs:dateTime("1970-01-01T00:00:00-00:01")
						  else fn:dateTime($stopdate,$stoptime) - xs:dateTime("1970-01-01T00:00:00-00:00")

     let $startdatetimeDTD := xs:dayTimeDuration($startdatetime) div xs:dayTimeDuration('PT1S')
     let $stopdatetimeDTD  := xs:dayTimeDuration($stopdatetime) div xs:dayTimeDuration('PT1S')
	 let $datetimeDTD := $stopdatetimeDTD - $startdatetimeDTD

	 let $ordertime := if( hs:nACheck($startdatetime) or hs:nACheck($stopdatetime) ) then xs:dateTime("1970-01-01T00:00:00-00:00") else $datetimeDTD

     let $startTimeFormatted := concat(substring($startdate, 1, 10), 'T', $starttime)
     let $stopTimeFormatted := if( hs:nACheck($stopdate) or hs:nACheck($stoptime))
	                           then xs:string("N/A")
							   else concat(substring($stopdate, 1, 10), 'T', $stoptime)

     let $diffInTime := if( hs:nACheck($stopdate) )
	                    then xs:dayTimeDuration('-PT1S')
					    else $datetimeDTD
    order by $ordertime
    return <rep:job id="{$startdatetime}" jname="{$stopdatetime}" startTime="{$startTimeFormatted}" stopTime="{$stopTimeFormatted}"> { $diffInTime }</rep:job>
    } </rep:jobArray>

  let $numberOfJobs := count($resultArrayAsc/rep:job)
  let $numberOfScenarios := count($n//dat:scenario)
  let $minStartDateTime := min(for $min in $resultArrayAsc/rep:job return if( hs:nACheck($min/@startTime) ) then current-dateTime() else xs:dateTime($min/@startTime))
  let $maxStopDateTime :=  max(for $max in $resultArrayAsc/rep:job return if( hs:nACheck($max/@stopTime) ) then xs:dateTime("1970-01-01T00:00:00-00:01") else xs:dateTime($max/@stopTime))
  (:
     let $maxStopDateTimeDTD := xs:dayTimeDuration($maxStopDateTime) div xs:dayTimeDuration('PT1S')
     let $minStartDateTimeDTD  := xs:dayTimeDuration($minStartDateTime) div xs:dayTimeDuration('PT1S')
	 let $totalDurationInSec := $maxStopDateTimeDTD - $minStartDateTimeDTD
  :)
  let $totalDuration := $maxStopDateTime - $minStartDateTime
  let $totalDurationInSec := fn:days-from-duration($totalDuration)*24*60*60+fn:hours-from-duration($totalDuration)*60*60+fn:minutes-from-duration($totalDuration)*60+fn:seconds-from-duration($totalDuration)

  return
    if(not(exists($n))) then <rep:jobArray totalDurationInSec = "0" overallStart="N/A" overallStop="N/A" numberOfJobs="0" maxNumOfListedJobs="0" numberOfScenarios="0">  </rep:jobArray>
    else if(compare($order, "ascending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { $resultArrayAsc/rep:job[position()<=$maxNumOfListedJobs]} </rep:jobArray>
    else if(compare($order, "descending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { reverse($resultArrayAsc/rep:job)[position()<=$maxNumOfListedJobs] } </rep:jobArray>
    else <rep:jobArray>-1</rep:jobArray>
};

declare function hs:stringToDateTime($t1 as xs:string)
{
    (: Degisik tarih formatlari icin dusunuldu. 2011-10-13T15:08:31+0300 veya 2011-10-13T15:08:31.91+0300 veya 2011-10-13T15:08:31.897+0300 :)
    let $uzunluk := string-length($t1)
    let $baslangic := if($uzunluk eq 24) then 19 else if($uzunluk eq 27) then 22 else if($uzunluk eq 28) then 23 else ()

    let $t2 := substring($t1, 1, $baslangic)
    let $t3 := substring($t1, $baslangic+2, 2)
    let $t7 := concat($t2, '+', $t3, ':00')
    let $t8 := xs:dateTime($t7)

	return $t8
};

declare function hs:nACheck($x as xs:anyAtomicType) as xs:boolean
{
  let $result := if (compare(xs:string($x),xs:string("N/A")) eq 0)
				 then true()
				 else false()

  return $result
} ;

declare function hs:stringCheck($x as xs:anyAtomicType) as xs:boolean
{
typeswitch ($x)

case xs:string return true()
default
return false()
} ;

(: jobProperties icinde gelen baslangic ve bitis tarih araligindaki o jobin calisma bilgilerini donuyor :)
declare function hs:getJobs($jobProperty as element(dat:jobProperties), $jobPath) as element(dat:jobProperties)*
{
	let $doc := doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")
	for $jobs in $jobPath (:/TlosProcessDataAll/RUN/dat:TlosProcessData/dat:scenario[com:jsName = 'Senaryo3']/dat:jobList/dat:jobProperties:)
		where $jobs/dat:baseJobInfos/com:jsName = $jobProperty/dat:baseJobInfos/com:jsName and not($jobs[@agentId="0"])
		and ( if(not(empty($jobProperty/dat:timeManagement/dat:jsRealTime/dat:startTime)) and not(empty($jobProperty/dat:timeManagement/dat:jsRealTime/dat:stopTime)))
 				 then 	not(empty($jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date))
						and (string($jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date) != '')
						and	$jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date >= $jobProperty/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date
						and $jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date <= $jobProperty/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date
				  else true()
			)
	return  $jobs
};

(:
Kullanim:
let $kacEleman := 1
let $jobId := 0 (: Eger belirli bir jobId girilirse o job ile ilgili sonuclar, sifir girilirse butun joblar ile ilgili sonuclar:)
let $runId := 0 (: Eger belirli bir runId girilirse oradan geriye, sifir girilirse en son runId den geriye:)
let $refRunIdBolean := true()  (: Eger true secilirse bu runId yi referans kabul et anlamina gelir. false ise runId yi dikkate almaz.:)

return hs:jobStateListbyRunId($kacEleman, $runId, $jobId, $refRunIdBolean)
:)
declare function hs:jobStateListbyRunId($numberOfElement as xs:int, $runId as xs:int, $jobId as xs:int, $refRunIdBolean as xs:boolean) as node()*
 {

    let $runIdFound := if ($runId != 0 )
	                   then $runId
	                   else sq:getId("runId")

    let $posUpper := max(for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
	                 where $runx[@id = $runIdFound] or not($refRunIdBolean)
	                 return $pos)

    let $posLower := if ($posUpper - $numberOfElement > 0) then $posUpper - $numberOfElement else 0

    let $nextId := sq:getNextId("reportId")
    let $createBlankReport := hs:insertStateReportLock($jobId, $nextId)

	let $arasonuc := for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
					 where $pos > $posLower and $pos <=$posUpper and $runx//dat:jobProperties[(@ID = $jobId or $jobId = 0) and @agentId!="0"]
					 order by $runx/@id descending
	                 return hs:jobStateReport($runx/dat:TlosProcessData, $jobId, $nextId)
    let $sonuc := if(exists($arasonuc))
	              then hs:searchStateReportById(sq:getReportId())
	              else ()
	return $sonuc
};

declare function hs:jobStateReport($n as element(dat:TlosProcessData), $jobId as xs:int, $nextId as xs:int) as node()*
{
   (: Son state leri belirleme kismi :)
   let $propertiesList := $n//dat:jobProperties[(@ID = $jobId or $jobId = 0)]
   let $stateList :=
         for $donbaba in fn:distinct-values($propertiesList/@ID)
         let $jobsInGroup := $propertiesList[@ID = $donbaba]
         return
             let $kacdefa := count($jobsInGroup)
             let $list := if ($kacdefa = 1) then $jobsInGroup[@agentId="0"]/dat:stateInfos/state-types:LiveStateInfos
                          else $jobsInGroup[@agentId!="0"][1]/dat:stateInfos/state-types:LiveStateInfos
         return hs:jobStateReportFromLiveStateInfo($list, $jobId, $nextId)

    let $sonuc2 := for $runx at $pos in $stateList/state-types:LiveStateInfo
                   order by $runx/@LSIDateTime descending
	               return $runx
	return $sonuc2
 };

declare function hs:jobStateReportFromLiveStateInfo($stateList as element(state-types:LiveStateInfos), $jobId as xs:int, $nextId as xs:int) as node()*
{
   let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")

	let $sonuc2 := (for $runx at $pos in $stateList/state-types:LiveStateInfo
                   order by $runx/@LSIDateTime descending
	               return $runx)[1]

    (: raporu guncelleme kismi :)
(:    let $ee := data($sonuc2/state-types:StateName)
    let $test := concat(xs:string("rep:reportAll/rep:stateReport/rep:report/rep:"),$ee):)

	let $valStateName := $sonuc2/state-types:StateName
	let $valSubstateName := $sonuc2/state-types:SubstateName
	let $valStatusName := $sonuc2/state-types:StatusName

    let $relPath := $docrep/rep:reportAll/rep:stateReport/rep:report[@id=$nextId]

    let $sorgu := if ( empty($sonuc2/state-types:StatusName) )
	           then
			     if ( empty($sonuc2/state-types:SubstateName) )
	             then util:eval(concat("<rep:", $valStateName, ">", $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]  + 1, "</rep:",$valStateName,">"))
			     else util:eval(concat("<rep:", $valSubstateName, ">", $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]  + 1 , "</rep:",$valSubstateName,">"))
			   else util:eval(concat("<rep:", $valStatusName, ">", $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]/rep:*[local-name() eq $sonuc2/state-types:StatusName] + 1 , "</rep:",$valStatusName,">"))

    let $df := if ( empty($sonuc2/state-types:StatusName) )
	           then
			     if ( empty($sonuc2/state-types:SubstateName) )
	             then update replace $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]
				                with $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]  + 1
			     else update replace $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]
				                with $sorgu
			   else update replace $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]/rep:*[local-name() eq $sonuc2/state-types:StatusName]
			                    with $sorgu

   return <ss>{$sonuc2}</ss>
};

declare function hs:insertStateReportLock($jsId as xs:int, $nextId as xs:int) as xs:boolean
{
   let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")
   let $relPath := $docrep/rep:reportAll/rep:stateReport

   let $sonuc := util:exclusive-lock($relPath, hs:insertBlankStateReport($jsId, $nextId))
   return true()
};

declare function hs:insertBlankStateReport($jsId as xs:int, $nextId as xs:int) as node()*
{

   let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")
   let $relPath := $docrep/rep:reportAll/rep:stateReport

(:    let $nextId := sq:getNextId("reportId")	:)
    let $scope := xs:string("job")
	return update insert
		<rep:report xmlns="http://www.likyateknoloji.com/XML_report_types" id="{$nextId}" jsId="{$jsId}" scope="{$scope}" LSIDateTime="{current-dateTime()}">
			<rep:PENDING>
				<rep:CREATED>0</rep:CREATED>
				<rep:DEACTIVATED>0</rep:DEACTIVATED>
				<rep:VALIDATED>0</rep:VALIDATED>
				<rep:IDLED>
					<rep:BYTIME>0</rep:BYTIME>
					<rep:BYUSER>0</rep:BYUSER>
                    <rep:BYEVENT>0</rep:BYEVENT>
				</rep:IDLED>
				<rep:READY>
					<rep:LOOKFOR-RESOURCE>0</rep:LOOKFOR-RESOURCE>
					<rep:USER-CHOOSE-RESOURCE>0</rep:USER-CHOOSE-RESOURCE>
					<rep:USER-WAITING>0</rep:USER-WAITING>
					<rep:WAITING>0</rep:WAITING>
					<rep:TRANSFERING>0</rep:TRANSFERING>
				</rep:READY>
				<rep:PAUSED>0</rep:PAUSED>
			</rep:PENDING>
			<rep:RUNNING>
				<rep:STAGE-IN>0</rep:STAGE-IN>
				<rep:MIGRATING>0</rep:MIGRATING>
				<rep:ON-RESOURCE>
					<rep:TIME-IN>0</rep:TIME-IN>
					<rep:TIME-OUT>0</rep:TIME-OUT>
				</rep:ON-RESOURCE>
				<rep:HELD>0</rep:HELD>
				<rep:STAGE-OUT>0</rep:STAGE-OUT>
			</rep:RUNNING>
			<rep:FAILED>0</rep:FAILED>
			<rep:CANCELLED>0</rep:CANCELLED>
			<rep:FINISHED>
				<rep:COMPLETED>
					<rep:SUCCESS>0</rep:SUCCESS>
					<rep:WARNING>0</rep:WARNING>
					<rep:FAILED>0</rep:FAILED>
				</rep:COMPLETED>
				<rep:SKIPPED>0</rep:SKIPPED>
				<rep:STOPPED>0</rep:STOPPED>
			</rep:FINISHED>
		</rep:report>
	into $relPath
} ;

declare function hs:searchStateReportById($reportId as xs:int) as element(rep:report)?
 {
    let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")
	let $relPath := $docrep/rep:reportAll/rep:stateReport/rep:report

	for $report in $relPath
	where $report/@id = $reportId
    return $report
};

(:declare function hs:getJobs($jobProperty as element(dat:jobProperties), $jobPath) as element(dat:jobProperties)*
{
	let $doc := doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")
	for $jobs in $jobPath (:/TlosProcessDataAll/RUN/dat:TlosProcessData/dat:scenario[com:jsName = 'Senaryo3']/dat:jobList/dat:jobProperties:)
		where $jobs/com:jsName = $jobProperty/com:jsName
		and ( if(not(empty($jobProperty/dat:jobRealTime/dat:startTime)) and not(empty($jobProperty/dat:jobRealTime/dat:stopTime)))
 				 then 	not(empty($jobs/dat:jobRealTime/dat:startTime/com:date/com:year))
						and (string($jobs/dat:jobRealTime/dat:startTime/com:date/com:year) != '')
						and not(empty($jobs/dat:jobRealTime/dat:startTime/com:date/com:month))
						and (string($jobs/dat:jobRealTime/dat:startTime/com:date/com:month) != '')
						and not(empty($jobs/dat:jobRealTime/dat:startTime/com:date/com:day))
						and (string($jobs/dat:jobRealTime/dat:startTime/com:date/com:day) != '')
						and	xs:date(concat($jobs/dat:jobRealTime/dat:startTime/com:date/com:year,'-', $jobs/dat:jobRealTime/dat:startTime/com:date/com:month,'-',$jobs/dat:jobRealTime/dat:startTime/com:date/com:day ) )
							>=  xs:date(concat($jobProperty/dat:jobRealTime/dat:startTime/com:date/com:year,'-', $jobProperty/dat:jobRealTime/dat:startTime/com:date/com:month,'-',$jobProperty/dat:jobRealTime/dat:startTime/com:date/com:day ) )
						and xs:date(concat($jobs/dat:jobRealTime/dat:startTime/com:date/com:year,'-', $jobs/dat:jobRealTime/dat:startTime/com:date/com:month,'-',$jobs/dat:jobRealTime/dat:startTime/com:date/com:day ) )
							<=  xs:date(concat($jobProperty/dat:jobRealTime/dat:stopTime/com:date/com:year,'-', $jobProperty/dat:jobRealTime/dat:stopTime/com:date/com:month,'-',$jobProperty/dat:jobRealTime/dat:stopTime/com:date/com:day ) )
				  else ("TRUE")
			)
	return  $jobs
};:)

xquery version "1.0";
module namespace hs = "http://hs.tlos.com/";

import module namespace sq = "http://sq.tlos.com/" at "xmldb:exist://db/TLOSSW/modules/moduleSequenceOperations.xquery";

declare namespace com = "http://www.likyateknoloji.com/XML_common_types";
declare namespace dat="http://www.likyateknoloji.com/XML_data_types";
declare namespace state-types="http://www.likyateknoloji.com/state-types";
declare namespace rep="http://www.likyateknoloji.com/XML_report_types";
declare namespace fn="http://www.w3.org/2005/xpath-functions";

(:
Programmed by : Hakan Saribiyik
Version : 0.1
First Release Date : 2 Jan 2013
UpdateDate :
Purpose : Reporting of jobs and their duration and other time related things.
Usage : First step, get related Jobs with getJobsReport(
                 Number of runs that dealt with for the report,
                 Run Id for which we are focusing and take a referans point, if its value is 0 then it means we are focusing the last run,
				 Job Id if we focusing just a job, or enter 0 for all job related with the second argument,
				 true() if we choose the run id as a referance point, false() otherwise
				 ) function
example;
				 let $run := local:getJobsReport(1,1792,0, true())

Second step, get job array with requested data with getJobArray(
                 output of the getJobsReport function,
				 "ascending|descending" for ascending or descending ordered jobs based on real work time,
				 number of maksimum jobs in the array
                 ) function
example;
return local:getJobArray($run, "ascending", 15)

:)

declare function hs:calculateBaseStats($numberOfElement as xs:int, $runId as xs:int, $jobId as xs:int, $refRunIdBolean as xs:boolean) as node()*
{
  let $runIdx := if( $runId = 0 ) then sq:getId("runId") (: son run :)
						 else $runId

  (: Burada son run i bilerek dikkate almiyoruz, ondan onceki 3 run in ortalamasi yeterli :)
  let $localStats :=
    let $arasonuc := for $i in (1,2,3)
                      let $hepsi := hs:getJobArray(hs:getJobsReport($numberOfElement,$runIdx - $i ,$jobId, $refRunIdBolean),"descending",50)/@totalDurationInSec
                     return $hepsi

    let $max :=  round-half-to-even( max($arasonuc), 2)
    let $min := round-half-to-even( min($arasonuc), 2)
    let $ortalama := round-half-to-even( avg($arasonuc), 2)
    return <rep:localStats> <rep:max> { $max } </rep:max><rep:min> { $min } </rep:min><rep:avg>{ $ortalama } </rep:avg> </rep:localStats>

  return $localStats
};

declare function hs:getJobsReport($numberOfElement as xs:int, $runId as xs:int, $jobId as xs:int, $refRunIdBolean as xs:boolean) as node()*
 {

    let $runIdFound := if ($runId = 0) then sq:getId("runId")
                       else if ($runId < 0) then sq:getId("runId") + $runId
	                   else $runId

    let $posUpper := max(for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
	                 where $runx[@id = $runIdFound] or not($refRunIdBolean)
	                 return $pos)

    let $posLower := if ($posUpper - $numberOfElement > 0) then $posUpper - $numberOfElement else 0

    let $sonuc := for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
		  where $pos > $posLower and $pos <=$posUpper and $runx//dat:jobProperties[(@ID = $jobId or $jobId = 0)]
		  order by $runx/@id descending
                  return $runx

    let $sonuc2 := for $runx in $sonuc//dat:jobProperties
		  where $runx[(@ID = $jobId or $jobId = 0) and (boolean(@agentId) and not(@agentId='0'))]
		  order by $runx/@id descending
                  return $runx

    return <all> { $sonuc2 } </all>
};

(: Special DateTime format; source : http://www.w3.org/TR/xpath-functions/#dt-dayTimeDuration
   format PnDTnHnMnS, where nD represents the number of days, T is the date/time separator, nH the number of hours, nM the number of minutes and nS the number of seconds.
   For example, to indicate a duration of 3 days, 10 hours and 30 minutes, one would write: P3DT10H30M.
:)

declare function hs:getJobArray($n as node()*, $order as xs:string, $maxNumOfListedJobs) as node()*
{
  let $resultArrayAsc := <rep:jobArray> {
    for $job in $n//dat:jobProperties[boolean(@agentId) and not(@agentId='0')]
	(: hs. is bazen transfering state de kalabiliyor. Bu durumda LSIDateTime dan baslama zamanini aliyoruz. Belkide N/A yapmak gerekir. Emin degilim :)
     let $startdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date else xs:string(xs:date(hs:stringToDateTime($job/@LSIDateTime)))
     let $starttime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time else xs:string(xs:time(hs:stringToDateTime($job/@LSIDateTime)))
     let $stopdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date else xs:string("N/A")
     let $stoptime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time else xs:string("N/A")

     let $startdatetime := fn:dateTime(xs:date($startdate),xs:time($starttime)) - xs:dateTime("1970-01-01T00:00:00-00:00")
     let $stopdatetime := if( hs:nACheck($stopdate) or hs:nACheck($stoptime) )
	                      then xs:dateTime("1970-01-01T00:00:00-00:00") - xs:dateTime("1970-01-01T00:00:00-00:01")
						  else fn:dateTime($stopdate,$stoptime) - xs:dateTime("1970-01-01T00:00:00-00:00")

     let $startdatetimeDTD := xs:dayTimeDuration($startdatetime) div xs:dayTimeDuration('PT1S')
     let $stopdatetimeDTD  := xs:dayTimeDuration($stopdatetime) div xs:dayTimeDuration('PT1S')
	 let $datetimeDTD := $stopdatetimeDTD - $startdatetimeDTD

	 let $ordertime := if( hs:nACheck($startdatetime) or hs:nACheck($stopdatetime) ) then xs:dateTime("1970-01-01T00:00:00-00:00") else $datetimeDTD

     let $startTimeFormatted := concat(substring($startdate, 1, 10), 'T', $starttime)
     let $stopTimeFormatted := if( hs:nACheck($stopdate) or hs:nACheck($stoptime))
	                           then xs:string("N/A")
							   else concat(substring($stopdate, 1, 10), 'T', $stoptime)

     let $diffInTime := if( hs:nACheck($stopdate) )
	                    then xs:dayTimeDuration('-PT1S')
					    else $datetimeDTD
    order by $ordertime
    return <rep:job id="{$job/@ID}" jname="{$job/dat:baseJobInfos/com:jsName}" startTime="{$startTimeFormatted}" stopTime="{$stopTimeFormatted}"> { $diffInTime }</rep:job>
    } </rep:jobArray>

  let $numberOfJobs := count($resultArrayAsc/rep:job)
  let $numberOfScenarios := count($n//dat:scenario)
  let $minStartDateTime := min(for $min in $resultArrayAsc/rep:job return if( hs:nACheck($min/@startTime) ) then current-dateTime() else xs:dateTime($min/@startTime))
  let $maxStopDateTime :=  max(for $max in $resultArrayAsc/rep:job return if( hs:nACheck($max/@stopTime) ) then xs:dateTime("1970-01-01T00:00:00-00:01") else xs:dateTime($max/@stopTime))
  (:
     let $maxStopDateTimeDTD := xs:dayTimeDuration($maxStopDateTime) div xs:dayTimeDuration('PT1S')
     let $minStartDateTimeDTD  := xs:dayTimeDuration($minStartDateTime) div xs:dayTimeDuration('PT1S')
	 let $totalDurationInSec := $maxStopDateTimeDTD - $minStartDateTimeDTD
  :)
  let $totalDuration := $maxStopDateTime - $minStartDateTime
  let $totalDurationInSec := fn:days-from-duration($totalDuration)*24*60*60+fn:hours-from-duration($totalDuration)*60*60+fn:minutes-from-duration($totalDuration)*60+fn:seconds-from-duration($totalDuration)

  return
    if(not(exists($n))) then <rep:jobArray totalDurationInSec = "0" overallStart="N/A" overallStop="N/A" numberOfJobs="0" maxNumOfListedJobs="0" numberOfScenarios="0">  </rep:jobArray>
    else if(compare($order, "ascending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { $resultArrayAsc/rep:job[position()<=$maxNumOfListedJobs]} </rep:jobArray>
    else if(compare($order, "descending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { reverse($resultArrayAsc/rep:job)[position()<=$maxNumOfListedJobs] } </rep:jobArray>
    else <rep:jobArray>-1</rep:jobArray>
};

declare function hs:getJobArrayXX($n as node()?, $order as xs:string, $maxNumOfListedJobs) as node()*
{
  let $resultArrayAsc := <rep:jobArray> {
    for $job in $n//dat:jobProperties[boolean(@agentId) and not(@agentId='0')]
	(: hs. is bazen transfering state de kalabiliyor. Bu durumda LSIDateTime dan baslama zamanini aliyoruz. Belkide N/A yapmak gerekir. Emin degilim :)
     let $startdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date else xs:string(xs:date(hs:stringToDateTime($job/@LSIDateTime)))
     let $starttime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:startTime/com:time else xs:string(xs:time(hs:stringToDateTime($job/@LSIDateTime)))
     let $stopdate := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date else xs:string("N/A")
     let $stoptime := if(exists($job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time)) then $job/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:time else xs:string("N/A")

     let $startdatetime := fn:dateTime(xs:date($startdate),xs:time($starttime)) - xs:dateTime("1970-01-01T00:00:00-00:00")
     let $stopdatetime := if( hs:nACheck($stopdate) or hs:nACheck($stoptime) )
	                      then xs:dateTime("1970-01-01T00:00:00-00:00") - xs:dateTime("1970-01-01T00:00:00-00:01")
						  else fn:dateTime($stopdate,$stoptime) - xs:dateTime("1970-01-01T00:00:00-00:00")

     let $startdatetimeDTD := xs:dayTimeDuration($startdatetime) div xs:dayTimeDuration('PT1S')
     let $stopdatetimeDTD  := xs:dayTimeDuration($stopdatetime) div xs:dayTimeDuration('PT1S')
	 let $datetimeDTD := $stopdatetimeDTD - $startdatetimeDTD

	 let $ordertime := if( hs:nACheck($startdatetime) or hs:nACheck($stopdatetime) ) then xs:dateTime("1970-01-01T00:00:00-00:00") else $datetimeDTD

     let $startTimeFormatted := concat(substring($startdate, 1, 10), 'T', $starttime)
     let $stopTimeFormatted := if( hs:nACheck($stopdate) or hs:nACheck($stoptime))
	                           then xs:string("N/A")
							   else concat(substring($stopdate, 1, 10), 'T', $stoptime)

     let $diffInTime := if( hs:nACheck($stopdate) )
	                    then xs:dayTimeDuration('-PT1S')
					    else $datetimeDTD
    order by $ordertime
    return <rep:job id="{$startdatetime}" jname="{$stopdatetime}" startTime="{$startTimeFormatted}" stopTime="{$stopTimeFormatted}"> { $diffInTime }</rep:job>
    } </rep:jobArray>

  let $numberOfJobs := count($resultArrayAsc/rep:job)
  let $numberOfScenarios := count($n//dat:scenario)
  let $minStartDateTime := min(for $min in $resultArrayAsc/rep:job return if( hs:nACheck($min/@startTime) ) then current-dateTime() else xs:dateTime($min/@startTime))
  let $maxStopDateTime :=  max(for $max in $resultArrayAsc/rep:job return if( hs:nACheck($max/@stopTime) ) then xs:dateTime("1970-01-01T00:00:00-00:01") else xs:dateTime($max/@stopTime))
  (:
     let $maxStopDateTimeDTD := xs:dayTimeDuration($maxStopDateTime) div xs:dayTimeDuration('PT1S')
     let $minStartDateTimeDTD  := xs:dayTimeDuration($minStartDateTime) div xs:dayTimeDuration('PT1S')
	 let $totalDurationInSec := $maxStopDateTimeDTD - $minStartDateTimeDTD
  :)
  let $totalDuration := $maxStopDateTime - $minStartDateTime
  let $totalDurationInSec := fn:days-from-duration($totalDuration)*24*60*60+fn:hours-from-duration($totalDuration)*60*60+fn:minutes-from-duration($totalDuration)*60+fn:seconds-from-duration($totalDuration)

  return
    if(not(exists($n))) then <rep:jobArray totalDurationInSec = "0" overallStart="N/A" overallStop="N/A" numberOfJobs="0" maxNumOfListedJobs="0" numberOfScenarios="0">  </rep:jobArray>
    else if(compare($order, "ascending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { $resultArrayAsc/rep:job[position()<=$maxNumOfListedJobs]} </rep:jobArray>
    else if(compare($order, "descending") eq 0) then <rep:jobArray totalDurationInSec = "{$totalDurationInSec}" overallStart="{$minStartDateTime}" overallStop="{$maxStopDateTime}" numberOfJobs="{$numberOfJobs}" maxNumOfListedJobs="{$maxNumOfListedJobs}" numberOfScenarios="{$numberOfScenarios}"> { reverse($resultArrayAsc/rep:job)[position()<=$maxNumOfListedJobs] } </rep:jobArray>
    else <rep:jobArray>-1</rep:jobArray>
};

declare function hs:stringToDateTime($t1 as xs:string)
{
    (: Degisik tarih formatlari icin dusunuldu. 2011-10-13T15:08:31+0300 veya 2011-10-13T15:08:31.91+0300 veya 2011-10-13T15:08:31.897+0300 :)
    let $uzunluk := string-length($t1)
    let $baslangic := if($uzunluk eq 24) then 19 else if($uzunluk eq 27) then 22 else if($uzunluk eq 28) then 23 else ()

    let $t2 := substring($t1, 1, $baslangic)
    let $t3 := substring($t1, $baslangic+2, 2)
    let $t7 := concat($t2, '+', $t3, ':00')
    let $t8 := xs:dateTime($t7)

	return $t8
};

declare function hs:nACheck($x as xs:anyAtomicType) as xs:boolean
{
  let $result := if (compare(xs:string($x),xs:string("N/A")) eq 0)
				 then true()
				 else false()

  return $result
} ;

declare function hs:stringCheck($x as xs:anyAtomicType) as xs:boolean
{
typeswitch ($x)

case xs:string return true()
default
return false()
} ;

(: jobProperties icinde gelen baslangic ve bitis tarih araligindaki o jobin calisma bilgilerini donuyor :)
declare function hs:getJobs($jobProperty as element(dat:jobProperties), $jobPath) as element(dat:jobProperties)*
{
	let $doc := doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")
	for $jobs in $jobPath (:/TlosProcessDataAll/RUN/dat:TlosProcessData/dat:scenario[com:jsName = 'Senaryo3']/dat:jobList/dat:jobProperties:)
		where $jobs/dat:baseJobInfos/com:jsName = $jobProperty/dat:baseJobInfos/com:jsName and not($jobs[@agentId="0"])
		and ( if(not(empty($jobProperty/dat:timeManagement/dat:jsRealTime/dat:startTime)) and not(empty($jobProperty/dat:timeManagement/dat:jsRealTime/dat:stopTime)))
 				 then 	not(empty($jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date))
						and (string($jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date) != '')
						and	$jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date >= $jobProperty/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date
						and $jobs/dat:timeManagement/dat:jsRealTime/dat:startTime/com:date <= $jobProperty/dat:timeManagement/dat:jsRealTime/dat:stopTime/com:date
				  else true()
			)
	return  $jobs
};

(:
Kullanim:
let $kacEleman := 1
let $jobId := 0 (: Eger belirli bir jobId girilirse o job ile ilgili sonuclar, sifir girilirse butun joblar ile ilgili sonuclar:)
let $runId := 0 (: Eger belirli bir runId girilirse oradan geriye, sifir girilirse en son runId den geriye:)
let $refRunIdBolean := true()  (: Eger true secilirse bu runId yi referans kabul et anlamina gelir. false ise runId yi dikkate almaz.:)

return hs:jobStateListbyRunId($kacEleman, $runId, $jobId, $refRunIdBolean)
:)
declare function hs:jobStateListbyRunId($numberOfElement as xs:int, $runId as xs:int, $jobId as xs:int, $refRunIdBolean as xs:boolean) as node()*
 {

    let $runIdFound := if ($runId != 0 )
	                   then $runId
	                   else sq:getId("runId")

    let $posUpper := max(for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
	                 where $runx[@id = $runIdFound] or not($refRunIdBolean)
	                 return $pos)

    let $posLower := if ($posUpper - $numberOfElement > 0) then $posUpper - $numberOfElement else 0

    let $nextId := sq:getNextId("reportId")
    let $createBlankReport := hs:insertStateReportLock($jobId, $nextId)

	let $arasonuc := for $runx at $pos in doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")/TlosProcessDataAll/RUN
					 where $pos > $posLower and $pos <=$posUpper and $runx//dat:jobProperties[(@ID = $jobId or $jobId = 0) and @agentId!="0"]
					 order by $runx/@id descending
	                 return hs:jobStateReport($runx/dat:TlosProcessData, $jobId, $nextId)
    let $sonuc := if(exists($arasonuc))
	              then hs:searchStateReportById(sq:getReportId())
	              else ()
	return $sonuc
};

declare function hs:jobStateReport($n as element(dat:TlosProcessData), $jobId as xs:int, $nextId as xs:int) as node()*
{
   (: Son state leri belirleme kismi :)
   let $propertiesList := $n//dat:jobProperties[(@ID = $jobId or $jobId = 0)]
   let $stateList :=
         for $donbaba in fn:distinct-values($propertiesList/@ID)
         let $jobsInGroup := $propertiesList[@ID = $donbaba]
         return
             let $kacdefa := count($jobsInGroup)
             let $list := if ($kacdefa = 1) then $jobsInGroup[@agentId="0"]/dat:stateInfos/state-types:LiveStateInfos
                          else $jobsInGroup[@agentId!="0"][1]/dat:stateInfos/state-types:LiveStateInfos
         return hs:jobStateReportFromLiveStateInfo($list, $jobId, $nextId)

    let $sonuc2 := for $runx at $pos in $stateList/state-types:LiveStateInfo
                   order by $runx/@LSIDateTime descending
	               return $runx
	return $sonuc2
 };

declare function hs:jobStateReportFromLiveStateInfo($stateList as element(state-types:LiveStateInfos), $jobId as xs:int, $nextId as xs:int) as node()*
{
   let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")

	let $sonuc2 := (for $runx at $pos in $stateList/state-types:LiveStateInfo
                   order by $runx/@LSIDateTime descending
	               return $runx)[1]

    (: raporu guncelleme kismi :)
(:    let $ee := data($sonuc2/state-types:StateName)
    let $test := concat(xs:string("rep:reportAll/rep:stateReport/rep:report/rep:"),$ee):)

	let $valStateName := $sonuc2/state-types:StateName
	let $valSubstateName := $sonuc2/state-types:SubstateName
	let $valStatusName := $sonuc2/state-types:StatusName

    let $relPath := $docrep/rep:reportAll/rep:stateReport/rep:report[@id=$nextId]

    let $sorgu := if ( empty($sonuc2/state-types:StatusName) )
	           then
			     if ( empty($sonuc2/state-types:SubstateName) )
	             then util:eval(concat("<rep:", $valStateName, ">", $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]  + 1, "</rep:",$valStateName,">"))
			     else util:eval(concat("<rep:", $valSubstateName, ">", $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]  + 1 , "</rep:",$valSubstateName,">"))
			   else util:eval(concat("<rep:", $valStatusName, ">", $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]/rep:*[local-name() eq $sonuc2/state-types:StatusName] + 1 , "</rep:",$valStatusName,">"))

    let $df := if ( empty($sonuc2/state-types:StatusName) )
	           then
			     if ( empty($sonuc2/state-types:SubstateName) )
	             then update replace $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]
				                with $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]  + 1
			     else update replace $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]
				                with $sorgu
			   else update replace $relPath/rep:*[local-name() eq $sonuc2/state-types:StateName]/rep:*[local-name() eq $sonuc2/state-types:SubstateName]/rep:*[local-name() eq $sonuc2/state-types:StatusName]
			                    with $sorgu

   return <ss>{$sonuc2}</ss>
};

declare function hs:insertStateReportLock($jsId as xs:int, $nextId as xs:int) as xs:boolean
{
   let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")
   let $relPath := $docrep/rep:reportAll/rep:stateReport

   let $sonuc := util:exclusive-lock($relPath, hs:insertBlankStateReport($jsId, $nextId))
   return true()
};

declare function hs:insertBlankStateReport($jsId as xs:int, $nextId as xs:int) as node()*
{

   let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")
   let $relPath := $docrep/rep:reportAll/rep:stateReport

(:    let $nextId := sq:getNextId("reportId")	:)
    let $scope := xs:string("job")
	return update insert
		<rep:report xmlns="http://www.likyateknoloji.com/XML_report_types" id="{$nextId}" jsId="{$jsId}" scope="{$scope}" LSIDateTime="{current-dateTime()}">
			<rep:PENDING>
				<rep:CREATED>0</rep:CREATED>
				<rep:DEACTIVATED>0</rep:DEACTIVATED>
				<rep:VALIDATED>0</rep:VALIDATED>
				<rep:IDLED>
					<rep:BYTIME>0</rep:BYTIME>
					<rep:BYUSER>0</rep:BYUSER>
                    <rep:BYEVENT>0</rep:BYEVENT>
				</rep:IDLED>
				<rep:READY>
					<rep:LOOKFOR-RESOURCE>0</rep:LOOKFOR-RESOURCE>
					<rep:USER-CHOOSE-RESOURCE>0</rep:USER-CHOOSE-RESOURCE>
					<rep:USER-WAITING>0</rep:USER-WAITING>
					<rep:WAITING>0</rep:WAITING>
					<rep:TRANSFERING>0</rep:TRANSFERING>
				</rep:READY>
				<rep:PAUSED>0</rep:PAUSED>
			</rep:PENDING>
			<rep:RUNNING>
				<rep:STAGE-IN>0</rep:STAGE-IN>
				<rep:MIGRATING>0</rep:MIGRATING>
				<rep:ON-RESOURCE>
					<rep:TIME-IN>0</rep:TIME-IN>
					<rep:TIME-OUT>0</rep:TIME-OUT>
				</rep:ON-RESOURCE>
				<rep:HELD>0</rep:HELD>
				<rep:STAGE-OUT>0</rep:STAGE-OUT>
			</rep:RUNNING>
			<rep:FAILED>0</rep:FAILED>
			<rep:CANCELLED>0</rep:CANCELLED>
			<rep:FINISHED>
				<rep:COMPLETED>
					<rep:SUCCESS>0</rep:SUCCESS>
					<rep:WARNING>0</rep:WARNING>
					<rep:FAILED>0</rep:FAILED>
				</rep:COMPLETED>
				<rep:SKIPPED>0</rep:SKIPPED>
				<rep:STOPPED>0</rep:STOPPED>
			</rep:FINISHED>
		</rep:report>
	into $relPath
} ;

declare function hs:searchStateReportById($reportId as xs:int) as element(rep:report)?
 {
    let $docrep := doc("//db/TLOSSW/xmls/tlosSWReports10.xml")
	let $relPath := $docrep/rep:reportAll/rep:stateReport/rep:report

	for $report in $relPath
	where $report/@id = $reportId
    return $report
};

(:declare function hs:getJobs($jobProperty as element(dat:jobProperties), $jobPath) as element(dat:jobProperties)*
{
	let $doc := doc("//db/TLOSSW/xmls/tlosSWDailyScenarios10.xml")
	for $jobs in $jobPath (:/TlosProcessDataAll/RUN/dat:TlosProcessData/dat:scenario[com:jsName = 'Senaryo3']/dat:jobList/dat:jobProperties:)
		where $jobs/com:jsName = $jobProperty/com:jsName
		and ( if(not(empty($jobProperty/dat:jobRealTime/dat:startTime)) and not(empty($jobProperty/dat:jobRealTime/dat:stopTime)))
 				 then 	not(empty($jobs/dat:jobRealTime/dat:startTime/com:date/com:year))
						and (string($jobs/dat:jobRealTime/dat:startTime/com:date/com:year) != '')
						and not(empty($jobs/dat:jobRealTime/dat:startTime/com:date/com:month))
						and (string($jobs/dat:jobRealTime/dat:startTime/com:date/com:month) != '')
						and not(empty($jobs/dat:jobRealTime/dat:startTime/com:date/com:day))
						and (string($jobs/dat:jobRealTime/dat:startTime/com:date/com:day) != '')
						and	xs:date(concat($jobs/dat:jobRealTime/dat:startTime/com:date/com:year,'-', $jobs/dat:jobRealTime/dat:startTime/com:date/com:month,'-',$jobs/dat:jobRealTime/dat:startTime/com:date/com:day ) )
							>=  xs:date(concat($jobProperty/dat:jobRealTime/dat:startTime/com:date/com:year,'-', $jobProperty/dat:jobRealTime/dat:startTime/com:date/com:month,'-',$jobProperty/dat:jobRealTime/dat:startTime/com:date/com:day ) )
						and xs:date(concat($jobs/dat:jobRealTime/dat:startTime/com:date/com:year,'-', $jobs/dat:jobRealTime/dat:startTime/com:date/com:month,'-',$jobs/dat:jobRealTime/dat:startTime/com:date/com:day ) )
							<=  xs:date(concat($jobProperty/dat:jobRealTime/dat:stopTime/com:date/com:year,'-', $jobProperty/dat:jobRealTime/dat:stopTime/com:date/com:month,'-',$jobProperty/dat:jobRealTime/dat:stopTime/com:date/com:day ) )
				  else ("TRUE")
			)
	return  $jobs
};:)