conceptql 0.4.1 → 0.6.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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +498 -0
  3. data/config/vocabularies.csv +85 -87
  4. data/config/vocabulary_formats.sha +1 -0
  5. data/config/vocabulary_formats.tsv +39 -0
  6. data/doc/spec.md +2091 -0
  7. data/lib/conceptql/behaviors/metadatable.rb +15 -3
  8. data/lib/conceptql/behaviors/provenanceable.rb +82 -8
  9. data/lib/conceptql/behaviors/utilizable.rb +5 -3
  10. data/lib/conceptql/cli.rb +1 -1
  11. data/lib/conceptql/data_model/base.rb +3 -171
  12. data/lib/conceptql/data_model/gdm.rb +3 -1
  13. data/lib/conceptql/data_model.rb +20 -4
  14. data/lib/conceptql/database.rb +9 -2
  15. data/lib/conceptql/date_adjuster.rb +12 -5
  16. data/lib/conceptql/lexicon/lexicon_gdm.rb +4 -1
  17. data/lib/conceptql/lexicon/lexicon_ohdsi.rb +19 -1
  18. data/lib/conceptql/lexicon/lexicon_strategy.rb +58 -4
  19. data/lib/conceptql/lexicon.rb +218 -2
  20. data/lib/conceptql/nodifier.rb +7 -1
  21. data/lib/conceptql/one_query_counts.rb +120 -0
  22. data/lib/conceptql/operators/co_reported.rb +4 -31
  23. data/lib/conceptql/operators/count.rb +4 -0
  24. data/lib/conceptql/operators/death.rb +1 -1
  25. data/lib/conceptql/operators/dedup.rb +1 -1
  26. data/lib/conceptql/operators/episode.rb +10 -2
  27. data/lib/conceptql/operators/ethnicity.rb +0 -4
  28. data/lib/conceptql/operators/except.rb +5 -0
  29. data/lib/conceptql/operators/filter.rb +12 -2
  30. data/lib/conceptql/operators/hospice.rb +2 -3
  31. data/lib/conceptql/operators/hospitalization.rb +2 -3
  32. data/lib/conceptql/operators/information_periods.rb +5 -4
  33. data/lib/conceptql/operators/invalid.rb +7 -1
  34. data/lib/conceptql/operators/multiple_vocabularies.rb +19 -6
  35. data/lib/conceptql/operators/numeric.rb +51 -14
  36. data/lib/conceptql/operators/occurrence.rb +16 -4
  37. data/lib/conceptql/operators/one_in_two_out.rb +1 -2
  38. data/lib/conceptql/operators/operator.rb +66 -30
  39. data/lib/conceptql/operators/person.rb +1 -1
  40. data/lib/conceptql/operators/person_filter.rb +5 -0
  41. data/lib/conceptql/operators/place_of_service_filter.rb +38 -10
  42. data/lib/conceptql/operators/provenance.rb +13 -4
  43. data/lib/conceptql/operators/provider_filter.rb +5 -1
  44. data/lib/conceptql/operators/race.rb +2 -10
  45. data/lib/conceptql/operators/read.rb +1 -100
  46. data/lib/conceptql/operators/recall.rb +1 -1
  47. data/lib/conceptql/operators/snf.rb +3 -4
  48. data/lib/conceptql/operators/sum.rb +46 -5
  49. data/lib/conceptql/operators/temporal_operator.rb +6 -2
  50. data/lib/conceptql/operators/trim_date.rb +52 -6
  51. data/lib/conceptql/operators/trim_date_end.rb +11 -1
  52. data/lib/conceptql/operators/trim_date_start.rb +11 -1
  53. data/lib/conceptql/operators/union.rb +45 -1
  54. data/lib/conceptql/operators/vocabulary.rb +21 -4
  55. data/lib/conceptql/paths.rb +16 -0
  56. data/lib/conceptql/query.rb +78 -24
  57. data/lib/conceptql/query_modifiers/gdm/provider_query_modifier.rb +7 -7
  58. data/lib/conceptql/rdbms/generic.rb +21 -1
  59. data/lib/conceptql/rdbms/spark.rb +12 -0
  60. data/lib/conceptql/scope.rb +187 -24
  61. data/lib/conceptql/version.rb +1 -1
  62. data/lib/conceptql/vocabularies/drg_systems.rb +118 -0
  63. data/lib/conceptql/vocabularies/dynamic_vocabularies.rb +10 -4
  64. data/lib/conceptql/vocabularies/entry.rb +15 -23
  65. data/lib/conceptql/vocabularies/formats.rb +59 -0
  66. data/lib/conceptql/vocabularies/vocabulary_class_factory.rb +8 -16
  67. data/lib/conceptql/window/table.rb +12 -3
  68. metadata +9 -14
  69. data/lib/conceptql/data_model/omopv4_plus.rb +0 -12
  70. data/lib/conceptql/operators/concurrent_within.rb +0 -69
  71. data/lib/conceptql/query_modifiers/omopv4_plus/admission_date_query_modifier.rb +0 -45
  72. data/lib/conceptql/query_modifiers/omopv4_plus/drug_query_modifier.rb +0 -80
  73. data/lib/conceptql/query_modifiers/omopv4_plus/pos_query_modifier.rb +0 -47
  74. data/lib/conceptql/query_modifiers/omopv4_plus/provenance_query_modifier.rb +0 -45
  75. data/lib/conceptql/query_modifiers/omopv4_plus/provider_query_modifier.rb +0 -26
  76. data/lib/conceptql/vocabularies/behaviors/costish.rb +0 -24
  77. data/lib/conceptql/vocabularies/behaviors/omopish.rb +0 -32
  78. data/schemas/omopv4_plus.yml +0 -729
  79. data/schemas/omopv4_plus_more_ignorables.tsv +0 -13
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+ require_relative "../paths"
5
+
6
+ module ConceptQL
7
+ module Vocabularies
8
+ # The code formats that a Vocabulary operator checks its codes against.
9
+ # They come from config/vocabulary_formats.tsv, a pinned copy of the
10
+ # published table of the public repository
11
+ # outcomesinsights/vocabulary_formats (bead conceptql-bns, seed
12
+ # conceptql-ysx). config/vocabulary_formats.sha records the commit, and
13
+ # `just vocabulary-formats <ref>` refreshes both.
14
+ #
15
+ # Only the DEFAULT row of a vocabulary is used: the row whose vocabulary_id
16
+ # is the vocabulary's id. A variant row (ICD9CM.DOTLESS) is never used. The
17
+ # published patterns carry no anchors, so each one is anchored here as
18
+ # \A(?:pattern)\z. A vocabulary with no row has no format to check.
19
+ #
20
+ # A pattern is case-exact unless its row declares case-insensitivity with
21
+ # the scoped flag (?i:...) (vocabulary_formats seed vfm-8k1, seed
22
+ # conceptql-oji ruling "b"). Ruby honors the flag natively, so a pattern
23
+ # is compiled with no flag of its own: an ignore-case flag would override
24
+ # what the row says.
25
+ module Formats
26
+ DECLARES_CASE_INSENSITIVE = "(?i:"
27
+
28
+ class << self
29
+ # The anchored pattern of a vocabulary as a string, or nil. The
30
+ # vocabulary_id finds its row in any case.
31
+ def pattern(vocabulary_id)
32
+ patterns[vocabulary_id.to_s.downcase]
33
+ end
34
+
35
+ # The anchored pattern as a Regexp, or nil.
36
+ def regexp(vocabulary_id)
37
+ (str = pattern(vocabulary_id)) && Regexp.new(str)
38
+ end
39
+
40
+ # True when the vocabulary's row declares case-insensitivity with
41
+ # (?i:...). The lexicon then matches the vocabulary's codes without
42
+ # regard to case (LexiconStrategy#code_condition). A vocabulary with no
43
+ # row is case-exact.
44
+ def case_insensitive?(vocabulary_id)
45
+ pattern(vocabulary_id).to_s.include?(DECLARES_CASE_INSENSITIVE)
46
+ end
47
+
48
+ private
49
+
50
+ def patterns
51
+ @patterns ||= CSV.foreach(ConceptQL.vocabulary_formats_file_path, col_sep: "\t", headers: true)
52
+ .reject { |row| row["vocabulary_id"].include?(".") }
53
+ .to_h { |row| [ row["vocabulary_id"].downcase, "\\A(?:#{row.fetch("regexp")})\\z" ] }
54
+ .freeze
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -3,8 +3,7 @@
3
3
  require_relative "../behaviors/drugish"
