Skip to content

Instantly share code, notes, and snippets.

@andreypopp
Created May 21, 2021 15:42
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 andreypopp/d3b29778714f17b5aafcd8641da43336 to your computer and use it in GitHub Desktop.
Save andreypopp/d3b29778714f17b5aafcd8641da43336 to your computer and use it in GitHub Desktop.
module OHDSI
import Tables
import LibPQ
import JSON
import Dates
db = LibPQ.Connection("")
sql(query, args...) =
LibPQ.execute(db, query, args;
type_map=Dict(:jsonb=>Any),
conversions=Dict((:jsonb, Any)=>(x)->JSON.parse(String(x)))
)
abstract type ConceptExpr end
Base.@kwdef struct Concept <: ConceptExpr
id::Int
end
Base.@kwdef struct ParentsOf <: ConceptExpr
concept::Concept
end
Base.@kwdef struct ChildrenOf <: ConceptExpr
concept::Concept
end
# Represent ConceptExpr as a plain Julia value suitable for consumption by the
# notebook UI.
info(concept::Concept) = begin
res = sql(
"""
SELECT *, 'OHDSIConcept' as type
FROM concept WHERE concept_id = \$1
""", concept.id
)
Tables.rowtable(res)[1]
end
info(v::ParentsOf) = (
type="OHDSIConceptParentsOf",
concept=info(v.concept),
)
info(v::ChildrenOf) = (
type="OHDSIConceptChildrenOf",
concept=info(v.concept),
)
ConceptValue = Vector{
NamedTuple{
(:concept_id, :concept_name, :domain_id, :vocabulary_id,
:concept_class_id, :standard_concept, :concept_code,
:valid_start_date, :valid_end_date, :invalid_reason),
Tuple{
Union{Missing, Int32},
Union{Missing, String},
Union{Missing, String},
Union{Missing, String},
Union{Missing, String},
Union{Missing, String},
Union{Missing, String},
Union{Missing, Dates.Date},
Union{Missing, Dates.Date},
Union{Missing, String}
}
}
}
computestats(concepts::ConceptValue) = begin
standard=0
nonstandard=0
vocabulary=Dict()
for c in concepts
vocabulary[c.vocabulary_id] = get(vocabulary, c.vocabulary_id, 0) + 1
if c.standard_concept == "S"
standard = standard + 1
else
nonstandard = nonstandard + 1
end
end
(
standard=standard,
nonstandard=nonstandard,
vocabulary=vocabulary
)
end
# Evaluate ConceptExpr and return resulted ConceptValue
eval(v::Concept) = let
items = [info(v)]
(items=items, stats=computestats(items))
end
eval(v::ParentsOf) = begin
rows = sql("""
SELECT c.*
FROM concept c
JOIN concept_ancestor ca
ON c.concept_id = ca.ancestor_concept_id
WHERE
ca.descendant_concept_id = \$1
AND ca.max_levels_of_separation = 1
""", v.concept.id)
items = [row for row in Tables.rowtable(rows)]
(stats=computestats(items), items=items)
end
eval(v::ChildrenOf) = begin
rows = sql("""
SELECT c.*
FROM concept c
JOIN concept_ancestor ca
ON c.concept_id = ca.descendant_concept_id
WHERE
ca.ancestor_concept_id = \$1
AND ca.max_levels_of_separation = 1
""", v.concept.id)
items = [row for row in Tables.rowtable(rows)]
(stats=computestats(items), items=items)
end
Main.PlutoRunner.pluto_show(concept::ConceptExpr) =
info(concept), MIME"application/vnd.ohdsi.concept+object"()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment