Skip to content

Commit

Permalink
Merge pull request #6 from KainosSoftwareLtd/VEL-1157-extension-tosor…
Browse files Browse the repository at this point in the history
…t-on-conditions-on-nested-fields

extension to sort on nested parameters
  • Loading branch information
szymonp-kainos committed Jun 8, 2016
2 parents b8420ac + 798a0b4 commit 516dae3
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 9 deletions.
5 changes: 5 additions & 0 deletions src/fhir/meta_pg.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ exports.getter = (plv8, rt, query)->
select: sql.raw('*')
from: sql.q(tbl_name)
where: {"resource->>'name'": query.name }
else if rt = "SearchParameter"
utils.exec plv8,
select: sql.raw('*')
from: sql.q(tbl_name)
where: {"resource->>'name'": query.name.split(".")[0], "resource->>'base'": query.base}
else
utils.exec plv8,
select: sql.raw('*')
Expand Down
50 changes: 45 additions & 5 deletions src/fhir/search.litcoffee
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,20 @@ To build search query we need to
if expr.sort
ordering = order_hsql(alias, expr.sort)
hsql =
select: ':*'
from: ['$alias', ['$q', "#{namings.table_name(plv8, expr.query)}"], alias]
where: expr.where
order: ordering
if expr.sort && is_nested_order(expr.sort)
nested_order_query = get_nested_order_query(expr, alias)
hsql =
select: nested_order_query.select,
from: nested_order_query.from,
join: nested_order_query.join,
where: nested_order_query.where,
order: ordering
else
hsql =
select: ':*'
from: ['$alias', ['$q', "#{namings.table_name(plv8, expr.query)}"], alias]
where: expr.where
order: ordering
if expr.count != null || expr.page != null
hsql.limit = expr.count || DEFAULT_RESOURCES_PER_PAGE
Expand Down Expand Up @@ -271,6 +280,37 @@ implementation based on searchType
throw new Error("Search type does not exports order_expression fn: [#{meta.searchType}] #{JSON.stringify(meta)}")
h.order_expression(tbl, meta)
is_nested_order = (params)->
for meta in params.map((x)-> x[1])
name = meta.name
if name.split(".").length > 1
return true
return false
nested_table = (params)->
for meta in params.map((x)-> x[1])
name = meta.name
if name.split(".").length > 1
return name.split(".")[0]
get_nested_order_query = (expr, alias)->
nested_table_name = nested_table(expr.sort)
table_name = namings.table_name(plv8, expr.query)
if table_name == "appointment"
{
select: ":#{table_name}.*",
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}"],
join: [[["$raw", "#{nested_table_name} AS #{alias}"],["$raw", "#{alias}.id = subelem_id"]]],
where: expr.where
}
else if table_name == "encounter"
{
select: ":#{table_name}.*",
from: ['$alias', ['$q', "#{nested_table_name}"], alias],
join: [["#{table_name}", "#{alias}.id=split_part((\"#{table_name}\".resource->'#{nested_table_name}'->>'reference'), '/', 2)"]],
where: expr.where
}

### Handling chained parameters

Expand Down
2 changes: 1 addition & 1 deletion src/fhir/search_common.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ get_search_functions = (obj) ->

}

exports.get_search_functions = get_search_functions
exports.get_search_functions = get_search_functions
26 changes: 26 additions & 0 deletions src/fhir/search_nested.litcoffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Search and indexing nested elements

sql = require('../honey')
lang = require('../lang')
xpath = require('./xpath')
search_common = require('./search_common')
paths = {
"patient.given" : "\"tbl1\".resource->'name'->0->'given'->0",
"patient.family" : "\"tbl1\".resource->'name'->0->'family'->0",
"patient.birthDate" : "\"tbl1\".resource->'birthDate'",
"practitioner.given" : "\"tbl1\".resource->'name'->0->'given'->0",
"practitioner.family" : "\"tbl1\".resource->'name'->0->'family'->0",
}
exports.order_expression = (tbl, meta)->
elem = meta.name
expression = paths[elem]
if meta.operator == "desc"
expression += " DESC"
expression
exports.order_expression.plv8_signature =
arguments: ['text', 'json']
returns: 'json'
immutable: true
6 changes: 5 additions & 1 deletion src/fhir/search_reference.litcoffee
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Only equality operator is implemented.
xpath = require('./xpath')
lang = require('../lang')
search_token = require('./search_token')
search_nested = require('./search_nested')
TODO = -> throw new Error("TODO")
Expand Down Expand Up @@ -109,7 +110,10 @@ Only equality operator is implemented.
op(tbl, meta, value)
exports.order_expression = (tbl, meta)->
search_token.order_expression(tbl, meta)
if meta.name.split(".").length>1
search_nested.order_expression(tbl, meta)
else
search_token.order_expression(tbl, meta)
exports.index = (plv8, metas)->
meta = metas[0]
Expand Down
9 changes: 7 additions & 2 deletions src/fhir/search_token.litcoffee
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ PostgreSQL implementation is based on arrays support - http://www.postgresql.org
'date'
]
sf = search_common.get_search_functions({extract:'fhir_extract_as_token', sort:'fhir_sort_as_token',SUPPORTED_TYPES:SUPPORTED_TYPES})
sf = search_common.get_search_functions({extract:'fhir_extract_as_token', sort:'fhir_sort_as_token', SUPPORTED_TYPES:SUPPORTED_TYPES})
extract_expr = sf.extract_expr
exports.order_expression = sf.order_expression
Expand Down Expand Up @@ -74,12 +74,17 @@ PostgreSQL implementation is based on arrays support - http://www.postgresql.org
else if element_type == 'Reference'
for ref in data
res.push(ref.reference)
else if element_type == 'ReferenceUid'
for ref in data
res.push(ref.reference.split("/")[1])
else if element_type == 'ReferenceUidTxt'
for ref in data
res = ref.reference.split("/")[1]
else
throw new Error("fhir_extract_as_token: Not implemented for #{element_type}")
# console.log("!!!! #{resource.id} #{JSON.stringify(data)} #{JSON.stringify(path)} => #{JSON.stringify(res)} (#{element_type})")

if res.length == 0
['$NULL']
else
Expand Down

0 comments on commit 516dae3

Please sign in to comment.