4
4
  require_relative "../behaviors/labish"
5
5
  require_relative "behaviors/gdmish"
6
- require_relative "behaviors/omopish"
7
- require_relative "behaviors/costish"
6
+ require_relative "drg_systems"
8
7
  require_relative "../operators/vocabulary"
9
8
 
10
9
  module ConceptQL
@@ -19,9 +18,8 @@ module ConceptQL
19
18
  def get_klasses
20
19
  {
21
20
  gdm: get_gdm_klass,
22
- gdm_wide: get_gdm_klass,
23
- omopv4_plus: get_omopv4_plus_klass
24
- }.compact
21
+ gdm_wide: get_gdm_klass
22
+ }
25
23
  end
26
24
 
27
25
  def get_gdm_klass
@@ -30,16 +28,6 @@ module ConceptQL
30
28
  end
31
29
  end
32
30
 
33
- def get_omopv4_plus_klass
34
- return nil unless entry.belongs_in_omopv4_plus?
35
-
36
- get_klass do
37
- include Behaviors::Omopish
38
-
39
- include Behaviors::Costish if entry.is_costish?
40
- end
41
- end
42
-
43
31
  def get_klass(&block)
44
32
  ventry = entry
45
33
  Class.new(ConceptQL::Operators::Vocabulary) do |klass|
