Skip to content

Instantly share code, notes, and snippets.

@garyvidal
Last active March 21, 2020 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save garyvidal/3b6799faf796b96e21d4 to your computer and use it in GitHub Desktop.
Save garyvidal/3b6799faf796b96e21d4 to your computer and use it in GitHub Desktop.
Fix Sorting issue in xquerrail
(:~
: Returns a list of packageType
: @return element(packageType)*
:)
declare function model:list($model as element(domain:model), $params as item())
as element(list)?
{
let $listable := fn:not(domain:navigation($model)/@listable eq "false")
return
if(fn:not($listable))
then fn:error(xs:QName("MODEL-NOT-LISTABLE"),fn:concat($model/@name, " is not listable"))
else
let $name := $model/@name
let $search := model:list-params($model,$params)
let $persistence := $model/@persistence
let $namespace := domain:get-field-namespace($model)
let $predicateExpr := ()
let $listExpr :=
for $field in $model//(domain:element|domain:attribute)[@name = domain:get-param-keys($params)]
return
domain:get-field-query($field,domain:get-field-value($field,$params))
let $additional-query:= domain:get-param-value($params,"_query")
let $list :=
if ($persistence = 'document') then
let $path := $model/domain:document/text()
let $root := fn:data($model/domain:document/@root)
return
"fn:doc($model/domain:document/text())/*:" || $root || "/*:" || $name || "[cts:contains(.,cts:and-query(($search,$additional-query)))]"
else
let $predicate :=
cts:element-query(fn:QName($namespace,$name),
cts:and-query((
domain:get-base-query($model),
$additional-query,
$search,
$listExpr
))
)
let $_ := xdmp:set($predicateExpr,($predicateExpr,$predicate))
return
(
fn:concat("cts:search(fn:collection(),", $predicate, ")")
)
let $total :=
if($persistence = 'document')
then xdmp:value(fn:concat("fn:count(", $list, ")"))
else xdmp:estimate(cts:search(
fn:collection(),
cts:element-query(fn:QName($namespace,$name),cts:and-query(($search,$predicateExpr)))
))
let $sort :=
let $sort-field := domain:get-param-value($params,"sidx")[1][. ne ""]
let $sort-order := domain:get-param-value($params,"sord")[1]
let $model-sort-field := domain:navigation($model)/@sortField ! domain:get-model-field($model,.)
let $model-order := (domain:navigation($model)/@sortOrder, "ascending")[1]
let $domain-sort-field := $model//(domain:element|domain:attribute)[(domain:get-field-name-key(.),@name) = ($sort-field,$model-sort-field )][1]
let $domain-sort-as :=
if($domain-sort-field)
then fn:concat("[1] cast as ", domain:resolve-datatype($domain-sort-field),"?")
else ()
let $sort-order :=
if($sort-order) then $sort-order
else if($model-order) then $model-order
else ()
return
if(fn:exists($domain-sort-field)) then
let $sortPath := domain:get-field-xpath($domain-sort-field)
return
if($sort-order = ("desc","descending"))
then fn:concat("($__context__",$sortPath,")",$domain-sort-as," descending")
else fn:concat("($__context__",$sortPath,")",$domain-sort-as," ascending")
else if($model-sort-field) then
let $sortPath := domain:get-field-xpath($model-sort-field)
return
if($model-order = ("desc","descending"))
then fn:concat("($__context__",$sortPath,")",$domain-sort-as," descending")
else fn:concat("($__context__",$sortPath,")",$domain-sort-as," ascending")
else ()
(: 'start' is 1-based offset in records from 'page' which is 1-based offset in pages
: which is defined by 'rows'. Perfectly fine to give just start and rows :)
let $page-size := domain:navigation($model)/@pageSize
let $pageSize := xs:integer((domain:get-param-value($params, 'rows'), $page-size, 50)[1])
let $page := xs:integer((domain:get-param-value($params, 'page'),1)[1])
let $start := xs:integer((domain:get-param-value($params, 'start'),1)[1])
let $start := $start + ($page - 1) * $pageSize
let $last := $start + $pageSize - 1
let $end := if ($total > $last) then $last else $total
let $all := domain:get-param-value($params,"all") = "true"
let $resultsExpr :=
if($all) then
if($sort ne "" and fn:exists($sort))
then fn:concat("(for $__context__ in ", $list, " order by ",$sort, " return $__context__)")
else $list
else
if($sort ne "" and fn:exists($sort))
then fn:concat("(for $__context__ in ", $list, " order by ",$sort, " return $__context__)[",$start, " to ",$end,"]")
else fn:concat("(", $list, ")[$start to $end]")
let $results := xdmp:with-namespaces(domain:declared-namespaces($model), xdmp:value($resultsExpr))
let $results :=
if($persistence = "directory")
then
(: $results:)
for $result in $results
return
model:filter-list-result($model,$result/node(),$params)
else $results
return
<list type="{$name}" elapsed="{xdmp:elapsed-time()}">
{ attribute xmlns { domain:get-field-namespace($model) } }
<currentpage>{$page}</currentpage>
<pagesize>{$pageSize}</pagesize>
<totalpages>{fn:ceiling($total div $pageSize)}</totalpages>
<totalrecords>{$total}</totalrecords>
{(:Add Additional Debug Arguments:)
if(domain:get-param-value($params,"debug") = "true") then (
<debugQuery>{xdmp:describe($predicateExpr,(),())}</debugQuery>,
<searchString>{$search}</searchString>,
<sortString>{$sort}</sortString>,
<expr>{$resultsExpr}</expr>,
<params>{$params}</params>
) else ()
}
{$results}
</list>
};

