Skip to content

Commit 516dae3

Browse files
Merge pull request #6 from KainosSoftwareLtd/VEL-1157-extension-tosort-on-conditions-on-nested-fields
extension to sort on nested parameters
2 parents b8420ac + 798a0b4 commit 516dae3

File tree

6 files changed

+89
-9
lines changed

6 files changed

+89
-9
lines changed

src/fhir/meta_pg.coffee

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ exports.getter = (plv8, rt, query)->
1010
select: sql.raw('*')
1111
from: sql.q(tbl_name)
1212
where: {"resource->>'name'": query.name }
13+
else if rt = "SearchParameter"
14+
utils.exec plv8,
15+
select: sql.raw('*')
16+
from: sql.q(tbl_name)
17+
where: {"resource->>'name'": query.name.split(".")[0], "resource->>'base'": query.base}
1318
else
1419
utils.exec plv8,
1520
select: sql.raw('*')

src/fhir/search.litcoffee

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,20 @@ To build search query we need to
217217
if expr.sort
218218
ordering = order_hsql(alias, expr.sort)
219219
220-
hsql =
221-
select: ':*'
222-
from: ['$alias', ['$q', "#{namings.table_name(plv8, expr.query)}"], alias]
223-
where: expr.where
224-
order: ordering
220+
if expr.sort && is_nested_order(expr.sort)
221+
nested_order_query = get_nested_order_query(expr, alias)
222+
hsql =
223+
select: nested_order_query.select,
224+
from: nested_order_query.from,
225+
join: nested_order_query.join,
226+
where: nested_order_query.where,
227+
order: ordering
228+
else
229+
hsql =
230+
select: ':*'
231+
from: ['$alias', ['$q', "#{namings.table_name(plv8, expr.query)}"], alias]
232+
where: expr.where
233+
order: ordering
225234
226235
if expr.count != null || expr.page != null
227236
hsql.limit = expr.count || DEFAULT_RESOURCES_PER_PAGE
@@ -271,6 +280,37 @@ implementation based on searchType
271280
throw new Error("Search type does not exports order_expression fn: [#{meta.searchType}] #{JSON.stringify(meta)}")
272281
h.order_expression(tbl, meta)
273282
283+
is_nested_order = (params)->
284+
for meta in params.map((x)-> x[1])
285+
name = meta.name
286+
if name.split(".").length > 1
287+
return true
288+
return false
289+
290+
nested_table = (params)->
291+
for meta in params.map((x)-> x[1])
292+
name = meta.name
293+
if name.split(".").length > 1
294+
return name.split(".")[0]
295+
296+
get_nested_order_query = (expr, alias)->
297+
nested_table_name = nested_table(expr.sort)
298+
table_name = namings.table_name(plv8, expr.query)
299+
if table_name == "appointment"
300+
{
301+
select: ":#{table_name}.*",
302+
from: ['$raw', "(SELECT split_part((json_array_elements((\"#{table_name}\".resource->'participant')::json)->'actor'->>'reference')::text, '/', 2)::text as subelem_id, \"#{table_name}\".* FROM \"#{table_name}\") AS #{table_name}"],
303+
join: [[["$raw", "#{nested_table_name} AS #{alias}"],["$raw", "#{alias}.id = subelem_id"]]],
304+
where: expr.where
305+
}
306+
else if table_name == "encounter"
307+
{
308+
select: ":#{table_name}.*",
309+
from: ['$alias', ['$q', "#{nested_table_name}"], alias],
310+
join: [["#{table_name}", "#{alias}.id=split_part((\"#{table_name}\".resource->'#{nested_table_name}'->>'reference'), '/', 2)"]],
311+
where: expr.where
312+
}
313+
274314

275315
### Handling chained parameters
276316

src/fhir/search_common.coffee

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ get_search_functions = (obj) ->
4949

5050
}
5151

52-
exports.get_search_functions = get_search_functions
52+
exports.get_search_functions = get_search_functions

src/fhir/search_nested.litcoffee

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Search and indexing nested elements
2+
3+
sql = require('../honey')
4+
lang = require('../lang')
5+
xpath = require('./xpath')
6+
search_common = require('./search_common')
7+
8+
paths = {
9+
"patient.given" : "\"tbl1\".resource->'name'->0->'given'->0",
10+
"patient.family" : "\"tbl1\".resource->'name'->0->'family'->0",
11+
"patient.birthDate" : "\"tbl1\".resource->'birthDate'",
12+
"practitioner.given" : "\"tbl1\".resource->'name'->0->'given'->0",
13+
"practitioner.family" : "\"tbl1\".resource->'name'->0->'family'->0",
14+
}
15+
16+
exports.order_expression = (tbl, meta)->
17+
elem = meta.name
18+
expression = paths[elem]
19+
if meta.operator == "desc"
20+
expression += " DESC"
21+
expression
22+
23+
exports.order_expression.plv8_signature =
24+
arguments: ['text', 'json']
25+
returns: 'json'
26+
immutable: true

src/fhir/search_reference.litcoffee

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Only equality operator is implemented.
1717
xpath = require('./xpath')
1818
lang = require('../lang')
1919
search_token = require('./search_token')
20+
search_nested = require('./search_nested')
2021
2122
TODO = -> throw new Error("TODO")
2223
@@ -109,7 +110,10 @@ Only equality operator is implemented.
109110
op(tbl, meta, value)
110111
111112
exports.order_expression = (tbl, meta)->
112-
search_token.order_expression(tbl, meta)
113+
if meta.name.split(".").length>1
114+
search_nested.order_expression(tbl, meta)
115+
else
116+
search_token.order_expression(tbl, meta)
113117
114118
exports.index = (plv8, metas)->
115119
meta = metas[0]

src/fhir/search_token.litcoffee

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ PostgreSQL implementation is based on arrays support - http://www.postgresql.org
3030
'date'
3131
]
3232
33-
sf = search_common.get_search_functions({extract:'fhir_extract_as_token', sort:'fhir_sort_as_token',SUPPORTED_TYPES:SUPPORTED_TYPES})
33+
sf = search_common.get_search_functions({extract:'fhir_extract_as_token', sort:'fhir_sort_as_token', SUPPORTED_TYPES:SUPPORTED_TYPES})
3434
extract_expr = sf.extract_expr
3535
3636
exports.order_expression = sf.order_expression
@@ -74,12 +74,17 @@ PostgreSQL implementation is based on arrays support - http://www.postgresql.org
7474
else if element_type == 'Reference'
7575
for ref in data
7676
res.push(ref.reference)
77+
else if element_type == 'ReferenceUid'
78+
for ref in data
79+
res.push(ref.reference.split("/")[1])
80+
else if element_type == 'ReferenceUidTxt'
81+
for ref in data
82+
res = ref.reference.split("/")[1]
7783
else
7884
throw new Error("fhir_extract_as_token: Not implemented for #{element_type}")
7985
8086
# console.log("!!!! #{resource.id} #{JSON.stringify(data)} #{JSON.stringify(path)} => #{JSON.stringify(res)} (#{element_type})")
8187
82-
8388
if res.length == 0
8489
['$NULL']
8590
else

0 commit comments

Comments
 (0)