@@ -52,7 +40,7 @@ module ConceptQL
52
40
  preferred_name entry.preferred_name
53
41
  argument :codes, type: :codelist
54
42
  aliases entry.aliases
55
- predominant_domains entry.predominant_domains
43
+ predominant_domains(*entry.predominant_domains)
56
44
  short_name entry.short_name
57
45
  long_name entry.long_name
58
46
  conceptql_spec_id "vocabulary"
@@ -75,6 +63,10 @@ module ConceptQL
75
63
 
76
64
  include ConceptQL::Behaviors::Drugish if entry.is_drugish?
77
65
 
66
+ include DrgSystems::OperatorBehavior if DrgSystems.system(entry.id)
67
+
68
+ deprecated DrgSystems::DRG_DEPRECATION if entry.id == DrgSystems::DRG_OPERATOR
69
+
78
70
  def vocab_entry
79
71
  self.class.entry
80
72
  end
@@ -25,8 +25,11 @@ module ConceptQL
25
25
 
26
26
  rhs = query.db[get_table_window(query)]
27
27
 
28
+ # select_group replaces the select list, so rhs needs no
29
+ # remove_window_id. Its select_remove asked the database for the
30
+ # columns of the window table while the SQL was built (bead
31
+ # conceptql-6k8).
28
32
  unless opts[:precalculated_window_id]
29
- rhs = remove_window_id(rhs)
30
33
  rhs = rhs
31
34
  .select_group(:person_id, :start_date, :end_date)
32
35
  .select_append do
@@ -37,7 +40,7 @@ module ConceptQL
37
40
 
38
41
  rhs = rhs.as(:r)
39
42
 
40
- remove_window_id(query)
43
+ remove_window_id(query, op.dynamic_columns)
41
44
  .from_self(alias: :l)
42
45
  .join(rhs, expr)
43
46
  .select_all(:l)
@@ -52,12 +55,18 @@ module ConceptQL
52
55
  db[get_table_window(nil)].select(:person_id)
53
56
  end
54
57
 
55
- def remove_window_id(ds)
58
+ # columns: the names of the columns of ds, when the caller knows them.
59
+ # For a ds without a select list, select_remove asks the database for
60
+ # them, and a table that ds reads may not exist while the SQL is built
61
+ # (bead conceptql-6k8).
62
+ def remove_window_id(ds, columns = nil)
56
63
  cols = ds.opts[:select]
57
64
  if cols && !cols.empty? && cols.any? { |c| !c.is_a?(Symbol) }
58
65
  # When select has non-symbol expressions (e.g. CAST...AS),
59
66
  # select_remove can't match them by symbol name, so filter manually
60
67
  ds.select(*cols.reject { |c| window_id_column?(c) })
68
+ elsif columns && cols.blank?
69
+ ds.select(*(columns - [ :window_id ]))
61
70
  else
62
71
  ds.select_remove(:window_id)
63
72
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conceptql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Duryea
@@ -102,7 +102,7 @@ dependencies:
102
102
  version: 0.3.0
103
103
  - - "<"
104
104
  - !ruby/object:Gem::Version
105
- version: '0.5'
105
+ version: '0.6'
106
106
  type: :runtime
107
107
  prerelease: false
108
108
  version_requirements: !ruby/object:Gem::Requirement
@@ -112,7 +112,7 @@ dependencies:
112
112
  version: 0.3.0
113
113
  - - "<"
114
114
  - !ruby/object:Gem::Version
115
- version: '0.5'
115
+ version: '0.6'
116
116
  - !ruby/object:Gem::Dependency
117
117
  name: thor
118
118
  requirement: !ruby/object:Gem::Requirement
@@ -328,6 +328,9 @@ files:
328
328
  - config/provenance.yml
329
329
  - config/race.yml
330
330
  - config/vocabularies.csv
331
+ - config/vocabulary_formats.sha
332
+ - config/vocabulary_formats.tsv
333
+ - doc/spec.md
331
334
  - lib/conceptql.rb
332
335
  - lib/conceptql/behaviors/code_lister.rb
333
336
  - lib/conceptql/behaviors/drugish.rb
@@ -344,7 +347,6 @@ files:
344
347
  - lib/conceptql/data_model/base.rb
345
348
  - lib/conceptql/data_model/gdm.rb
346
349
  - lib/conceptql/data_model/gdm_wide.rb
347
- - lib/conceptql/data_model/omopv4_plus.rb
348
350
  - lib/conceptql/database.rb
349
351
  - lib/conceptql/date_adjuster.rb
350
352
  - lib/conceptql/diagram.rb
@@ -354,13 +356,13 @@ files:
354
356
  - lib/conceptql/lexicon/lexicon_ohdsi.rb
355
357
  - lib/conceptql/lexicon/lexicon_strategy.rb
356
358
  - lib/conceptql/nodifier.rb
359
+ - lib/conceptql/one_query_counts.rb
357
360
  - lib/conceptql/operators/after.rb
358
361
  - lib/conceptql/operators/any_overlap.rb
359
362
  - lib/conceptql/operators/before.rb
360
363
  - lib/conceptql/operators/binary_operator_operator.rb
361
364
  - lib/conceptql/operators/casting_operator.rb
362
365
  - lib/conceptql/operators/co_reported.rb
363
- - lib/conceptql/operators/concurrent_within.rb
364
366
  - lib/conceptql/operators/contains.rb
365
367
  - lib/conceptql/operators/count.rb
366
368
  - lib/conceptql/operators/date_range.rb
@@ -418,11 +420,6 @@ files:
418
420
  - lib/conceptql/query_modifiers/gdm_wide/lab_query_modifier.rb
419
421
  - lib/conceptql/query_modifiers/gdm_wide/pos_query_modifier.rb
420
422
  - lib/conceptql/query_modifiers/gdm_wide/provenance_query_modifier.rb
421
- - lib/conceptql/query_modifiers/omopv4_plus/admission_date_query_modifier.rb
422
- - lib/conceptql/query_modifiers/omopv4_plus/drug_query_modifier.rb
423
- - lib/conceptql/query_modifiers/omopv4_plus/pos_query_modifier.rb
424
- - lib/conceptql/query_modifiers/omopv4_plus/provenance_query_modifier.rb
425
- - lib/conceptql/query_modifiers/omopv4_plus/provider_query_modifier.rb
426
423
  - lib/conceptql/query_modifiers/query_modifier.rb
427
424
  - lib/conceptql/rdbms.rb
428
425
  - lib/conceptql/rdbms/duckdb.rb
@@ -434,11 +431,11 @@ files:
434
431
  - lib/conceptql/utils_cli.rb
435
432
  - lib/conceptql/version.rb
436
433
  - lib/conceptql/visitors/metadata_extractor.rb