Keybase proof

I hereby claim:

  • I am garyvidal on github.
  • I am garyvidal (https://keybase.io/garyvidal) on keybase.
  • I have a public key ASD1lRosA2YiUf7vQ-pmqiaN1a2FBVGICvvdIR9NbT0mzgo

To claim this, I am signing this object:

{
  "body": {
    "key": {
      "eldest_kid": "0120f5951a2c03662251feef43ea66aa268dd5ad850551880afbdd211f4d6d3d26ce0a",
      "host": "keybase.io",
      "kid": "0120f5951a2c03662251feef43ea66aa268dd5ad850551880afbdd211f4d6d3d26ce0a",
      "uid": "e3d83981b0c9e2f699b4b8239cd46f19",
      "username": "garyvidal"
    },
    "merkle_root": {
      "ctime": 1584785350,
      "hash": "77bc7ea8f0790c7f77c6bfcdea0fa7ed9eec81d18453144cdf31615e4f52ac7d85d2be8ded05a2e143397b694c5ecc230d85ea66bdcb889539fdef9616d9a136",
      "hash_meta": "d9fdfa733ceb4136cd7ac0e82997fda98736dd3b4eb9967fb9e89a5008cfbb61",
      "seqno": 15529202
    },
    "service": {
      "entropy": "gDd/4UvBpJq6ibQKiGAABGoG",
      "name": "github",
      "username": "garyvidal"
    },
    "type": "web_service_binding",
    "version": 2
  },
  "client": {
    "name": "keybase.io go client",
    "version": "5.3.0"
  },
  "ctime": 1584785355,
  "expire_in": 504576000,
  "prev": "c7a49ea9dca32bbc4b1144c6a6385659977e5f89fd5144dd740f7503fd55838e",
  "seqno": 4,
  "tag": "signature"
}

with the key ASD1lRosA2YiUf7vQ-pmqiaN1a2FBVGICvvdIR9NbT0mzgo, yielding the signature:

hKRib2R5hqhkZXRhY2hlZMOpaGFzaF90eXBlCqNrZXnEIwEg9ZUaLANmIlH+70PqZqomjdWthQVRiAr73SEfTW09Js4Kp3BheWxvYWTESpcCBMQgx6SeqdyjK7xLEUTGpjhWWZd+X4n9UUTddA91A/1Vg47EIKqePe5tQeZEHaMoLMJ7FKGe/5gAaE4iCzY4RPeP4QhgAgHCo3NpZ8RAojl+qGcM/PdiK2ldtEaA0hVjxFCiVnmhIUgDxKgrqnePZhMEFsOy6EKQ5D0bJ0RiDxMLPZLQ5gRYun1XQpm5CKhzaWdfdHlwZSCkaGFzaIKkdHlwZQildmFsdWXEIBZycitFvh2L3FJz5jtBq3H9WF6OULi96tDWTGozoP63o3RhZ80CAqd2ZXJzaW9uAQ==

And finally, I am proving ownership of the github account by posting this as a gist.

My publicly-auditable identity:

https://keybase.io/garyvidal

From the command line:

Consider the keybase command line program.

# look me up
keybase id garyvidal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment