conceptql 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +226 -117
  3. data/LICENSE +21 -0
  4. data/README.md +35 -83
  5. data/bin/conceptql +2 -1
  6. data/bin/conceptql_utils +6 -0
  7. data/config/multiple_vocabularies.csv +4 -0
  8. data/config/provenance.yml +489 -0
  9. data/config/race.yml +50 -0
  10. data/config/vocabularies.csv +87 -0
  11. data/lib/conceptql/behaviors/code_lister.rb +23 -0
  12. data/lib/conceptql/behaviors/drugish.rb +17 -0
  13. data/lib/conceptql/behaviors/labish.rb +19 -0
  14. data/lib/conceptql/behaviors/metadatable.rb +226 -73
  15. data/lib/conceptql/behaviors/provenanceable.rb +26 -0
  16. data/lib/conceptql/behaviors/single_event.rb +11 -0
  17. data/lib/conceptql/behaviors/timeless.rb +11 -0
  18. data/lib/conceptql/behaviors/utilizable.rb +206 -0
  19. data/lib/conceptql/behaviors/windowable.rb +27 -0
  20. data/lib/conceptql/cli.rb +117 -108
  21. data/lib/conceptql/columnizer.rb +75 -0
  22. data/lib/conceptql/data_model/base.rb +462 -0
  23. data/lib/conceptql/data_model/gdm.rb +155 -0
  24. data/lib/conceptql/data_model/gdm_wide.rb +42 -0
  25. data/lib/conceptql/data_model/omopv4_plus.rb +12 -0
  26. data/lib/conceptql/data_model.rb +30 -0
  27. data/lib/conceptql/database.rb +214 -0
  28. data/lib/conceptql/date_adjuster.rb +66 -18
  29. data/lib/conceptql/diagram.rb +243 -0
  30. data/lib/conceptql/lexicon/lexicon_gdm.rb +47 -0
  31. data/lib/conceptql/lexicon/lexicon_no_db.rb +49 -0
  32. data/lib/conceptql/lexicon/lexicon_ohdsi.rb +63 -0
  33. data/lib/conceptql/lexicon/lexicon_strategy.rb +116 -0
  34. data/lib/conceptql/lexicon.rb +111 -0
  35. data/lib/conceptql/nodifier.rb +65 -24
  36. data/lib/conceptql/operators/after.rb +34 -14
  37. data/lib/conceptql/operators/any_overlap.rb +8 -6
  38. data/lib/conceptql/operators/before.rb +34 -10
  39. data/lib/conceptql/operators/binary_operator_operator.rb +66 -23
  40. data/lib/conceptql/operators/casting_operator.rb +51 -36
  41. data/lib/conceptql/operators/co_reported.rb +111 -0
  42. data/lib/conceptql/operators/concurrent_within.rb +69 -0
  43. data/lib/conceptql/operators/contains.rb +12 -8
  44. data/lib/conceptql/operators/count.rb +17 -9
  45. data/lib/conceptql/operators/date_range.rb +48 -14
  46. data/lib/conceptql/operators/death.rb +14 -4
  47. data/lib/conceptql/operators/dedup.rb +31 -0
  48. data/lib/conceptql/operators/during.rb +7 -12
  49. data/lib/conceptql/operators/episode.rb +146 -0
  50. data/lib/conceptql/operators/equal.rb +9 -3
  51. data/lib/conceptql/operators/ethnicity.rb +49 -0
  52. data/lib/conceptql/operators/except.rb +19 -12
  53. data/lib/conceptql/operators/filter.rb +23 -8
  54. data/lib/conceptql/operators/first.rb +16 -3
  55. data/lib/conceptql/operators/from.rb +52 -4
  56. data/lib/conceptql/operators/gender.rb +34 -11
  57. data/lib/conceptql/operators/hospice.rb +19 -0
  58. data/lib/conceptql/operators/hospitalization.rb +19 -0
  59. data/lib/conceptql/operators/information_periods.rb +36 -0
  60. data/lib/conceptql/operators/invalid.rb +35 -0
  61. data/lib/conceptql/operators/last.rb +16 -3
  62. data/lib/conceptql/operators/match.rb +91 -0
  63. data/lib/conceptql/operators/multiple_vocabularies.rb +172 -0
  64. data/lib/conceptql/operators/numeric.rb +65 -23
  65. data/lib/conceptql/operators/numeric_filter.rb +68 -0
  66. data/lib/conceptql/operators/occurrence.rb +153 -32
  67. data/lib/conceptql/operators/one_in_two_out.rb +237 -38
  68. data/lib/conceptql/operators/operator.rb +624 -178
  69. data/lib/conceptql/operators/pass_thru.rb +17 -3
  70. data/lib/conceptql/operators/person.rb +18 -6
  71. data/lib/conceptql/operators/person_filter.rb +9 -3
  72. data/lib/conceptql/operators/place_of_service_filter.rb +43 -0
  73. data/lib/conceptql/operators/provenance.rb +55 -0
  74. data/lib/conceptql/operators/provider_filter.rb +62 -0
  75. data/lib/conceptql/operators/race.rb +55 -7
  76. data/lib/conceptql/operators/read.rb +168 -0
  77. data/lib/conceptql/operators/recall.rb +49 -14
  78. data/lib/conceptql/operators/snf.rb +19 -0
  79. data/lib/conceptql/operators/sum.rb +29 -12
  80. data/lib/conceptql/operators/temporal_operator.rb +108 -16
  81. data/lib/conceptql/operators/time_window.rb +20 -32
  82. data/lib/conceptql/operators/trim_date.rb +71 -0
  83. data/lib/conceptql/operators/trim_date_end.rb +28 -40
  84. data/lib/conceptql/operators/trim_date_start.rb +28 -41
  85. data/lib/conceptql/operators/union.rb +67 -6
  86. data/lib/conceptql/operators/vocabulary.rb +151 -0
  87. data/lib/conceptql/paths.rb +41 -0
  88. data/lib/conceptql/query.rb +191 -26
  89. data/lib/conceptql/query_modifiers/gdm/admission_date_query_modifier.rb +46 -0
  90. data/lib/conceptql/query_modifiers/gdm/drug_query_modifier.rb +54 -0
  91. data/lib/conceptql/query_modifiers/gdm/lab_query_modifier.rb +57 -0
  92. data/lib/conceptql/query_modifiers/gdm/pos_query_modifier.rb +46 -0
  93. data/lib/conceptql/query_modifiers/gdm/provenance_query_modifier.rb +45 -0
  94. data/lib/conceptql/query_modifiers/gdm/provider_query_modifier.rb +53 -0
  95. data/lib/conceptql/query_modifiers/gdm_wide/admission_date_query_modifier.rb +42 -0
  96. data/lib/conceptql/query_modifiers/gdm_wide/drug_query_modifier.rb +52 -0
  97. data/lib/conceptql/query_modifiers/gdm_wide/lab_query_modifier.rb +55 -0
  98. data/lib/conceptql/query_modifiers/gdm_wide/pos_query_modifier.rb +37 -0
  99. data/lib/conceptql/query_modifiers/gdm_wide/provenance_query_modifier.rb +38 -0
  100. data/lib/conceptql/query_modifiers/omopv4_plus/admission_date_query_modifier.rb +45 -0
  101. data/lib/conceptql/query_modifiers/omopv4_plus/drug_query_modifier.rb +80 -0
  102. data/lib/conceptql/query_modifiers/omopv4_plus/pos_query_modifier.rb +47 -0
  103. data/lib/conceptql/query_modifiers/omopv4_plus/provenance_query_modifier.rb +45 -0
  104. data/lib/conceptql/query_modifiers/omopv4_plus/provider_query_modifier.rb +26 -0
  105. data/lib/conceptql/query_modifiers/query_modifier.rb +20 -0
  106. data/lib/conceptql/rdbms/duckdb.rb +25 -0
  107. data/lib/conceptql/rdbms/generic.rb +120 -0
  108. data/lib/conceptql/rdbms/postgres.rb +51 -0
  109. data/lib/conceptql/rdbms/spark.rb +22 -0
  110. data/lib/conceptql/rdbms.rb +22 -0
  111. data/lib/conceptql/scope.rb +481 -31
  112. data/lib/conceptql/sql_formatters/formatter.rb +25 -0
  113. data/lib/conceptql/sql_formatters.rb +22 -0
  114. data/lib/conceptql/utils.rb +113 -0
  115. data/lib/conceptql/utils_cli.rb +17 -0
  116. data/lib/conceptql/version.rb +3 -1
  117. data/lib/conceptql/visitors/metadata_extractor.rb +54 -0
  118. data/lib/conceptql/vocabularies/behaviors/costish.rb +24 -0
  119. data/lib/conceptql/vocabularies/behaviors/gdmish.rb +19 -0
  120. data/lib/conceptql/vocabularies/behaviors/omopish.rb +32 -0
  121. data/lib/conceptql/vocabularies/dynamic_vocabularies.rb +63 -0
  122. data/lib/conceptql/vocabularies/entry.rb +138 -0
  123. data/lib/conceptql/vocabularies/vocabulary_class_factory.rb +85 -0
  124. data/lib/conceptql/window/base.rb +26 -0
  125. data/lib/conceptql/window/date_range.rb +25 -0
  126. data/lib/conceptql/window/table.rb +116 -0
  127. data/lib/conceptql/window.rb +72 -0
  128. data/lib/conceptql.rb +65 -2
  129. data/lib/sequel/extensions/pg_ctas_explain.rb +22 -0
  130. data/lib/sequel/extensions/pg_vacuum_table.rb +23 -0
  131. data/schemas/gdm.yml +882 -0
  132. data/schemas/gdm_wide.yml +757 -0
  133. data/schemas/ohdsi_vocabs.yml +143 -0
  134. data/schemas/omopv4_plus.yml +729 -0
  135. data/schemas/omopv4_plus_more_ignorables.tsv +13 -0
  136. metadata +267 -207
  137. data/.gitignore +0 -23
  138. data/Gemfile +0 -4
  139. data/Guardfile +0 -56
  140. data/LICENSE.txt +0 -22
  141. data/Rakefile +0 -1
  142. data/conceptql.gemspec +0 -32
  143. data/doc/ConceptQL Specification (alpha).pdf +0 -0
  144. data/doc/diagram_0.png +0 -0
  145. data/doc/implementation_notes.md +0 -39
  146. data/doc/spec.md +0 -1344
  147. data/lib/conceptql/behaviors/debuggable.rb +0 -70
  148. data/lib/conceptql/behaviors/dottable.rb +0 -103
  149. data/lib/conceptql/behaviors/preppable.rb +0 -20
  150. data/lib/conceptql/converter.rb +0 -65
  151. data/lib/conceptql/debugger.rb +0 -48
  152. data/lib/conceptql/fake_grapher.rb +0 -20
  153. data/lib/conceptql/graph.rb +0 -52
  154. data/lib/conceptql/graph_nodifier.rb +0 -203
  155. data/lib/conceptql/logger.rb +0 -10
  156. data/lib/conceptql/operators/complement.rb +0 -38
  157. data/lib/conceptql/operators/concept.rb +0 -70
  158. data/lib/conceptql/operators/condition_type.rb +0 -71
  159. data/lib/conceptql/operators/cpt.rb +0 -25
  160. data/lib/conceptql/operators/drug_type_concept.rb +0 -21
  161. data/lib/conceptql/operators/from_seer_visits.rb +0 -23
  162. data/lib/conceptql/operators/hcpcs.rb +0 -25
  163. data/lib/conceptql/operators/icd10.rb +0 -28
  164. data/lib/conceptql/operators/icd9.rb +0 -28
  165. data/lib/conceptql/operators/icd9_procedure.rb +0 -25
  166. data/lib/conceptql/operators/intersect.rb +0 -34
  167. data/lib/conceptql/operators/loinc.rb +0 -25
  168. data/lib/conceptql/operators/medcode.rb +0 -28
  169. data/lib/conceptql/operators/medcode_procedure.rb +0 -27
  170. data/lib/conceptql/operators/ndc.rb +0 -29
  171. data/lib/conceptql/operators/observation_by_enttype.rb +0 -29
  172. data/lib/conceptql/operators/observation_period.rb +0 -30
  173. data/lib/conceptql/operators/overlapped_by.rb +0 -23
  174. data/lib/conceptql/operators/overlaps.rb +0 -19
  175. data/lib/conceptql/operators/place_of_service_code.rb +0 -24
  176. data/lib/conceptql/operators/procedure_occurrence.rb +0 -25
  177. data/lib/conceptql/operators/prodcode.rb +0 -29
  178. data/lib/conceptql/operators/rxnorm.rb +0 -24
  179. data/lib/conceptql/operators/snomed.rb +0 -24
  180. data/lib/conceptql/operators/snomed_condition.rb +0 -26
  181. data/lib/conceptql/operators/source_vocabulary_operator.rb +0 -58
  182. data/lib/conceptql/operators/standard_vocabulary_operator.rb +0 -45
  183. data/lib/conceptql/operators/started_by.rb +0 -22
  184. data/lib/conceptql/operators/to_seer_visits.rb +0 -24
  185. data/lib/conceptql/operators/visit.rb +0 -15
  186. data/lib/conceptql/operators/visit_occurrence.rb +0 -30
  187. data/lib/conceptql/tree.rb +0 -53
  188. data/lib/conceptql/utils/temp_table.rb +0 -72
  189. data/spec/conceptql/behaviors/dottable_spec.rb +0 -99
  190. data/spec/conceptql/converter_spec.rb +0 -51
  191. data/spec/conceptql/date_adjuster_spec.rb +0 -68
  192. data/spec/conceptql/operators/after_spec.rb +0 -16
  193. data/spec/conceptql/operators/before_spec.rb +0 -16
  194. data/spec/conceptql/operators/casting_operator_spec.rb +0 -68
  195. data/spec/conceptql/operators/complement_spec.rb +0 -15
  196. data/spec/conceptql/operators/concept_spec.rb +0 -40
  197. data/spec/conceptql/operators/condition_type_spec.rb +0 -128
  198. data/spec/conceptql/operators/contains_spec.rb +0 -19
  199. data/spec/conceptql/operators/cpt_spec.rb +0 -29
  200. data/spec/conceptql/operators/date_range_spec.rb +0 -33
  201. data/spec/conceptql/operators/death_spec.rb +0 -10
  202. data/spec/conceptql/operators/during_spec.rb +0 -30
  203. data/spec/conceptql/operators/except_spec.rb +0 -15
  204. data/spec/conceptql/operators/first_spec.rb +0 -35
  205. data/spec/conceptql/operators/from_spec.rb +0 -13
  206. data/spec/conceptql/operators/gender_spec.rb +0 -27
  207. data/spec/conceptql/operators/hcpcs_spec.rb +0 -29
  208. data/spec/conceptql/operators/icd10_spec.rb +0 -34
  209. data/spec/conceptql/operators/icd9_procedure_spec.rb +0 -29
  210. data/spec/conceptql/operators/icd9_spec.rb +0 -34
  211. data/spec/conceptql/operators/intersect_spec.rb +0 -28
  212. data/spec/conceptql/operators/last_spec.rb +0 -36
  213. data/spec/conceptql/operators/loinc_spec.rb +0 -29
  214. data/spec/conceptql/operators/medcode_procedure_spec.rb +0 -34
  215. data/spec/conceptql/operators/medcode_spec.rb +0 -34
  216. data/spec/conceptql/operators/observation_period_spec.rb +0 -10
  217. data/spec/conceptql/operators/occurrence_spec.rb +0 -87
  218. data/spec/conceptql/operators/overlapped_by_spec.rb +0 -32
  219. data/spec/conceptql/operators/overlaps_spec.rb +0 -21
  220. data/spec/conceptql/operators/person_filter_spec.rb +0 -15
  221. data/spec/conceptql/operators/person_spec.rb +0 -10
  222. data/spec/conceptql/operators/place_of_service_code_spec.rb +0 -24
  223. data/spec/conceptql/operators/procedure_occurrence_spec.rb +0 -10
  224. data/spec/conceptql/operators/prodcode_spec.rb +0 -35
  225. data/spec/conceptql/operators/query_double.rb +0 -20
  226. data/spec/conceptql/operators/query_double_spec.rb +0 -7
  227. data/spec/conceptql/operators/race_spec.rb +0 -21
  228. data/spec/conceptql/operators/rxnorm_spec.rb +0 -29
  229. data/spec/conceptql/operators/snomed_spec.rb +0 -29
  230. data/spec/conceptql/operators/source_vocabulary_operator_spec.rb +0 -35
  231. data/spec/conceptql/operators/standard_vocabulary_operator_spec.rb +0 -35
  232. data/spec/conceptql/operators/started_by_spec.rb +0 -22
  233. data/spec/conceptql/operators/temporal_operator_spec.rb +0 -51
  234. data/spec/conceptql/operators/time_window_spec.rb +0 -77
  235. data/spec/conceptql/operators/union_spec.rb +0 -21
  236. data/spec/conceptql/operators/visit_occurrence_spec.rb +0 -10
  237. data/spec/conceptql/query_spec.rb +0 -22
  238. data/spec/conceptql/tree_spec.rb +0 -50
  239. data/spec/doubles/stream_for_casting_double.rb +0 -9
  240. data/spec/doubles/stream_for_occurrence_double.rb +0 -25
  241. data/spec/doubles/stream_for_temporal_double.rb +0 -6
  242. data/spec/spec_helper.rb +0 -102
@@ -1,34 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/medcode'
3
-
4
- describe ConceptQL::Operators::Medcode do
5
- it_behaves_like(:source_vocabulary_operator)
6
-
7
- subject do
8
- described_class.new
9
- end
10
-
11
- describe '#table' do
12
- it 'should be condition_occurrence' do
13
- expect(subject.table).to eq(:condition_occurrence)
14
- end
15
- end
16
-
17
- describe '#concept_column' do
18
- it 'should be condition_concept_id' do
19
- expect(subject.concept_column).to eq(:condition_concept_id)
20
- end
21
- end
22
-
23
- describe '#source_column' do
24
- it 'should be condition_source_valuej' do
25
- expect(subject.source_column).to eq(:condition_source_value)
26
- end
27
- end
28
-
29
- describe '#vocabulary_id' do
30
- it 'should be 203 (a J&J provided mapping as part of CPRD)' do
31
- expect(subject.vocabulary_id).to eq(203)
32
- end
33
- end
34
- end
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/observation_period'
3
- require_double('stream_for_casting')
4
-
5
- describe ConceptQL::Operators::ObservationPeriod do
6
- it_behaves_like(:casting_operator)
7
- end
8
-
9
-
10
-
@@ -1,87 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/occurrence'
3
- require_double('stream_for_occurrence')
4
-
5
- describe ConceptQL::Operators::Occurrence do
6
- it_behaves_like(:evaluator)
7
-
8
- describe 'occurrence set to 1' do
9
- subject do
10
- described_class.new(1, StreamForOccurrenceDouble.new).query(Sequel.mock(host: 'postgres')).sql
11
- end
12
-
13
- it 'should order by ascending start_date' do
14
- expect(subject).to match('ORDER BY "start_date" ASC')
15
- end
16
-
17
- it 'should partition by person_id' do
18
- expect(subject).to match('PARTITION BY "person_id"')
19
- end
20
-
21
- it 'should assign a row number' do
22
- expect(subject).to match('row_number()')
23
- end
24
-
25
- it 'should find the all rows with "rn" = 1' do
26
- expect(subject).to match('"rn" = 1')
27
- end
28
- end
29
-
30
- describe 'occurrence set to 2' do
31
- subject do
32
- described_class.new(2, StreamForOccurrenceDouble.new).query(Sequel.mock(host: 'postgres')).sql
33
- end
34
-
35
- it 'should order by ascending start_date' do
36
- expect(subject).to match('ORDER BY "start_date" ASC')
37
- end
38
-
39
- it 'should find the all rows with "rn" = 2' do
40
- expect(subject).to match('"rn" = 2')
41
- end
42
- end
43
-
44
- describe 'occurrence set to -1' do
45
- subject do
46
- described_class.new(-1, StreamForOccurrenceDouble.new).query(Sequel.mock(host: 'postgres')).sql
47
- end
48
-
49
- it 'should order by ascending start_date' do
50
- expect(subject).to match('ORDER BY "start_date" DESC')
51
- end
52
-
53
- it 'should find the all rows with "rn" = 1' do
54
- expect(subject).to match('"rn" = 1')
55
- end
56
- end
57
-
58
- describe 'occurrence set to -2' do
59
- subject do
60
- described_class.new(-2, StreamForOccurrenceDouble.new).query(Sequel.mock(host: 'postgres')).sql
61
- end
62
-
63
- it 'should order by ascending start_date' do
64
- expect(subject).to match('ORDER BY "start_date" DESC')
65
- end
66
-
67
- it 'should find the all rows with "rn" = 2' do
68
- expect(subject).to match('"rn" = 2')
69
- end
70
- end
71
-
72
- describe 'occurrence respects types' do
73
- subject do
74
- dub = StreamForOccurrenceDouble.new
75
- def dub.types
76
- [:condition_occurrence]
77
- end
78
- described_class.new(-2, dub).query(Sequel.mock(host: 'postgres')).sql
79
- end
80
-
81
- it 'should order by ascending start_date' do
82
- expect(subject).to match(', "criterion_type", "criterion_id"')
83
- end
84
- end
85
- end
86
-
87
-
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/overlapped_by'
3
- require_double('stream_for_temporal')
4
-
5
- describe ConceptQL::Operators::OverlappedBy do
6
- it_behaves_like(:temporal_operator)
7
-
8
- describe 'when not inclusive' do
9
- subject do
10
- described_class.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new)
11
- end
12
-
13
- it 'should use proper where clause' do
14
- expect(subject.query(Sequel.mock).sql).to match('l.start_date <= r.end_date')
15
- expect(subject.query(Sequel.mock).sql).to match('r.start_date <= l.start_date')
16
- expect(subject.query(Sequel.mock).sql).to match('r.end_date <= l.end_date')
17
- end
18
- end
19
-
20
- describe 'when inclusive' do
21
- subject do
22
- described_class.new(inclusive: true, left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new)
23
- end
24
-
25
- it 'should use proper where clause' do
26
- expect(subject.query(Sequel.mock).sql).to match('l.start_date <= r.end_date')
27
- expect(subject.query(Sequel.mock).sql).to match('r.start_date <= l.start_date')
28
- end
29
- end
30
- end
31
-
32
-
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/overlaps'
3
- require_double('stream_for_temporal')
4
-
5
- describe ConceptQL::Operators::Overlaps do
6
- it_behaves_like(:temporal_operator)
7
-
8
- describe 'when not inclusive' do
9
- subject do
10
- described_class.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new)
11
- end
12
-
13
- it 'should use proper where clause' do
14
- expect(subject.query(Sequel.mock).sql).to match('r.start_date <= l.end_date')
15
- expect(subject.query(Sequel.mock).sql).to match('l.start_date <= r.start_date')
16
- expect(subject.query(Sequel.mock).sql).to match('l.end_date <= r.end_date')
17
- end
18
- end
19
- end
20
-
21
-
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/person_filter'
3
- require_relative 'query_double'
4
-
5
- describe ConceptQL::Operators::PersonFilter do
6
- it_behaves_like(:evaluator)
7
-
8
- describe '#query' do
9
- it 'uses right stream as argument to PERSON_FILTER against left stream' do
10
- double1 = QueryDouble.new(1)
11
- double2 = QueryDouble.new(2)
12
- expect(ConceptQL::Operators::PersonFilter.new(left: double1, right: double2).query(Sequel.mock).sql).to eq("SELECT * FROM (SELECT * FROM table1) AS t1 WHERE (person_id IN (SELECT person_id FROM table2 GROUP BY person_id))")
13
- end
14
- end
15
- end
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/person'
3
- require_double('stream_for_casting')
4
-
5
- describe ConceptQL::Operators::Person do
6
- it_behaves_like(:casting_operator)
7
- end
8
-
9
-
10
-
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/place_of_service_code'
3
-
4
- describe ConceptQL::Operators::PlaceOfServiceCode do
5
- it_behaves_like(:evaluator)
6
-
7
- describe '#query' do
8
- it 'works for 23' do
9
- correct_query = "SELECT * FROM visit_occurrence AS v INNER JOIN vocabulary.concept AS vc ON (vc.concept_id = v.place_of_service_concept_id) WHERE ((vc.concept_code IN ('23')) AND (vc.vocabulary_id = 14))"
10
- expect(ConceptQL::Operators::PlaceOfServiceCode.new('23').query(Sequel.mock).sql).to eq(correct_query)
11
- end
12
-
13
- it 'works for 23 as number' do
14
- correct_query = "SELECT * FROM visit_occurrence AS v INNER JOIN vocabulary.concept AS vc ON (vc.concept_id = v.place_of_service_concept_id) WHERE ((vc.concept_code IN ('23')) AND (vc.vocabulary_id = 14))"
15
- expect(ConceptQL::Operators::PlaceOfServiceCode.new(23).query(Sequel.mock).sql).to eq(correct_query)
16
- end
17
-
18
- it 'works for multiple values' do
19
- correct_query = "SELECT * FROM visit_occurrence AS v INNER JOIN vocabulary.concept AS vc ON (vc.concept_id = v.place_of_service_concept_id) WHERE ((vc.concept_code IN ('23', '22')) AND (vc.vocabulary_id = 14))"
20
- expect(ConceptQL::Operators::PlaceOfServiceCode.new('23', '22').query(Sequel.mock).sql).to eq(correct_query)
21
- end
22
- end
23
- end
24
-
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/procedure_occurrence'
3
- require_double('stream_for_casting')
4
-
5
- describe ConceptQL::Operators::ProcedureOccurrence do
6
- it_behaves_like(:casting_operator)
7
- end
8
-
9
-
10
-
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/prodcode'
3
-
4
- describe ConceptQL::Operators::Prodcode do
5
- it_behaves_like(:source_vocabulary_operator)
6
-
7
- subject do
8
- described_class.new
9
- end
10
-
11
- describe '#table' do
12
- it 'should be drug_exposure' do
13
- expect(subject.table).to eq(:drug_exposure)
14
- end
15
- end
16
-
17
- describe '#concept_column' do
18
- it 'should be drug_concept_id' do
19
- expect(subject.concept_column).to eq(:drug_concept_id)
20
- end
21
- end
22
-
23
- describe '#source_column' do
24
- it 'should be drug_source_valuej' do
25
- expect(subject.source_column).to eq(:drug_source_value)
26
- end
27
- end
28
-
29
- describe '#vocabulary_id' do
30
- it 'should be 200 (a J&J provided mapping as part of CPRD)' do
31
- expect(subject.vocabulary_id).to eq(200)
32
- end
33
- end
34
- end
35
-
@@ -1,20 +0,0 @@
1
- require 'conceptql/operators/operator'
2
- class QueryDouble < ConceptQL::Operators::Operator
3
- def initialize(*args)
4
- super
5
- @num = arguments.first
6
- @type = arguments[1] || :visit_occurrence
7
- end
8
-
9
- def types
10
- [@type]
11
- end
12
-
13
- def evaluate(db)
14
- query(db)
15
- end
16
-
17
- def query(db)
18
- db["table#{@num}".to_sym]
19
- end
20
- end
@@ -1,7 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'query_double'
3
-
4
- describe QueryDouble do
5
- it_behaves_like(:evaluator)
6
- end
7
-
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/race'
3
-
4
- describe ConceptQL::Operators::Race do
5
- it_behaves_like(:evaluator)
6
-
7
- describe '#query' do
8
- it 'works for white' do
9
- correct_query = "SELECT * FROM person AS p INNER JOIN vocabulary.concept AS vc ON (vc.concept_id = p.race_concept_id) WHERE (lower(vc.concept_name) IN ('white'))"
10
- expect(ConceptQL::Operators::Race.new('White').query(Sequel.mock).sql).to eq(correct_query)
11
- expect(ConceptQL::Operators::Race.new('white').query(Sequel.mock).sql).to eq(correct_query)
12
- end
13
-
14
- it 'works for multiple values' do
15
- correct_query = "SELECT * FROM person AS p INNER JOIN vocabulary.concept AS vc ON (vc.concept_id = p.race_concept_id) WHERE (lower(vc.concept_name) IN ('white', 'other'))"
16
- expect(ConceptQL::Operators::Race.new('White', 'Other').query(Sequel.mock).sql).to eq(correct_query)
17
- expect(ConceptQL::Operators::Race.new('white', 'other').query(Sequel.mock).sql).to eq(correct_query)
18
- end
19
- end
20
- end
21
-
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/rxnorm'
3
-
4
- describe ConceptQL::Operators::Rxnorm do
5
- it_behaves_like(:standard_vocabulary_operator)
6
-
7
- subject do
8
- described_class.new
9
- end
10
-
11
- describe '#table' do
12
- it 'should be drug_exposure' do
13
- expect(subject.table).to eq(:drug_exposure)
14
- end
15
- end
16
-
17
- describe '#concept_column' do
18
- it 'should be drug_concept_id' do
19
- expect(subject.concept_column).to eq(:drug_concept_id)
20
- end
21
- end
22
-
23
- describe '#vocabulary_id' do
24
- it 'should be 8' do
25
- expect(subject.vocabulary_id).to eq(8)
26
- end
27
- end
28
- end
29
-
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/snomed'
3
-
4
- describe ConceptQL::Operators::Snomed do
5
- it_behaves_like(:standard_vocabulary_operator)
6
-
7
- subject do
8
- described_class.new
9
- end
10
-
11
- describe '#table' do
12
- it 'should be condition_occurrence' do
13
- expect(subject.table).to eq(:condition_occurrence)
14
- end
15
- end
16
-
17
- describe '#concept_column' do
18
- it 'should be condition_concept_id' do
19
- expect(subject.concept_column).to eq(:condition_concept_id)
20
- end
21
- end
22
-
23
- describe '#vocabulary_id' do
24
- it 'should be 1' do
25
- expect(subject.vocabulary_id).to eq(1)
26
- end
27
- end
28
- end
29
-
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/source_vocabulary_operator'
3
-
4
- describe ConceptQL::Operators::SourceVocabularyOperator do
5
- it_behaves_like(:evaluator)
6
-
7
- class SourceVocabularyDouble < ConceptQL::Operators::SourceVocabularyOperator
8
- def table
9
- :table
10
- end
11
-
12
- def source_column
13
- :source_column
14
- end
15
-
16
- def concept_column
17
- :concept_column
18
- end
19
-
20
- def vocabulary_id
21
- 1
22
- end
23
- end
24
-
25
- describe '#query' do
26
- it 'works for single values' do
27
- expect(SourceVocabularyDouble.new('value').query(Sequel.mock).sql).to eq("SELECT * FROM table AS tab INNER JOIN vocabulary.source_to_concept_map AS scm ON (scm.target_concept_id = tab.concept_column) WHERE ((scm.source_code IN ('value')) AND (scm.source_vocabulary_id = 1) AND (scm.source_code = tab.source_column))")
28
- end
29
-
30
- it 'works for multiple values' do
31
- expect(SourceVocabularyDouble.new('value1', 'value2').query(Sequel.mock).sql).to eq("SELECT * FROM table AS tab INNER JOIN vocabulary.source_to_concept_map AS scm ON (scm.target_concept_id = tab.concept_column) WHERE ((scm.source_code IN ('value1', 'value2')) AND (scm.source_vocabulary_id = 1) AND (scm.source_code = tab.source_column))")
32
- end
33
- end
34
- end
35
-
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/standard_vocabulary_operator'
3
-
4
- describe ConceptQL::Operators::StandardVocabularyOperator do
5
- it_behaves_like(:evaluator)
6
-
7
- class StandardVocabularyDouble < ConceptQL::Operators::StandardVocabularyOperator
8
- def table
9
- :table
10
- end
11
-
12
- def concept_column
13
- :concept_column
14
- end
15
-
16
- def vocabulary_id
17
- 1
18
- end
19
- end
20
-
21
- describe StandardVocabularyDouble do
22
- it_behaves_like(:standard_vocabulary_operator)
23
- end
24
-
25
- describe '#query' do
26
- it 'works for single values' do
27
- expect(StandardVocabularyDouble.new('value').query(Sequel.mock).sql).to eq("SELECT * FROM table AS tab INNER JOIN vocabulary.concept AS c ON (c.concept_id = tab.concept_column) WHERE ((c.concept_code IN ('value')) AND (c.vocabulary_id = 1))")
28
- end
29
-
30
- it 'works for multiple diagnoses' do
31
- expect(StandardVocabularyDouble.new('value1', 'value2').query(Sequel.mock).sql).to eq("SELECT * FROM table AS tab INNER JOIN vocabulary.concept AS c ON (c.concept_id = tab.concept_column) WHERE ((c.concept_code IN ('value1', 'value2')) AND (c.vocabulary_id = 1))")
32
- end
33
- end
34
- end
35
-
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/started_by'
3
- require_double('stream_for_temporal')
4
-
5
- describe ConceptQL::Operators::StartedBy do
6
- it_behaves_like(:temporal_operator)
7
- subject do
8
- described_class.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new)
9
- end
10
-
11
- it 'should use proper where clause' do
12
- expect(subject.query(Sequel.mock).sql).to match('l.start_date = r.start_date')
13
- expect(subject.query(Sequel.mock).sql).to match('l.end_date > r.end_date')
14
- end
15
-
16
- it 'should use proper where clause when inclusive' do
17
- sub = ConceptQL::Operators::StartedBy.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new, inclusive: true)
18
- expect(sub.query(Sequel.mock).sql).to match('l.start_date = r.start_date')
19
- expect(sub.query(Sequel.mock).sql).to match('l.end_date >= r.end_date')
20
- end
21
- end
22
-
@@ -1,51 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/temporal_operator'
3
- require_double('stream_for_temporal')
4
-
5
- describe ConceptQL::Operators::TemporalOperator do
6
- it_behaves_like(:evaluator)
7
-
8
- class TemporalDouble < ConceptQL::Operators::TemporalOperator
9
- def where_clause
10
- Proc.new do
11
- l__end_date < r__start_date
12
- end
13
- end
14
- end
15
-
16
- describe TemporalDouble do
17
- it_behaves_like(:temporal_operator)
18
- end
19
-
20
- describe StreamForTemporalDouble do
21
- it_behaves_like(:evaluator)
22
- end
23
-
24
- describe '#inclusive?' do
25
- it 'defaults to false' do
26
- expect(TemporalDouble.new.inclusive?).to be_falsy
27
- end
28
-
29
- it 'can be set to true' do
30
- expect(TemporalDouble.new(inclusive: true).inclusive?).to be_truthy
31
- end
32
- end
33
-
34
- describe '#query' do
35
- it 'uses logic from where_clause' do
36
- sql = TemporalDouble.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new).query(Sequel.mock).sql
37
- expect(sql).to match('l.end_date < r.start_date')
38
- end
39
-
40
- it 'pulls from the right tables' do
41
- sql = TemporalDouble.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new).query(Sequel.mock).sql
42
- expect(sql).to match('FROM table')
43
- end
44
-
45
- it 'is ok with symbols' do
46
- sql = TemporalDouble.new(left: StreamForTemporalDouble.new, right: StreamForTemporalDouble.new).query(Sequel.mock).sql
47
- expect(sql).to match('FROM table')
48
- end
49
- end
50
- end
51
-
@@ -1,77 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/time_window'
3
- require 'conceptql/operators/operator'
4
-
5
- describe ConceptQL::Operators::TimeWindow do
6
- class Stream4TimeWindowDouble < ConceptQL::Operators::Operator
7
- def types
8
- [:visit_occurrence]
9
- end
10
-
11
- def query(db)
12
- db.from(:table)
13
- end
14
- end
15
-
16
- let (:sequel_mock) do
17
- sequel_mock = double("sequel")
18
- end
19
-
20
- before do
21
- @db_mock = Sequel.mock
22
- end
23
-
24
- describe '#evaluate' do
25
- it 'adjusts start by 1 day' do
26
- expect(sequel_mock).to receive(:date_add).with(Sequel.identifier("start_date"), days: 1).and_return(sequel_mock)
27
- expect(@db_mock).to receive(:extension).with(:date_arithmetic)
28
-
29
- described_class.new(Stream4TimeWindowDouble.new, { start: 'd', end: '', date_manipulator: sequel_mock }).evaluate(@db_mock)
30
- end
31
-
32
- it 'adjusts end by 1 day' do
33
- expect(sequel_mock).to receive(:date_add).with(Sequel.identifier("end_date"), days: 1).and_return(sequel_mock)
34
- described_class.new(Stream4TimeWindowDouble.new, { start: '', end: 'd', date_manipulator: sequel_mock }).evaluate(@db_mock)
35
- end
36
-
37
- it 'adjusts both values by 1 day' do
38
- expect(sequel_mock).to receive(:date_add).with(Sequel.identifier("start_date"), days: 1).and_return(sequel_mock)
39
- expect(sequel_mock).to receive(:date_add).with(Sequel.identifier("end_date"), days: 1).and_return(sequel_mock)
40
- described_class.new(Stream4TimeWindowDouble.new, { start: 'd', end: 'd', date_manipulator: sequel_mock }).evaluate(@db_mock)
41
- end
42
-
43
- it 'makes multiple adjustments to both values' do
44
- expect(sequel_mock).to receive(:date_add).with(Sequel.identifier("start_date"), days: 1).and_return(sequel_mock)
45
- expect(sequel_mock).to receive(:date_add).with(sequel_mock, months: 1).and_return(sequel_mock)
46
- expect(sequel_mock).to receive(:date_add).with(sequel_mock, years: 1).and_return(sequel_mock)
47
-
48
- expect(sequel_mock).to receive(:date_sub).with(Sequel.identifier("end_date"), days: 1).and_return(sequel_mock)
49
- expect(sequel_mock).to receive(:date_sub).with(sequel_mock, months: 1).and_return(sequel_mock)
50
- expect(sequel_mock).to receive(:date_sub).with(sequel_mock, years: 1).and_return(sequel_mock)
51
-
52
- described_class.new(Stream4TimeWindowDouble.new, { start: 'dmy', end: '-d-m-y', date_manipulator: sequel_mock }).evaluate(@db_mock)
53
- end
54
-
55
- it 'can set start_date and end_date to specific dates' do
56
- described_class.new(Stream4TimeWindowDouble.new, { start: '2000-01-01', end: '2000-02-02' }).evaluate(@db_mock)
57
- end
58
-
59
- it 'can set start_date to be end_date' do
60
- described_class.new(Stream4TimeWindowDouble.new, { start: 'end', end: '' }).evaluate(@db_mock)
61
- end
62
-
63
- it 'can set end_date to be start_date' do
64
- described_class.new(Stream4TimeWindowDouble.new, { start: '', end: 'start' }).evaluate(@db_mock)
65
- end
66
-
67
- it 'will swap start and end dates, though this is a bad idea but you should probably know about this' do
68
- described_class.new(Stream4TimeWindowDouble.new, { start: 'end', end: 'start' }).evaluate(@db_mock)
69
- end
70
-
71
- it 'handles nil arguments to both start and end' do
72
- described_class.new(Stream4TimeWindowDouble.new, { start: nil, end: nil }).evaluate(@db_mock)
73
- end
74
- end
75
- end
76
-
77
-
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/union'
3
- require_relative 'query_double'
4
-
5
- describe ConceptQL::Operators::Union do
6
- it_behaves_like(:evaluator)
7
-
8
- describe '#query' do
9
- it 'works for multiple criteria' do
10
- double1 = QueryDouble.new(1)
11
- double2 = QueryDouble.new(2)
12
- double3 = QueryDouble.new(3)
13
- expect(described_class.new(double1, double2, double3).query(Sequel.mock).sql).to eq("SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM table1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM table2) AS t1) AS t1 UNION ALL SELECT * FROM (SELECT * FROM table3) AS t1) AS t1")
14
- end
15
-
16
- it 'works for single criteria' do
17
- double1 = QueryDouble.new(1)
18
- expect(described_class.new(double1).query(Sequel.mock).sql).to eq("SELECT * FROM (SELECT * FROM table1) AS t1")
19
- end
20
- end
21
- end
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
- require 'conceptql/operators/visit_occurrence'
3
- require_double('stream_for_casting')
4
-
5
- describe ConceptQL::Operators::VisitOccurrence do
6
- it_behaves_like(:casting_operator)
7
- end
8
-
9
-
10
-