437
- - lib/conceptql/vocabularies/behaviors/costish.rb
438
434
  - lib/conceptql/vocabularies/behaviors/gdmish.rb
439
- - lib/conceptql/vocabularies/behaviors/omopish.rb
435
+ - lib/conceptql/vocabularies/drg_systems.rb
440
436
  - lib/conceptql/vocabularies/dynamic_vocabularies.rb
441
437
  - lib/conceptql/vocabularies/entry.rb
438
+ - lib/conceptql/vocabularies/formats.rb
442
439
  - lib/conceptql/vocabularies/vocabulary_class_factory.rb
443
440
  - lib/conceptql/window.rb
444
441
  - lib/conceptql/window/base.rb
@@ -449,8 +446,6 @@ files:
449
446
  - schemas/gdm.yml
450
447
  - schemas/gdm_wide.yml
451
448
  - schemas/ohdsi_vocabs.yml
452
- - schemas/omopv4_plus.yml
453
- - schemas/omopv4_plus_more_ignorables.tsv
454
449
  homepage: https://github.com/outcomesinsights/conceptql
455
450
  licenses:
456
451
  - MIT
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "base"
4
- module ConceptQL
5
- module DataModel
6
- class Omopv4Plus < Base
7
- def base
8
- :omop
9
- end
10
- end
11
- end
12
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "operator"
4
- require_relative "../date_adjuster"
5
-
6
- module ConceptQL
7
- module Operators
8
- class ConcurrentWithin < Operator
9
- register __FILE__
10
-
11
- def events_per_patient
12
- upstreams.all? { |u| u.events_per_patient == :single } ? :single : :multiple
13
- end
14
-
15
- def multiple_vocabularies
16
- return true if upstreams.any?(&:multiple_vocabularies)
17
-
18
- vocabularies.length > 1
19
- end
20
-
21
- desc "Filters each upstream to only include records where other upstreams' date ranges overlap"
22
- option :start, type: :string
23
- option :end, type: :string
24
- allows_many_upstreams
25
- validate_at_least_one_upstream
26
- validate_no_arguments
27
- validate_option DateAdjuster::VALID_INPUT, :start, :end
28
- category "Combine Streams"
29
- basic_type :set
30
- default_query_columns
31
-
32
- def query(db)
33
- datasets = upstreams.map do |stream|
34
- stream.evaluate(db)
35
- end
36
-
37
- return datasets.first.from_self if datasets.length == 1
38
-
39
- adjusted_start_date = DateAdjuster.new(self, options[:start]).adjust(Sequel[:l][:start_date], true)
40
- adjusted_end_date = DateAdjuster.new(self, options[:end]).adjust(Sequel[:l][:end_date])
41
-
42
- datasets = datasets.map do |ds|
43
- matching = ds.from_self(alias: :l)
44
-
45
- (datasets - [ ds ]).each do |other|
46
- other = other
47
- .from_self(alias: :r)
48
- .where(adjusted_start_date <= Sequel[:r][:start_date])
49
- .where(adjusted_end_date >= Sequel[:r][:end_date])
50
- .select(*matching_columns)
51
-
52
- matching = matching.where(other.where(matching_columns.map do |x|
53
- [ Sequel.qualify(:l, x), Sequel.qualify(:r, x) ]
54
- end).exists)
55
- end
56
-
57
- matching
58
- end
59
-
60
- ds, *rest = datasets
61
- rest.each do |other|
62
- ds = ds.union(other, from_self: nil)
63
- end
64
-
65
- ds.from_self
66
- end
67
- end
68
- end
69
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../query_modifier"
4
-
5
- module ConceptQL
6
- module QueryModifiers
7
- module Omopv4Plus
8
- class AdmissionDateQueryModifier < QueryModifier
9
- def self.provided_columns
10
- %i[
11
- admission_date
12
- discharge_date
13
- ]
14
- end
15
-
16
- def self.has_required_columns?(cols)
17
- cols.map(&:to_s).any? { |col| col =~ /start_date/i }
18
- end
19
-
20
- def modified_query
21
- cols = dm.table_cols(source_table).map(&:to_s)
22
- return query unless cols.any? { |col| col =~ /start_date/i }
23
-
24
- start_col = cols.find { |col| col =~ /start_date/i }.to_sym
25
- end_col = cols.find { |col| col =~ /end_date/i }.to_sym
26
-
27
- query.from_self(alias: :t)
28
- .select_all(:t)
29
- .select_append(Sequel[:t][start_col].as(:admission_date))
30
- .select_append(Sequel.function(:coalesce, Sequel[:t][end_col],
31
- Sequel[:t][start_col]).as(:discharge_date))
32
- .from_self
33
- end
34
-
35
- private
36
-
37
- def domain
38
- op.domain
39
- rescue StandardError
40
- nil
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../query_modifier"
4
-
5
- module ConceptQL
6
- module QueryModifiers
7
- module Omopv4Plus
8
- class DrugQueryModifier < QueryModifier
9
- attr_reader :db
10
-
11
- def self.provided_columns
12
- %i[
13
- drug_name
14
- drug_amount
15
- drug_amount_units
16
- drug_quantity
17
- drug_days_supply
18
- ]
19
- end
20
-
21
- def self.has_required_columns?(cols)
22
- needed = [ :drug_concept_id ]
23
- found = needed & cols
24
- needed == found
25
- end
26
-
27
- def initialize(*args)
28
- super
29
- @db = query.db
30
- end
31
-
32
- def modified_query
33
- return query unless dm.table_cols(source_table).include?(:drug_concept_id)
34
-
35
- query.db
36
- drug_concept_ids = query.select(:drug_concept_id).distinct
37
- query.from_self(alias: :de)
38
- .left_join(micro_table(drug_concept_ids).as(:mt), drug_concept_id: :drug_concept_id)
39
- .select_all(:de)
40
- .select_append(Sequel[:de][:quantity].as(:drug_quantity))
41
- .select_append(Sequel[:de][:days_supply].as(:drug_days_supply))
42
- .select_append(Sequel[:mt][:amount_value].as(:drug_amount))
43
- .select_append(Sequel[:mt][:amount_unit].as(:drug_amount_units))
44
- .select_append(Sequel[:mt][:drug_name].as(:drug_name))
45
- .from_self
46
- end
47
-
48
- private
49
-
50
- def micro_table(drug_concept_ids)
51
- # TODO: Does drug_strength only have RXNORM concept_ids?
52
- # TODO: What is vocabulary for units? Can we shrink concept table to just that vocab before joining?
53
- collapsed_strengths = db[:drug_strength]
54
- .where(drug_concept_id: drug_concept_ids)
55
- .select_group(:drug_concept_id)
56
- .select_append(
57
- Sequel.function(:min, :amount_value).as(:amount_value),
58
- Sequel.function(:min, :amount_unit).as(:amount_unit),
59
- Sequel.function(:count, 1).as(:dcount)
60
- )
61
-
62
- value_case = Sequel.case({ 1 => :amount_value }, nil, :dcount).as(:amount_value)
63
- unit_case = Sequel.case({ 1 => :amount_unit }, nil, :dcount).as(:amount_unit)
64
-
65
- collapsed_strengths = collapsed_strengths.from_self.select(:drug_concept_id, value_case, unit_case)
66
-
67
- db.from(Sequel[:concept].as(:dc))
68
- .left_join(collapsed_strengths, { drug_concept_id: :concept_id }, { table_alias: :ds })
69
- .where(Sequel[:dc][:concept_id] => drug_concept_ids)
70
- .select(
71
- Sequel[:dc][:concept_id].as(:drug_concept_id),
72
- Sequel[:dc][:concept_name].as(:drug_name),
73
- Sequel[:ds][:amount_value].as(:amount_value),
74
- Sequel[:ds][:amount_unit].as(:amount_unit)
75
- )
76
- end
77
- end
78
- end
79
- end
80
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../query_modifier"
4
-
5
- module ConceptQL
6
- module QueryModifiers
7
- module Omopv4Plus
8
- class PoSQueryModifier < QueryModifier
9
- attr_reader :join_id, :table, :source_column, :column
10
-
11
- def self.provided_columns
12
- [ :visit_source_concept_id ]
13
- end
14
-
15
- def self.has_required_columns?(cols)
16
- needed = [ :visit_occurrence_id ]
17
- found = needed & cols
18
- needed == found
19
- end
20
-
21
- def initialize(*args)
22
- super
23
- @column = :visit_source_concept_id
24
- @join_id = :visit_occurrence_id
25
- @table = :visit_occurrence
26
- @source_column = :visit_source_concept_id
27
- end
28
-
29
- def modified_query
30
- return query unless dm.table_cols(source_table).include?(join_id)
31
- return query if dm.table_cols(source_table).include?(column)
32
-
33
- left_alias = "tab1".to_sym
34
- right_alias = "tab2".to_sym
35
-
36
- extra_table = query.db.from(table).select(Sequel.as(source_column, column), join_id)
37
- ds = query.from_self(alias: left_alias)
38
- ds.left_join(extra_table.as(right_alias),
39
- Sequel.qualify(left_alias, join_id) => Sequel.qualify(right_alias, join_id))
40
- .select_all(left_alias)
41
- .select_append(Sequel.qualify(right_alias, column).as(column))
42
- .from_self
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../query_modifier"
4
-
5
- module ConceptQL
6
- module QueryModifiers
7
- module Omopv4Plus
8
- class ProvenanceQueryModifier < QueryModifier
9
- RELATED_COLUMNS = %w[
10
- condition_type_concept_id
11
- procedure_type_concept_id
12
- death_type_concept_id
13
- observation_type_concept_id
14
- drug_type_concept_id
15
- ].sort.map(&:to_sym)
16
-
17
- attr_reader :db
18
-
19
- def self.provided_columns
20
- %i[
21
- file_provenance_type
22
- code_provenance_type
23
- ]
24
- end
25
-
26
- def self.has_required_columns?(cols)
27
- !(RELATED_COLUMNS & cols).empty?
28
- end
29
-
30
- def initialize(*args)
31
- super
32
- @db = query.db
33
- end
34
-
35
- def modified_query
36
- return query unless self.class.has_required_columns?(dm.table_cols(source_table))
37
-
38
- query.select_append(Sequel[dm.file_provenance_type_column(query, source_table)].as(:file_provenance_type),
39
- Sequel[dm.code_provenance_type_column(query,
40
- source_table)].as(:code_provenance_type)).from_self
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../query_modifier"
4
-
5
- module ConceptQL
6
- module QueryModifiers
7
- module Omopv4Plus
8
- class ProviderQueryModifier < QueryModifier
9
- def self.provided_columns
10
- [ :provider_id ]
11
- end
12
-
13
- def self.has_required_columns?(cols)
14
- cols.find { |col| col.to_s =~ /provider_id/ }
15
- end
16
-
17
- def modified_query
18
- col = self.class.has_required_columns?(dm.table_cols(source_table))
19
- return query if col.nil? || col.to_sym == :provider_id
20
-
21
- query.select_append(Sequel[col].as(:provider_id)).from_self
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../operators/vocabulary"
4
-
5
- module ConceptQL
6
- module Vocabularies
7
- module Behaviors
8
- module Costish
9
- def query(db)
10
- costs = db[:procedure_cost].where(column_to_search => values).select(:procedure_occurrence_id)
11
- db[:procedure_occurrence].where(procedure_occurrence_id: costs)
12
- end
13
-
14
- def table
15
- :procedure_occurrence
16
- end
17
-
18
- def column_to_search
19
- vocab_entry.id == "revenue_code" ? :revenue_code_source_value : :disease_class_source_value
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ConceptQL
4
- module Vocabularies
5
- module Behaviors
6
- module Omopish
7
- # Overrides Operator#tables
8
- def tables
9
- domains
10
- end
11
-
12
- def vocabulary_condition
13
- { dm.source_vocabulary_id(domain) => vocabulary_id.to_i }
14
- end
15
-
16
- def where_clause(_db)
17
- conds = vocabulary_condition
18
- conds[dm.source_value_column(domain)] = arguments unless select_all?
19
- conds
20
- end
21
-
22
- def query_cols
23
- dm.table_columns(domain)
24
- end
25
-
26
- def translated_vocabulary_id
27
- vocab_entry.omopv4_id
28
- end
29
- end
30
- end
31
- end
32
- end