quality-measure-engine 1.1.5 → 2.0.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 (66) hide show
  1. data/.gitignore +12 -0
  2. data/.travis.yml +16 -0
  3. data/Gemfile +5 -21
  4. data/Gemfile.lock +126 -0
  5. data/LICENSE.txt +13 -0
  6. data/README.md +23 -44
  7. data/Rakefile +6 -29
  8. data/lib/qme/bundle/bundle.rb +34 -0
  9. data/lib/qme/bundle/importer.rb +69 -0
  10. data/lib/qme/database_access.rb +7 -11
  11. data/lib/qme/map/map_reduce_builder.rb +4 -1
  12. data/lib/qme/map/map_reduce_executor.rb +55 -43
  13. data/lib/qme/map/measure_calculation_job.rb +24 -23
  14. data/lib/qme/quality_measure.rb +5 -5
  15. data/lib/qme/quality_report.rb +37 -19
  16. data/lib/qme/railtie.rb +7 -0
  17. data/lib/qme/tasks/bundle.rake +14 -0
  18. data/lib/qme/version.rb +3 -0
  19. data/lib/quality-measure-engine.rb +13 -25
  20. data/quality-measure-engine.gemspec +28 -0
  21. data/test/fixtures/bundles/just_measure_0002.zip +0 -0
  22. data/test/fixtures/delayed_backend_mongoid_jobs/queued_job.json +9 -0
  23. data/test/fixtures/measures/measure_metadata.json +52 -0
  24. data/test/fixtures/records/barry_berry.json +471 -0
  25. data/test/fixtures/records/billy_jones_ipp.json +78 -0
  26. data/test/fixtures/records/jane_jones_numerator.json +120 -0
  27. data/test/fixtures/records/jill_jones_denominator.json +78 -0
  28. data/test/simplecov_setup.rb +18 -0
  29. data/test/test_helper.rb +26 -0
  30. data/test/unit/qme/map/map_reduce_builder_test.rb +38 -0
  31. data/test/unit/qme/map/map_reduce_executor_test.rb +56 -0
  32. data/test/unit/qme/map/measure_calculation_job_test.rb +22 -0
  33. data/test/unit/qme/quality_measure_test.rb +14 -0
  34. data/{spec/qme/quality_report_spec.rb → test/unit/qme/quality_report_test.rb} +32 -20
  35. metadata +91 -115
  36. data/VERSION +0 -1
  37. data/js/map_reduce_utils.js +0 -173
  38. data/js/underscore_min.js +0 -25
  39. data/lib/qme/ext/record.rb +0 -43
  40. data/lib/qme/importer/entry.rb +0 -126
  41. data/lib/qme/importer/generic_importer.rb +0 -117
  42. data/lib/qme/importer/measure_properties_generator.rb +0 -39
  43. data/lib/qme/importer/property_matcher.rb +0 -110
  44. data/lib/qme/measure/database_loader.rb +0 -83
  45. data/lib/qme/measure/measure_loader.rb +0 -174
  46. data/lib/qme/measure/properties_builder.rb +0 -184
  47. data/lib/qme/measure/properties_converter.rb +0 -27
  48. data/lib/qme/randomizer/patient_randomization_job.rb +0 -47
  49. data/lib/qme/randomizer/patient_randomizer.rb +0 -250
  50. data/lib/qme/randomizer/random_patient_creator.rb +0 -47
  51. data/lib/qme_test.rb +0 -13
  52. data/lib/tasks/fixtures.rake +0 -91
  53. data/lib/tasks/measure.rake +0 -110
  54. data/lib/tasks/mongo.rake +0 -68
  55. data/lib/tasks/patient_random.rake +0 -45
  56. data/spec/qme/bundle_spec.rb +0 -37
  57. data/spec/qme/importer/generic_importer_spec.rb +0 -73
  58. data/spec/qme/importer/measure_properties_generator_spec.rb +0 -15
  59. data/spec/qme/importer/property_matcher_spec.rb +0 -174
  60. data/spec/qme/map/map_reduce_builder_spec.rb +0 -38
  61. data/spec/qme/map/measures_spec.rb +0 -38
  62. data/spec/qme/map/patient_mapper_spec.rb +0 -11
  63. data/spec/qme/measure_loader_spec.rb +0 -12
  64. data/spec/qme/properties_builder_spec.rb +0 -61
  65. data/spec/spec_helper.rb +0 -120
  66. data/spec/validate_measures_spec.rb +0 -21
@@ -85,12 +85,15 @@ module QME
85
85
  "function (key, value) {
86
86
  var patient = value;
87
87
  patient.measure_id = \"#{@measure_def['id']}\";\n"
88
- if @params['test_id'] && @params['test_id'].class==BSON::ObjectId
88
+ if @params['test_id'] && @params['test_id'].class==Moped::BSON::ObjectId
89
89
  reduce += " patient.test_id = new ObjectId(\"#{@params['test_id']}\");\n"
90
90
  end
91
91
  if @measure_def['sub_id']
92
92
  reduce += " patient.sub_id = \"#{@measure_def['sub_id']}\";\n"
93
93
  end
94
+ if @measure_def['nqf_id']
95
+ reduce += " patient.nqf_id = \"#{@measure_def['nqf_id']}\";\n"
96
+ end
94
97
 
95
98
  reduce += "patient.effective_date = #{@params['effective_date']};
96
99
  if (patient.provider_performances) {
@@ -16,7 +16,8 @@ module QME
16
16
  @measure_id = measure_id
17
17
  @sub_id = sub_id
18
18
  @parameter_values = parameter_values
19
- determine_connection_information
19
+ @measure_def = QualityMeasure.new(@measure_id, @sub_id).definition
20
+ determine_connection_information()
20
21
  end
21
22
 
22
23
  # Examines the patient_cache collection and generates a total of all groups
@@ -24,7 +25,7 @@ module QME
24
25
  # collection.
25
26
  # @return [Hash] measure groups (like numerator) as keys, counts as values
26
27
  def count_records_in_measure_groups
27
- patient_cache = get_db.collection('patient_cache')
28
+ pipeline = []
28
29
  base_query = {'value.measure_id' => @measure_id, 'value.sub_id' => @sub_id,
29
30
  'value.effective_date' => @parameter_values['effective_date'],
30
31
  'value.test_id' => @parameter_values['test_id']}
@@ -34,25 +35,37 @@ module QME
34
35
  query = base_query.clone
35
36
 
36
37
  query.merge!({'value.manual_exclusion' => {'$in' => [nil, false]}})
38
+
39
+ pipeline << {'$match' => query}
40
+ pipeline << {'$group' => {
41
+ "_id" => "$value.measure_id", # we don't really need this, but Mongo requires that we group
42
+ "population" => {"$sum" => "$value.population"},
43
+ "denominator" => {"$sum" => "$value.denominator"},
44
+ "numerator" => {"$sum" => "$value.numerator"},
45
+ "antinumerator" => {"$sum" => "$value.antinumerator"},
46
+ "exclusions" => {"$sum" => "$value.exclusions"},
47
+ "denexcep" => {"$sum" => "$value.denexcep"},
48
+ "considered" => {"$sum" => 1}
49
+ }}
37
50
 
38
- result = {:measure_id => @measure_id, :sub_id => @sub_id,
51
+ aggregate = get_db.command(:aggregate => 'patient_cache', :pipeline => pipeline)
52
+ if aggregate['ok'] != 1
53
+ raise RuntimeError, "Aggregation Failed"
54
+ elsif aggregate['result'].size !=1
55
+ raise RuntimeError, "Expected one group from patient_cache aggregation, got #{aggregate['result'].size}"
56
+ end
57
+
58
+ nqf_id = @measure_def['nqf_id'] || @measure_def['id']
59
+ result = {:measure_id => @measure_id, :sub_id => @sub_id, :nqf_id => nqf_id, :population_ids => @measure_def["population_ids"],
39
60
  :effective_date => @parameter_values['effective_date'],
40
61
  :test_id => @parameter_values['test_id'], :filters => @parameter_values['filters']}
41
-
42
- # need to time the old way agains the single query to verify that the single query is more performant
43
- aggregate = {"population"=>0, "denominator"=>0, "numerator"=>0, "antinumerator"=>0, "exclusions"=>0}
44
- %w(population denominator numerator antinumerator exclusions).each do |measure_group|
45
- patient_cache.find(query.merge("value.#{measure_group}" => true)) do |cursor|
46
- aggregate[measure_group] = cursor.count
47
- end
48
- end
49
- aggregate["considered"] = patient_cache.find(query).count
50
- aggregate["exclusions"] += patient_cache.find(base_query.merge({'value.manual_exclusion'=>true})).count
51
- result.merge!(aggregate)
52
62
 
63
+ result.merge!(aggregate['result'].first)
64
+ result.reject! {|k, v| k == '_id'} # get rid of the group id the Mongo forced us to use
65
+ result['exclusions'] += get_db['patient_cache'].find(base_query.merge({'value.manual_exclusion'=>true})).count
53
66
  result.merge!(execution_time: (Time.now.to_i - @parameter_values['start_time'].to_i)) if @parameter_values['start_time']
54
-
55
- get_db.collection("query_cache").save(result, safe: true)
67
+ get_db()["query_cache"].insert(result)
68
+ get_db().command({:getLastError => 1}) # make sure last insert finished before we continue
56
69
  result
57
70
  end
58
71
 
@@ -60,13 +73,13 @@ module QME
60
73
  # in the patient_cache collection. These documents will state the measure groups
61
74
  # that the record belongs to, such as numerator, etc.
62
75
  def map_records_into_measure_groups
63
- qm = QualityMeasure.new(@measure_id, @sub_id)
64
- measure = Builder.new(get_db, qm.definition, @parameter_values)
65
- records = get_db.collection('records')
66
- records.map_reduce(measure.map_function, "function(key, values){return values;}",
67
- :out => {:reduce => 'patient_cache'},
68
- :finalize => measure.finalize_function,
69
- :query => {:test_id => @parameter_values['test_id']})
76
+ measure = Builder.new(get_db(), @measure_def, @parameter_values)
77
+ get_db().command(:mapReduce => 'records',
78
+ :map => measure.map_function,
79
+ :reduce => "function(key, values){return values;}",
80
+ :out => {:reduce => 'patient_cache'},
81
+ :finalize => measure.finalize_function,
82
+ :query => {:test_id => @parameter_values['test_id']})
70
83
  apply_manual_exclusions
71
84
  end
72
85
 
@@ -74,13 +87,13 @@ module QME
74
87
  # This will create a document in the patient_cache collection. This document
75
88
  # will state the measure groups that the record belongs to, such as numerator, etc.
76
89
  def map_record_into_measure_groups(patient_id)
77
- qm = QualityMeasure.new(@measure_id, @sub_id)
78
- measure = Builder.new(get_db, qm.definition, @parameter_values)
79
- records = get_db.collection('records')
80
- records.map_reduce(measure.map_function, "function(key, values){return values;}",
81
- :out => {:reduce => 'patient_cache'},
82
- :finalize => measure.finalize_function,
83
- :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
90
+ measure = Builder.new(get_db(), @measure_def, @parameter_values)
91
+ get_db().command(:mapReduce => 'records',
92
+ :map => measure.map_function,
93
+ :reduce => "function(key, values){return values;}",
94
+ :out => {:reduce => 'patient_cache'},
95
+ :finalize => measure.finalize_function,
96
+ :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
84
97
  apply_manual_exclusions
85
98
  end
86
99
 
@@ -88,14 +101,14 @@ module QME
88
101
  # This will *not* create a document in the patient_cache collection, instead the
89
102
  # result is returned directly.
90
103
  def get_patient_result(patient_id)
91
- qm = QualityMeasure.new(@measure_id, @sub_id)
92
- measure = Builder.new(get_db, qm.definition, @parameter_values)
93
- records = get_db.collection('records')
94
- result = records.map_reduce(measure.map_function, "function(key, values){return values;}",
95
- :out => {:inline => true},
96
- :raw => true,
97
- :finalize => measure.finalize_function,
98
- :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
104
+ measure = Builder.new(get_db(), @measure_def, @parameter_values)
105
+ result = get_db().command(:mapReduce => 'records',
106
+ :map => measure.map_function,
107
+ :reduce => "function(key, values){return values;}",
108
+ :out => {:inline => true},
109
+ :raw => true,
110
+ :finalize => measure.finalize_function,
111
+ :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
99
112
  raise result['err'] if result['ok']!=1
100
113
  result['results'][0]['value']
101
114
  end
@@ -104,12 +117,11 @@ module QME
104
117
  # and sets a flag in each cached patient result for patients that have been excluded from the
105
118
  # current measure
106
119
  def apply_manual_exclusions
107
- exclusions = get_db.collection('manual_exclusions').find({'measure_id'=>@measure_id, 'sub_id'=>@sub_id}).to_a.map do |exclusion|
120
+ exclusions = get_db()['manual_exclusions'].find({'measure_id'=>@measure_id, 'sub_id'=>@sub_id}).to_a.map do |exclusion|
108
121
  exclusion['medical_record_id']
109
122
  end
110
- get_db.collection('patient_cache').update(
111
- {'value.measure_id'=>@measure_id, 'value.sub_id'=>@sub_id, 'value.medical_record_id'=>{'$in'=>exclusions} },
112
- {'$set'=>{'value.manual_exclusion'=>true}}, :multi=>true)
123
+ get_db()['patient_cache'].find({'value.measure_id'=>@measure_id, 'value.sub_id'=>@sub_id, 'value.medical_record_id'=>{'$in'=>exclusions} })
124
+ .update_all({'$set'=>{'value.manual_exclusion'=>true}})
113
125
  end
114
126
 
115
127
  def filter_parameters
@@ -117,7 +129,7 @@ module QME
117
129
  conditions = []
118
130
  if(filters = @parameter_values['filters'])
119
131
  if (filters['providers'] && filters['providers'].size > 0)
120
- providers = filters['providers'].map {|provider_id| BSON::ObjectId(provider_id) if (provider_id and provider_id != 'null') }
132
+ providers = filters['providers'].map {|provider_id| Moped::BSON::ObjectId(provider_id) if (provider_id and provider_id != 'null') }
121
133
  # provider_performances have already been filtered by start and end date in map_reduce_builder as part of the finalize
122
134
  conditions << {'value.provider_performances.provider_id' => {'$in' => providers}}
123
135
  end
@@ -1,11 +1,8 @@
1
1
  module QME
2
2
  module MapReduce
3
- # A Resque job that allows for measure calculation by a Resque worker. Can be created as follows:
3
+ # A delayed_job that allows for measure calculation by a delayed_job worker. Can be created as follows:
4
4
  #
5
- # MapReduce::MeasureCalculationJob.create(:measure_id => '0221', :sub_id => 'a', :effective_date => 1291352400, :test_id => xyzzy)
6
- #
7
- # This will return a uuid which can be used to check in on the status of a job. More details on this can be found
8
- # at the {Resque Stats project page}[https://github.com/quirkey/resque-status].
5
+ # Delayed::Job.enqueue QME::MapRedude::MeasureCalculationJob.new(:measure_id => '0221', :sub_id => 'a', :effective_date => 1291352400, :test_id => xyzzy)
9
6
  #
10
7
  # MeasureCalculationJob will check to see if a measure has been calculated before running the calculation. It does
11
8
  # this by creating a QME::QualityReport and asking if it has been calculated. If so, it will complete the job without
@@ -13,36 +10,40 @@ module QME
13
10
  #
14
11
  # When a measure needs calculation, the job will create a QME::MapReduce::Executor and interact with it to calculate
15
12
  # the report.
16
- class MeasureCalculationJob < Resque::JobWithStatus
17
- def perform
18
- MeasureCalculationJob.calculate(options)
13
+ class MeasureCalculationJob
14
+ attr_accessor :test_id, :measure_id, :sub_id, :effective_date, :filters
15
+
16
+ def initialize(options)
17
+ @measure_id = options['measure_id']
18
+ @sub_id = options['sub_id']
19
+ @options = options
19
20
  end
20
21
 
21
- def self.calculate(options)
22
- test_id = options['test_id'] ? BSON::ObjectId(options['test_id']) : nil
23
- qr = QualityReport.new(options['measure_id'], options['sub_id'], 'effective_date' => options['effective_date'], 'test_id' => test_id, 'filters' => options['filters'])
22
+ def perform
23
+ qr = QualityReport.new(@measure_id, @sub_id, @options)
24
24
  if qr.calculated?
25
- completed("#{options['measure_id']}#{options['sub_id']} has already been calculated") if respond_to? :completed
25
+ completed("#{@measure_id}#{@sub_id} has already been calculated")
26
26
  else
27
- map = QME::MapReduce::Executor.new(options['measure_id'], options['sub_id'], 'effective_date' => options['effective_date'], 'test_id' => test_id, 'filters' => options['filters'], 'start_time' => Time.now.to_i)
28
-
27
+ map = QME::MapReduce::Executor.new(@measure_id, @sub_id, @options.merge('start_time' => Time.now.to_i))
29
28
  if !qr.patients_cached?
30
- tick('Starting MapReduce') if respond_to? :tick
29
+ tick('Starting MapReduce')
31
30
  map.map_records_into_measure_groups
32
- tick('MapReduce complete') if respond_to? :tick
31
+ tick('MapReduce complete')
33
32
  end
34
33
 
35
- tick('Calculating group totals') if respond_to? :tick
34
+ tick('Calculating group totals')
36
35
  result = map.count_records_in_measure_groups
37
- completed("#{options['measure_id']}#{options['sub_id']}: p#{result['population']}, d#{result['denominator']}, n#{result['numerator']}, e#{result['exclusions']}") if respond_to? :completed
36
+ completed("#{@measure_id}#{@sub_id}: p#{result['population']}, d#{result['denominator']}, n#{result['numerator']}, excl#{result['exclusions']}, excep#{result['denexcep']}")
38
37
  end
38
+ end
39
+
40
+ def completed(message)
41
+
42
+ end
43
+
44
+ def tick(message)
39
45
 
40
46
  end
41
-
42
- # This can be uncommented and changed to put the jobs on a separate queue.
43
- # def self.queue
44
- # :statused
45
- # end
46
47
  end
47
48
  end
48
49
  end
@@ -8,7 +8,7 @@ module QME
8
8
  # @return [Hash] an hash of measure definitions
9
9
  def self.all
10
10
  result = {}
11
- measures = get_db.collection('measures')
11
+ measures = get_db()['measures']
12
12
  measures.find().each do |measure|
13
13
  id = measure['id']
14
14
  sub_id = measure['sub_id']
@@ -19,7 +19,7 @@ module QME
19
19
  end
20
20
 
21
21
  def self.get_measures(measure_ids)
22
- get_db.collection('measures').find('id' => {"$in" => measure_ids})
22
+ get_db()['measures'].find('id' => {"$in" => measure_ids})
23
23
  end
24
24
 
25
25
  # Creates a new QualityMeasure
@@ -34,11 +34,11 @@ module QME
34
34
  # Retrieve a measure definition from the database
35
35
  # @return [Hash] a JSON hash of the encoded measure
36
36
  def definition
37
- measures = get_db.collection('measures')
37
+ measures = get_db()['measures']
38
38
  if @sub_id
39
- measures.find_one({'id' => @measure_id, 'sub_id' => @sub_id})
39
+ measures.find({'id' => @measure_id, 'sub_id' => @sub_id}).first()
40
40
  else
41
- measures.find_one({'id' => @measure_id})
41
+ measures.find({'id' => @measure_id}).first()
42
42
  end
43
43
  end
44
44
  end
@@ -10,25 +10,25 @@ module QME
10
10
  # and query_cache collections
11
11
  def self.destroy_all
12
12
  determine_connection_information
13
- get_db.collection("query_cache").drop
14
- get_db.collection("patient_cache").drop
13
+ get_db()["query_cache"].drop
14
+ get_db()["patient_cache"].drop
15
15
  end
16
16
 
17
17
  # Removes the cached results for the patient with the supplied id and
18
18
  # recalculates as necessary
19
19
  def self.update_patient_results(id)
20
- determine_connection_information
20
+ determine_connection_information()
21
21
 
22
22
  # TODO: need to wait for any outstanding calculations to complete and then prevent
23
23
  # any new ones from starting until we are done.
24
24
 
25
25
  # drop any cached measure result calculations for the modified patient
26
- get_db.collection("patient_cache").remove('value.medical_record_id' => id)
26
+ get_db()["patient_cache"].find('value.medical_record_id' => id).remove_all()
27
27
 
28
28
  # get a list of cached measure results for a single patient
29
- sample_patient = get_db.collection('patient_cache').find_one()
29
+ sample_patient = get_db()['patient_cache'].find().first()
30
30
  if sample_patient
31
- cached_results = get_db.collection('patient_cache').find({'value.patient_id' => sample_patient['value']['patient_id']})
31
+ cached_results = get_db()['patient_cache'].find({'value.patient_id' => sample_patient['value']['patient_id']})
32
32
 
33
33
  # for each cached result (a combination of measure_id, sub_id, effective_date and test_id)
34
34
  cached_results.each do |measure|
@@ -42,7 +42,7 @@ module QME
42
42
 
43
43
  # remove the query totals so they will be recalculated using the new results for
44
44
  # the modified patient
45
- get_db.collection("query_cache").drop
45
+ get_db()["query_cache"].drop()
46
46
  end
47
47
 
48
48
  # Creates a new QualityReport
@@ -74,29 +74,47 @@ module QME
74
74
  # Kicks off a background job to calculate the measure
75
75
  # @return a unique id for the measure calculation job
76
76
  def calculate(asynchronous=true)
77
- options = {'measure_id' => @measure_id, 'sub_id' => @sub_id,
78
- 'effective_date' => @parameter_values['effective_date'],
79
- 'test_id' => @parameter_values['test_id'],
80
- 'filters' => QME::QualityReport.normalize_filters(@parameter_values['filters'])}
77
+
78
+ options = {'measure_id' => @measure_id, 'sub_id' => @sub_id}
79
+
80
+ options.merge! @parameter_values
81
+ options['filters'] = QME::QualityReport.normalize_filters(@parameter_values['filters'])
82
+
81
83
  if (asynchronous)
82
- MapReduce::MeasureCalculationJob.create(options)
84
+ job = Delayed::Job.enqueue(QME::MapReduce::MeasureCalculationJob.new(options))
85
+ job._id
83
86
  else
84
- MapReduce::MeasureCalculationJob.calculate(options)
87
+ mcj = QME::MapReduce::MeasureCalculationJob.new(options)
88
+ mcj.perform
85
89
  end
86
90
  end
87
91
 
88
92
  # Returns the status of a measure calculation job
89
93
  # @param job_id the id of the job to check on
90
- # @return [Hash] containing status information on the measure calculation job
94
+ # @return [Symbol] Will return the status: :complete, :queued, :running, :failed
91
95
  def status(job_id)
92
- Resque::Status.get(job_id)
96
+ job = Delayed::Job.where(_id: job_id).first
97
+ if job.nil?
98
+ # If we can't find the job, we assume that it is complete
99
+ :complete
100
+ else
101
+ if job.locked_at.nil?
102
+ :queued
103
+ else
104
+ if job.failed?
105
+ :failed
106
+ else
107
+ :running
108
+ end
109
+ end
110
+ end
93
111
  end
94
112
 
95
113
  # Gets the result of running a quality measure
96
114
  # @return [Hash] measure groups (like numerator) as keys, counts as values or nil if
97
115
  # the measure has not yet been calculated
98
116
  def result
99
- cache = get_db.collection("query_cache")
117
+ cache = get_db()["query_cache"]
100
118
  query = {:measure_id => @measure_id, :sub_id => @sub_id,
101
119
  :effective_date => @parameter_values['effective_date'],
102
120
  :test_id => @parameter_values['test_id']}
@@ -106,7 +124,7 @@ module QME
106
124
  query.merge!({filters: nil})
107
125
  end
108
126
 
109
- cache.find_one(query)
127
+ cache.find(query).first()
110
128
  end
111
129
 
112
130
  # make sure all filter id arrays are sorted
@@ -115,11 +133,11 @@ module QME
115
133
  end
116
134
 
117
135
  def patient_result
118
- cache = get_db.collection("patient_cache")
136
+ cache = get_db()["patient_cache"]
119
137
  query = {'value.measure_id' => @measure_id, 'value.sub_id' => @sub_id,
120
138
  'value.effective_date' => @parameter_values['effective_date'],
121
139
  'value.test_id' => @parameter_values['test_id']}
122
- cache.find_one(query)
140
+ cache.find(query).first()
123
141
  end
124
142
 
125
143
  end
@@ -0,0 +1,7 @@
1
+ module QME
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].each { |f| load f }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require 'quality-measure-engine'
2
+
3
+ db_name = ENV['DB_NAME'] || 'test'
4
+
5
+ namespace :bundle do
6
+ desc 'Import a quality bundle into the database.'
7
+ task :import, :bundle_path, :delete_existing, :needs => :environment do |task, args|
8
+ raise "The path to the measures zip file must be specified" unless args.bundle_path
9
+
10
+ bundle = File.open(args.bundle_path)
11
+ importer = QME::Bundle::Importer.new(db_name)
12
+ importer.import(bundle, args.delete_existing)
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module QME
2
+ VERSION = "2.0.0"
3
+ end
@@ -1,32 +1,20 @@
1
1
  require "bundler/setup"
2
2
 
3
- require 'resque/job_with_status'
3
+ require 'moped'
4
+ require 'delayed_job_mongoid'
5
+ require 'zip/zip'
4
6
 
5
- require_relative 'qme/database_access'
6
- require_relative 'qme/quality_measure'
7
+ require "qme/version"
8
+ require 'qme/database_access'
9
+ require 'qme/quality_measure'
7
10
 
8
- require_relative 'qme/map/map_reduce_builder'
9
- require_relative 'qme/map/map_reduce_executor'
10
- require_relative 'qme/map/measure_calculation_job'
11
+ require 'qme/map/map_reduce_builder'
12
+ require 'qme/map/map_reduce_executor'
13
+ require 'qme/map/measure_calculation_job'
11
14
 
12
- require_relative 'qme/quality_report'
15
+ require 'qme/quality_report'
13
16
 
14
- require_relative 'qme/randomizer/random_patient_creator'
15
- require_relative 'qme/randomizer/patient_randomizer'
16
- require_relative 'qme/randomizer/patient_randomization_job'
17
+ require 'qme/bundle/bundle'
18
+ require 'qme/bundle/importer'
17
19
 
18
- require 'singleton'
19
- require 'health-data-standards'
20
-
21
- require_relative 'qme/ext/record'
22
-
23
- require_relative 'qme/importer/property_matcher'
24
- require_relative 'qme/importer/generic_importer'
25
- require_relative 'qme/importer/measure_properties_generator'
26
-
27
- require 'json'
28
- require 'mongo'
29
- require 'nokogiri'
30
-
31
- require_relative 'qme/measure/measure_loader'
32
- require_relative 'qme/measure/database_loader'
20
+ require 'qme/railtie' if defined?(Rails)