openmrs_data_sanitizer 1.0.1
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +35 -0
- data/Rakefile +4 -0
- data/app/services/openmrs_data_sanitizer/data_aggregator.rb +985 -0
- data/app/services/openmrs_data_sanitizer/data_sanitizer.rb +414 -0
- data/lib/openmrs_data_sanitizer/engine.rb +13 -0
- data/lib/openmrs_data_sanitizer/version.rb +5 -0
- data/lib/openmrs_data_sanitizer.rb +12 -0
- metadata +150 -0
@@ -0,0 +1,985 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenmrsDataSanitizer
|
4
|
+
# rubocop:disable Metrics/ClassLength
|
5
|
+
# This class is responsible for aggregating data FROM #{schema}.the OpenMRS database
|
6
|
+
class DataAggregator
|
7
|
+
attr_accessor :schema
|
8
|
+
|
9
|
+
def initialize(schema:)
|
10
|
+
@schema = schema
|
11
|
+
end
|
12
|
+
|
13
|
+
def aggregate
|
14
|
+
prepare_tables
|
15
|
+
prepare_table_based_on_columns
|
16
|
+
truncate_tables
|
17
|
+
process_data
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
23
|
+
def prepare_tables
|
24
|
+
create_data_sanitizer_patients_height_table unless check_if_table_exists('data_sanitizer_patients_height')
|
25
|
+
create_data_sanitizer_patients_weight_table unless check_if_table_exists('data_sanitizer_patients_weight')
|
26
|
+
create_data_sanitizer_patient_present_table unless check_if_table_exists('data_sanitizer_patient_present')
|
27
|
+
create_data_sanitizer_guardian_present_table unless check_if_table_exists('data_sanitizer_guardian_present')
|
28
|
+
create_data_sanitizer_pregnant_status_table unless check_if_table_exists('data_sanitizer_pregnant_status')
|
29
|
+
unless check_if_table_exists('data_sanitizer_breastfeeding_status')
|
30
|
+
create_data_sanitizer_breastfeeding_status_table
|
31
|
+
end
|
32
|
+
create_data_sanitizer_side_effect_table unless check_if_table_exists('data_sanitizer_side_effect')
|
33
|
+
create_data_sanitizer_adherence_table unless check_if_table_exists('data_sanitizer_adherence')
|
34
|
+
create_data_sanitizer_appointment_table unless check_if_table_exists('data_sanitizer_appointment')
|
35
|
+
create_data_sanitizer_arv_medication_table unless check_if_table_exists('data_sanitizer_arv_medication')
|
36
|
+
create_data_sanitizer_arv_orders_table unless check_if_table_exists('data_sanitizer_arv_orders')
|
37
|
+
create_data_sanitizer_encounter_dates_table unless check_if_table_exists('data_sanitizer_encounter_dates')
|
38
|
+
create_data_sanitizer_patient_outcomes_table unless check_if_table_exists('data_sanitizer_patient_outcomes')
|
39
|
+
create_data_sanitizer_patient_who_stage_table unless check_if_table_exists('data_sanitizer_patient_who_stage')
|
40
|
+
unless check_if_table_exists('data_sanitizer_patient_reason_for_starting')
|
41
|
+
create_data_sanitizer_patient_reason_for_starting_table
|
42
|
+
end
|
43
|
+
unless check_if_table_exists('data_sanitizer_patient_detailed_side_effects')
|
44
|
+
create_data_sanitizer_patient_detailed_side_effects_table
|
45
|
+
end
|
46
|
+
create_data_sanitizer_visits_table unless check_if_table_exists('data_sanitizer_visits')
|
47
|
+
end
|
48
|
+
|
49
|
+
def prepare_table_based_on_columns
|
50
|
+
if count_table_columns('data_sanitizer_patients_height') != 3
|
51
|
+
drop_data_sanitizer_patients_height_table
|
52
|
+
create_data_sanitizer_patients_height_table
|
53
|
+
end
|
54
|
+
if count_table_columns('data_sanitizer_patients_weight') != 3
|
55
|
+
drop_data_sanitizer_patients_weight_table
|
56
|
+
create_data_sanitizer_patients_weight_table
|
57
|
+
end
|
58
|
+
if count_table_columns('data_sanitizer_patient_present') != 3
|
59
|
+
drop_data_sanitizer_patient_present_table
|
60
|
+
create_data_sanitizer_patient_present_table
|
61
|
+
end
|
62
|
+
if count_table_columns('data_sanitizer_guardian_present') != 3
|
63
|
+
drop_data_sanitizer_guardian_present_table
|
64
|
+
create_data_sanitizer_guardian_present_table
|
65
|
+
end
|
66
|
+
if count_table_columns('data_sanitizer_pregnant_status') != 3
|
67
|
+
drop_data_sanitizer_pregnant_status_table
|
68
|
+
create_data_sanitizer_pregnant_status_table
|
69
|
+
end
|
70
|
+
if count_table_columns('data_sanitizer_breastfeeding_status') != 3
|
71
|
+
drop_data_sanitizer_breastfeeding_status_table
|
72
|
+
create_data_sanitizer_breastfeeding_status_table
|
73
|
+
end
|
74
|
+
if count_table_columns('data_sanitizer_side_effect') != 5
|
75
|
+
drop_data_sanitizer_side_effect_table
|
76
|
+
create_data_sanitizer_side_effect_table
|
77
|
+
end
|
78
|
+
if count_table_columns('data_sanitizer_adherence') != 3
|
79
|
+
drop_data_sanitizer_adherence_table
|
80
|
+
create_data_sanitizer_adherence_table
|
81
|
+
end
|
82
|
+
if count_table_columns('data_sanitizer_appointment') != 3
|
83
|
+
drop_data_sanitizer_appointment_table
|
84
|
+
create_data_sanitizer_appointment_table
|
85
|
+
end
|
86
|
+
if count_table_columns('data_sanitizer_arv_medication') != 7
|
87
|
+
drop_data_sanitizer_arv_medication_table
|
88
|
+
create_data_sanitizer_arv_medication_table
|
89
|
+
end
|
90
|
+
if count_table_columns('data_sanitizer_arv_orders') != 12
|
91
|
+
drop_data_sanitizer_arv_orders_table
|
92
|
+
create_data_sanitizer_arv_orders_table
|
93
|
+
end
|
94
|
+
if count_table_columns('data_sanitizer_encounter_dates') != 2
|
95
|
+
drop_data_sanitizer_encounter_dates_table
|
96
|
+
create_data_sanitizer_encounter_dates_table
|
97
|
+
end
|
98
|
+
if count_table_columns('data_sanitizer_patient_outcomes') != 5
|
99
|
+
drop_data_sanitizer_patient_outcomes_table
|
100
|
+
create_data_sanitizer_patient_outcomes_table
|
101
|
+
end
|
102
|
+
if count_table_columns('data_sanitizer_patient_who_stage') != 3
|
103
|
+
drop_data_sanitizer_patient_who_stage_table
|
104
|
+
create_data_sanitizer_patient_who_stage_table
|
105
|
+
end
|
106
|
+
|
107
|
+
if count_table_columns('data_sanitizer_patient_reason_for_starting') != 3
|
108
|
+
drop_data_sanitizer_patient_reason_for_starting_table
|
109
|
+
create_data_sanitizer_patient_reason_for_starting_table
|
110
|
+
end
|
111
|
+
if count_table_columns('data_sanitizer_patient_detailed_side_effects') != 21
|
112
|
+
drop_data_sanitizer_patient_detailed_side_effects_table
|
113
|
+
create_data_sanitizer_patient_detailed_side_effects_table
|
114
|
+
end
|
115
|
+
return unless count_table_columns('data_sanitizer_visits') != 35
|
116
|
+
|
117
|
+
drop_data_sanitizer_visits_table
|
118
|
+
create_data_sanitizer_visits_table
|
119
|
+
end
|
120
|
+
|
121
|
+
def process_data
|
122
|
+
insert_data_sanitizer_patients_height
|
123
|
+
insert_data_sanitizer_patients_weight
|
124
|
+
insert_data_sanitizer_patient_present
|
125
|
+
insert_data_sanitizer_guardian_present
|
126
|
+
insert_data_sanitizer_pregnant_status
|
127
|
+
insert_data_sanitizer_breastfeeding_status
|
128
|
+
insert_data_sanitizer_side_effect
|
129
|
+
insert_data_sanitizer_adherence
|
130
|
+
insert_data_sanitizer_appointment
|
131
|
+
insert_data_sanitizer_arv_medication
|
132
|
+
insert_data_sanitizer_arv_orders
|
133
|
+
insert_data_sanitizer_encounter_dates
|
134
|
+
insert_data_sanitizer_patient_outcomes
|
135
|
+
insert_data_sanitizer_patient_who_stage
|
136
|
+
insert_data_sanitizer_patient_reason_for_starting
|
137
|
+
insert_data_sanitizer_patient_detailed_side_effects
|
138
|
+
insert_data_sanitizer_visits
|
139
|
+
end
|
140
|
+
|
141
|
+
def truncate_tables
|
142
|
+
table_names = %w[ data_sanitizer_patients_height data_sanitizer_patients_weight data_sanitizer_patient_present
|
143
|
+
data_sanitizer_guardian_present data_sanitizer_pregnant_status data_sanitizer_breastfeeding_status
|
144
|
+
data_sanitizer_side_effect data_sanitizer_adherence data_sanitizer_appointment
|
145
|
+
data_sanitizer_arv_medication data_sanitizer_arv_orders data_sanitizer_encounter_dates
|
146
|
+
data_sanitizer_patient_outcomes data_sanitizer_patient_who_stage data_sanitizer_patient_reason_for_starting
|
147
|
+
data_sanitizer_patient_detailed_side_effects data_sanitizer_visits ]
|
148
|
+
table_names.each do |table_name|
|
149
|
+
ActiveRecord::Base.connection.execute("TRUNCATE TABLE #{schema}.#{table_name}")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
153
|
+
|
154
|
+
# ========================
|
155
|
+
# DATABASE CREATION METHODS
|
156
|
+
# ========================
|
157
|
+
|
158
|
+
def create_data_sanitizer_patients_height_table
|
159
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
160
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patients_height (
|
161
|
+
patient_id INT,
|
162
|
+
height DECIMAL(10, 0),
|
163
|
+
visit_date DATE
|
164
|
+
);
|
165
|
+
SQL
|
166
|
+
# indexes
|
167
|
+
create_data_sanitizer_patients_height_index
|
168
|
+
end
|
169
|
+
|
170
|
+
def create_data_sanitizer_patients_weight_table
|
171
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
172
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patients_weight (
|
173
|
+
patient_id INT,
|
174
|
+
weight DECIMAL(10, 1),
|
175
|
+
visit_date DATE
|
176
|
+
);
|
177
|
+
SQL
|
178
|
+
create_data_sanitizer_patients_weight_index
|
179
|
+
end
|
180
|
+
|
181
|
+
def create_data_sanitizer_patient_present_table
|
182
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
183
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patient_present (
|
184
|
+
patient_id INT,
|
185
|
+
patient_present VARCHAR(3),
|
186
|
+
visit_date DATE
|
187
|
+
);
|
188
|
+
SQL
|
189
|
+
create_data_sanitizer_patient_present_index
|
190
|
+
end
|
191
|
+
|
192
|
+
def create_data_sanitizer_guardian_present_table
|
193
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
194
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_guardian_present (
|
195
|
+
patient_id INT,
|
196
|
+
guardian_present VARCHAR(3),
|
197
|
+
visit_date DATE
|
198
|
+
);
|
199
|
+
SQL
|
200
|
+
create_data_sanitizer_guardian_present_index
|
201
|
+
end
|
202
|
+
|
203
|
+
def create_data_sanitizer_pregnant_status_table
|
204
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
205
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_pregnant_status (
|
206
|
+
patient_id INT,
|
207
|
+
pregnant_status VARCHAR(3),
|
208
|
+
visit_date DATE
|
209
|
+
);
|
210
|
+
SQL
|
211
|
+
create_data_sanitizer_pregnant_status_index
|
212
|
+
end
|
213
|
+
|
214
|
+
def create_data_sanitizer_breastfeeding_status_table
|
215
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
216
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_breastfeeding_status (
|
217
|
+
patient_id INT,
|
218
|
+
breastfeeding_status VARCHAR(3),
|
219
|
+
visit_date DATE
|
220
|
+
);
|
221
|
+
SQL
|
222
|
+
create_data_sanitizer_breastfeeding_status_index
|
223
|
+
end
|
224
|
+
|
225
|
+
def create_data_sanitizer_side_effect_table
|
226
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
227
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_side_effect (
|
228
|
+
patient_id INT,
|
229
|
+
visit_date DATE,
|
230
|
+
concept_id INT,
|
231
|
+
value_coded INT,
|
232
|
+
available VARCHAR(3)
|
233
|
+
);
|
234
|
+
SQL
|
235
|
+
create_data_sanitizer_side_effect_index
|
236
|
+
end
|
237
|
+
|
238
|
+
def create_data_sanitizer_adherence_table
|
239
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
240
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_adherence (
|
241
|
+
patient_id INT,
|
242
|
+
visit_date DATE,
|
243
|
+
adherence DECIMAL(10, 0)
|
244
|
+
);
|
245
|
+
SQL
|
246
|
+
create_data_sanitizer_adherence_index
|
247
|
+
end
|
248
|
+
|
249
|
+
def create_data_sanitizer_appointment_table
|
250
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
251
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_appointment (
|
252
|
+
patient_id INT,
|
253
|
+
value_datetime DATETIME,
|
254
|
+
visit_date DATE
|
255
|
+
);
|
256
|
+
SQL
|
257
|
+
create_data_sanitizer_appointment_index
|
258
|
+
end
|
259
|
+
|
260
|
+
# rubocop:disable Metrics/MethodLength
|
261
|
+
def create_data_sanitizer_arv_medication_table
|
262
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
263
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_arv_medication (
|
264
|
+
patient_id INT,
|
265
|
+
order_id INT,
|
266
|
+
visit_date DATE,
|
267
|
+
drug_runout_date DATE,
|
268
|
+
num_unique_arvs INT,
|
269
|
+
unique_arvs_given VARCHAR(255),
|
270
|
+
drug_names VARCHAR(255)
|
271
|
+
);
|
272
|
+
SQL
|
273
|
+
create_data_sanitizer_arv_medication_index
|
274
|
+
end
|
275
|
+
|
276
|
+
def create_data_sanitizer_arv_orders_table
|
277
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
278
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_arv_orders (
|
279
|
+
patient_id INT,
|
280
|
+
order_id INT,
|
281
|
+
encounter_id INT,
|
282
|
+
visit_date DATE,
|
283
|
+
drug_id INT,
|
284
|
+
drug_name VARCHAR(100),
|
285
|
+
units VARCHAR(50),
|
286
|
+
equivalent_daily_dose DOUBLE(10,1),
|
287
|
+
instructions VARCHAR(300),
|
288
|
+
start_date DATE,
|
289
|
+
runout_date DATE,
|
290
|
+
quantity INT
|
291
|
+
);
|
292
|
+
SQL
|
293
|
+
create_data_sanitizer_arv_orders_index
|
294
|
+
end
|
295
|
+
|
296
|
+
def create_data_sanitizer_encounter_dates_table
|
297
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
298
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_encounter_dates (
|
299
|
+
patient_id INT,
|
300
|
+
visit_date DATE
|
301
|
+
);
|
302
|
+
SQL
|
303
|
+
create_data_sanitizer_encounter_dates_index
|
304
|
+
end
|
305
|
+
|
306
|
+
def create_data_sanitizer_patient_outcomes_table
|
307
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
308
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patient_outcomes (
|
309
|
+
patient_id INT,
|
310
|
+
visit_date DATE,
|
311
|
+
end_date DATE,
|
312
|
+
state INT,
|
313
|
+
concept_id INT,
|
314
|
+
outcome VARCHAR(100)
|
315
|
+
);
|
316
|
+
SQL
|
317
|
+
create_data_sanitizer_patient_outcomes_index
|
318
|
+
end
|
319
|
+
|
320
|
+
def create_data_sanitizer_patient_who_stage_table
|
321
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
322
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patient_who_stage (
|
323
|
+
patient_id INT,
|
324
|
+
visit_date DATE,
|
325
|
+
who_stage VARCHAR(100)
|
326
|
+
);
|
327
|
+
SQL
|
328
|
+
create_data_sanitizer_patient_who_stage_index
|
329
|
+
end
|
330
|
+
|
331
|
+
def create_data_sanitizer_patient_reason_for_starting_table
|
332
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
333
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patient_reason_for_starting (
|
334
|
+
patient_id INT,
|
335
|
+
visit_date DATE,
|
336
|
+
reason_for_starting_art VARCHAR(100)
|
337
|
+
);
|
338
|
+
SQL
|
339
|
+
create_data_sanitizer_patient_reason_for_starting_index
|
340
|
+
end
|
341
|
+
|
342
|
+
def create_data_sanitizer_patient_detailed_side_effects_table
|
343
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
344
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_patient_detailed_side_effects (
|
345
|
+
patient_id INT,
|
346
|
+
visit_date DATE,
|
347
|
+
peripheral_neuropathy VARCHAR(3),
|
348
|
+
anemia VARCHAR(3),
|
349
|
+
hepatitis VARCHAR(3),
|
350
|
+
jaundice VARCHAR(3),
|
351
|
+
psychosis VARCHAR(3),
|
352
|
+
skin_rash VARCHAR(3),
|
353
|
+
dizziness VARCHAR(3),
|
354
|
+
lipodystrophy VARCHAR(3),
|
355
|
+
renal_failure VARCHAR(3),
|
356
|
+
other VARCHAR(3),
|
357
|
+
kidney_failure VARCHAR(3),
|
358
|
+
gynaecomastia VARCHAR(3),
|
359
|
+
cough VARCHAR(3),
|
360
|
+
headache VARCHAR(3),
|
361
|
+
lactic_acidosis VARCHAR(3),
|
362
|
+
alcohol_problem VARCHAR(3),
|
363
|
+
fever VARCHAR(3),
|
364
|
+
nausea VARCHAR(3),
|
365
|
+
vomiting VARCHAR(3),
|
366
|
+
night_sweats VARCHAR(3),
|
367
|
+
other_specify VARCHAR(3),
|
368
|
+
malnutrition VARCHAR(3)
|
369
|
+
);
|
370
|
+
SQL
|
371
|
+
create_data_sanitizer_patient_detailed_side_effects_index
|
372
|
+
end
|
373
|
+
|
374
|
+
def create_data_sanitizer_visits_table
|
375
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
376
|
+
CREATE TABLE IF NOT EXISTS #{schema}.data_sanitizer_visits (
|
377
|
+
patient_id INT,
|
378
|
+
visit_date DATE,
|
379
|
+
who_stage VARCHAR(100),
|
380
|
+
reason_for_starting_antiretroviral_treatment_construct VARCHAR(100),
|
381
|
+
patient_present VARCHAR(3),
|
382
|
+
guardian_present VARCHAR(3),
|
383
|
+
height DECIMAL(10, 0),
|
384
|
+
weight DECIMAL(10, 1),
|
385
|
+
peripheral_neuropathy VARCHAR(3),
|
386
|
+
anemia VARCHAR(3),
|
387
|
+
hepatitis VARCHAR(3),
|
388
|
+
jaundice VARCHAR(3),
|
389
|
+
psychosis VARCHAR(3),
|
390
|
+
skin_rash VARCHAR(3),
|
391
|
+
dizziness VARCHAR(3),
|
392
|
+
lipodystrophy VARCHAR(3),
|
393
|
+
renal_failure VARCHAR(3),
|
394
|
+
other VARCHAR(3),
|
395
|
+
kidney_failure VARCHAR(3),
|
396
|
+
gynaecomastia VARCHAR(3),
|
397
|
+
cough VARCHAR(3),
|
398
|
+
headache VARCHAR(3),
|
399
|
+
lactic_acidosis VARCHAR(3),
|
400
|
+
alcohol_problem VARCHAR(3),
|
401
|
+
fever VARCHAR(3),
|
402
|
+
nausea VARCHAR(3),
|
403
|
+
vomiting VARCHAR(3),
|
404
|
+
night_sweats VARCHAR(3),
|
405
|
+
other_specify VARCHAR(3),
|
406
|
+
malnutrition VARCHAR(3),
|
407
|
+
adherence DECIMAL(10, 0),
|
408
|
+
drugs_dispensed VARCHAR(200),
|
409
|
+
drug_end_date DATE,
|
410
|
+
outcome_concept_id INT,
|
411
|
+
outcome_end_date DATE,
|
412
|
+
outcome VARCHAR(100),
|
413
|
+
appointment_date DATE
|
414
|
+
);
|
415
|
+
SQL
|
416
|
+
create_data_sanitizer_visits_index
|
417
|
+
end
|
418
|
+
# rubocop:enable Metrics/MethodLength
|
419
|
+
|
420
|
+
# ========================
|
421
|
+
# DATABASE INDEX CREATION METHODS
|
422
|
+
# ========================
|
423
|
+
|
424
|
+
def create_data_sanitizer_patients_height_index
|
425
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
426
|
+
CREATE INDEX aws_patient_height ON #{schema}.data_sanitizer_patients_height (patient_id, visit_date);
|
427
|
+
SQL
|
428
|
+
end
|
429
|
+
|
430
|
+
def create_data_sanitizer_patients_weight_index
|
431
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
432
|
+
CREATE INDEX aws_patient_weight ON #{schema}.data_sanitizer_patients_weight (patient_id, visit_date);
|
433
|
+
SQL
|
434
|
+
end
|
435
|
+
|
436
|
+
def create_data_sanitizer_patient_present_index
|
437
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
438
|
+
CREATE INDEX aws_patient_present ON #{schema}.data_sanitizer_patient_present (patient_id, visit_date);
|
439
|
+
SQL
|
440
|
+
end
|
441
|
+
|
442
|
+
def create_data_sanitizer_guardian_present_index
|
443
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
444
|
+
CREATE INDEX aws_guardian_present ON #{schema}.data_sanitizer_guardian_present (patient_id, visit_date);
|
445
|
+
SQL
|
446
|
+
end
|
447
|
+
|
448
|
+
def create_data_sanitizer_pregnant_status_index
|
449
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
450
|
+
CREATE INDEX aws_pregnant_status ON #{schema}.data_sanitizer_pregnant_status (patient_id, visit_date);
|
451
|
+
SQL
|
452
|
+
end
|
453
|
+
|
454
|
+
def create_data_sanitizer_breastfeeding_status_index
|
455
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
456
|
+
CREATE INDEX aws_breastfeeding_status ON #{schema}.data_sanitizer_breastfeeding_status (patient_id, visit_date);
|
457
|
+
SQL
|
458
|
+
end
|
459
|
+
|
460
|
+
def create_data_sanitizer_side_effect_index
|
461
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
462
|
+
CREATE INDEX aws_side_effect ON #{schema}.data_sanitizer_side_effect (patient_id, visit_date);
|
463
|
+
SQL
|
464
|
+
end
|
465
|
+
|
466
|
+
def create_data_sanitizer_adherence_index
|
467
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
468
|
+
CREATE INDEX aws_adherence ON #{schema}.data_sanitizer_adherence (patient_id, visit_date);
|
469
|
+
SQL
|
470
|
+
end
|
471
|
+
|
472
|
+
def create_data_sanitizer_appointment_index
|
473
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
474
|
+
CREATE INDEX aws_appointment ON #{schema}.data_sanitizer_appointment (patient_id, visit_date);
|
475
|
+
SQL
|
476
|
+
end
|
477
|
+
|
478
|
+
def create_data_sanitizer_arv_medication_index
|
479
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
480
|
+
CREATE INDEX aws_arv_medication ON #{schema}.data_sanitizer_arv_medication (patient_id, visit_date);
|
481
|
+
SQL
|
482
|
+
end
|
483
|
+
|
484
|
+
def create_data_sanitizer_arv_orders_index
|
485
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
486
|
+
CREATE INDEX aws_arv_orders ON #{schema}.data_sanitizer_arv_orders (patient_id, visit_date);
|
487
|
+
SQL
|
488
|
+
end
|
489
|
+
|
490
|
+
def create_data_sanitizer_encounter_dates_index
|
491
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
492
|
+
CREATE INDEX aws_encounter_dates ON #{schema}.data_sanitizer_encounter_dates (patient_id, visit_date);
|
493
|
+
SQL
|
494
|
+
end
|
495
|
+
|
496
|
+
def create_data_sanitizer_patient_outcomes_index
|
497
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
498
|
+
CREATE INDEX aws_patient_outcomes ON #{schema}.data_sanitizer_patient_outcomes (patient_id, visit_date);
|
499
|
+
SQL
|
500
|
+
end
|
501
|
+
|
502
|
+
def create_data_sanitizer_patient_who_stage_index
|
503
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
504
|
+
CREATE INDEX aws_patient_who ON #{schema}.data_sanitizer_patient_who_stage (patient_id, visit_date);
|
505
|
+
SQL
|
506
|
+
end
|
507
|
+
|
508
|
+
def create_data_sanitizer_patient_reason_for_starting_index
|
509
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
510
|
+
CREATE INDEX aws_patient_reason_for_starting ON #{schema}.data_sanitizer_patient_reason_for_starting (patient_id, visit_date);
|
511
|
+
SQL
|
512
|
+
end
|
513
|
+
|
514
|
+
def create_data_sanitizer_patient_detailed_side_effects_index
|
515
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
516
|
+
CREATE INDEX aws_patient_detailed_side_effects ON #{schema}.data_sanitizer_patient_detailed_side_effects (patient_id, visit_date);
|
517
|
+
SQL
|
518
|
+
end
|
519
|
+
|
520
|
+
def create_data_sanitizer_visits_index
|
521
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
522
|
+
CREATE INDEX aws_visits ON #{schema}.data_sanitizer_visits (patient_id, visit_date);
|
523
|
+
SQL
|
524
|
+
end
|
525
|
+
|
526
|
+
# ========================
|
527
|
+
# DATABASE TABLE DELETE METHODS
|
528
|
+
# ========================
|
529
|
+
|
530
|
+
def drop_data_sanitizer_patients_height_table
|
531
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
532
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patients_height;
|
533
|
+
SQL
|
534
|
+
end
|
535
|
+
|
536
|
+
def drop_data_sanitizer_patients_weight_table
|
537
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
538
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patients_weight;
|
539
|
+
SQL
|
540
|
+
end
|
541
|
+
|
542
|
+
def drop_data_sanitizer_patient_present_table
|
543
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
544
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patient_present;
|
545
|
+
SQL
|
546
|
+
end
|
547
|
+
|
548
|
+
def drop_data_sanitizer_guardian_present_table
|
549
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
550
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_guardian_present;
|
551
|
+
SQL
|
552
|
+
end
|
553
|
+
|
554
|
+
def drop_data_sanitizer_pregnant_status_table
|
555
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
556
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_pregnant_status;
|
557
|
+
SQL
|
558
|
+
end
|
559
|
+
|
560
|
+
def drop_data_sanitizer_breastfeeding_status_table
|
561
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
562
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_breastfeeding_status;
|
563
|
+
SQL
|
564
|
+
end
|
565
|
+
|
566
|
+
def drop_data_sanitizer_side_effect_table
|
567
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
568
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_side_effect;
|
569
|
+
SQL
|
570
|
+
end
|
571
|
+
|
572
|
+
def drop_data_sanitizer_adherence_table
|
573
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
574
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_adherence;
|
575
|
+
SQL
|
576
|
+
end
|
577
|
+
|
578
|
+
def drop_data_sanitizer_appointment_table
|
579
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
580
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_appointment;
|
581
|
+
SQL
|
582
|
+
end
|
583
|
+
|
584
|
+
def drop_data_sanitizer_arv_medication_table
|
585
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
586
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_arv_medication;
|
587
|
+
SQL
|
588
|
+
end
|
589
|
+
|
590
|
+
def drop_data_sanitizer_arv_orders_table
|
591
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
592
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_arv_orders;
|
593
|
+
SQL
|
594
|
+
end
|
595
|
+
|
596
|
+
def drop_data_sanitizer_encounter_dates_table
|
597
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
598
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_encounter_dates;
|
599
|
+
SQL
|
600
|
+
end
|
601
|
+
|
602
|
+
def drop_data_sanitizer_patient_outcomes_table
|
603
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
604
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patient_outcomes;
|
605
|
+
SQL
|
606
|
+
end
|
607
|
+
|
608
|
+
def drop_data_sanitizer_patient_who_stage_table
|
609
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
610
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patient_who_stage;
|
611
|
+
SQL
|
612
|
+
end
|
613
|
+
|
614
|
+
def drop_data_sanitizer_patient_reason_for_starting_table
|
615
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
616
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patient_reason_for_starting;
|
617
|
+
SQL
|
618
|
+
end
|
619
|
+
|
620
|
+
def drop_data_sanitizer_patient_detailed_side_effects_table
|
621
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
622
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_patient_detailed_side_effects;
|
623
|
+
SQL
|
624
|
+
end
|
625
|
+
|
626
|
+
def drop_data_sanitizer_visits_table
|
627
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
628
|
+
DROP TABLE IF EXISTS #{schema}.data_sanitizer_visits;
|
629
|
+
SQL
|
630
|
+
end
|
631
|
+
|
632
|
+
# ========================
|
633
|
+
# DATABASE INSERTION METHODS
|
634
|
+
# ========================
|
635
|
+
|
636
|
+
# rubocop:disable Metrics/MethodLength
|
637
|
+
def insert_data_sanitizer_patients_height
|
638
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
639
|
+
INSERT INTO #{schema}.data_sanitizer_patients_height (patient_id, height, visit_date)
|
640
|
+
SELECT e.patient_id, ROUND(obs.value_numeric), DATE(obs.obs_datetime) visit_date
|
641
|
+
FROM #{schema}.encounter e
|
642
|
+
INNER JOIN #{schema}.obs ON e.patient_id = obs.person_id
|
643
|
+
AND e.voided = 0
|
644
|
+
AND e.encounter_type = 6
|
645
|
+
AND e.program_id = 1
|
646
|
+
AND obs.voided = 0
|
647
|
+
AND obs.concept_id = 5090 -- Height concept_id
|
648
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
649
|
+
ORDER BY obs_datetime DESC;
|
650
|
+
SQL
|
651
|
+
end
|
652
|
+
|
653
|
+
def insert_data_sanitizer_patients_weight
|
654
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
655
|
+
INSERT INTO #{schema}.data_sanitizer_patients_weight (patient_id, weight, visit_date)
|
656
|
+
SELECT e.patient_id, ROUND(obs.value_numeric), DATE(obs.obs_datetime) visit_date
|
657
|
+
FROM #{schema}.encounter e
|
658
|
+
INNER JOIN #{schema}.obs ON e.patient_id = obs.person_id
|
659
|
+
AND e.voided = 0
|
660
|
+
AND e.program_id = 1
|
661
|
+
AND e.encounter_type = 6
|
662
|
+
AND obs.voided = 0
|
663
|
+
AND obs.concept_id = 5089
|
664
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
665
|
+
ORDER BY obs_datetime DESC;
|
666
|
+
SQL
|
667
|
+
end
|
668
|
+
|
669
|
+
def insert_data_sanitizer_patient_present
|
670
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
671
|
+
INSERT INTO #{schema}.data_sanitizer_patient_present (patient_id, patient_present, visit_date)
|
672
|
+
SELECT e.patient_id,
|
673
|
+
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS patient_present,
|
674
|
+
DATE(obs.obs_datetime) visit_date
|
675
|
+
FROM #{schema}.encounter e
|
676
|
+
INNER JOIN #{schema}.obs ON e.patient_id = obs.person_id
|
677
|
+
AND e.voided = 0
|
678
|
+
AND e.encounter_type = 51
|
679
|
+
AND e.program_id = 1
|
680
|
+
AND obs.voided = 0
|
681
|
+
AND obs.concept_id = 1805
|
682
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
683
|
+
ORDER BY obs_datetime DESC;
|
684
|
+
SQL
|
685
|
+
end
|
686
|
+
|
687
|
+
def insert_data_sanitizer_guardian_present
|
688
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
689
|
+
INSERT INTO #{schema}.data_sanitizer_guardian_present (patient_id, guardian_present, visit_date)
|
690
|
+
SELECT e.patient_id,
|
691
|
+
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS guardian_present,
|
692
|
+
DATE(obs.obs_datetime) visit_date
|
693
|
+
FROM #{schema}.encounter e
|
694
|
+
INNER JOIN #{schema}.obs ON e.patient_id = obs.person_id
|
695
|
+
AND e.voided = 0
|
696
|
+
AND e.encounter_type = 51
|
697
|
+
AND e.program_id = 1
|
698
|
+
AND obs.voided = 0
|
699
|
+
AND obs.concept_id = 6794
|
700
|
+
INNER JOIN #{schema}.person ON person.person_id = obs.person_id
|
701
|
+
AND person.gender IN('Female','F')
|
702
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
703
|
+
ORDER BY obs_datetime DESC;
|
704
|
+
SQL
|
705
|
+
end
|
706
|
+
|
707
|
+
def insert_data_sanitizer_pregnant_status
|
708
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
709
|
+
INSERT INTO #{schema}.data_sanitizer_pregnant_status (patient_id, pregnant_status, visit_date)
|
710
|
+
SELECT e.patient_id,
|
711
|
+
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS pregnant_status,
|
712
|
+
DATE(obs.obs_datetime) visit_date
|
713
|
+
FROM #{schema}.encounter e
|
714
|
+
INNER JOIN #{schema}.obs ON e.patient_id = obs.person_id
|
715
|
+
AND e.voided = 0
|
716
|
+
AND e.program_id = 1
|
717
|
+
AND e.encounter_type = 53
|
718
|
+
AND obs.voided = 0
|
719
|
+
AND obs.concept_id IN(6131, 1755)
|
720
|
+
INNER JOIN #{schema}.person ON person.person_id = obs.person_id
|
721
|
+
AND person.gender IN('Female','F')
|
722
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
723
|
+
ORDER BY obs_datetime DESC;
|
724
|
+
SQL
|
725
|
+
end
|
726
|
+
|
727
|
+
def insert_data_sanitizer_breastfeeding_status
|
728
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
729
|
+
INSERT INTO #{schema}.data_sanitizer_breastfeeding_status (patient_id, breastfeeding_status, visit_date)
|
730
|
+
SELECT e.patient_id,
|
731
|
+
(CASE WHEN obs.value_coded = 1065 THEN 'YES' ELSE 'NO' END) AS breastfeeding_status,
|
732
|
+
DATE(obs.obs_datetime) visit_date
|
733
|
+
FROM #{schema}.encounter e
|
734
|
+
INNER JOIN #{schema}.obs ON e.patient_id = obs.person_id
|
735
|
+
AND e.voided = 0
|
736
|
+
AND e.program_id = 1
|
737
|
+
AND e.encounter_type = 53
|
738
|
+
AND obs.voided = 0
|
739
|
+
AND obs.concept_id IN(834,5632, 8039,7965)
|
740
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
741
|
+
ORDER BY obs_datetime DESC;
|
742
|
+
SQL
|
743
|
+
end
|
744
|
+
|
745
|
+
def insert_data_sanitizer_side_effect
|
746
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
747
|
+
INSERT INTO #{schema}.data_sanitizer_side_effect (patient_id, visit_date, concept_id, value_coded, available)
|
748
|
+
SELECT t.person_id,
|
749
|
+
DATE(t.obs_datetime) visit_date,
|
750
|
+
t2.concept_id,
|
751
|
+
t2.value_coded,
|
752
|
+
(CASE WHEN t2.value_coded = 1065 THEN 'YES' ELSE 'NO' END) available
|
753
|
+
FROM #{schema}.obs t
|
754
|
+
INNER JOIN #{schema}.obs t2 ON t.concept_id = 7755
|
755
|
+
AND t.obs_id = t2.obs_group_id
|
756
|
+
AND t.voided = 0
|
757
|
+
AND t2.voided = 0
|
758
|
+
INNER JOIN #{schema}.encounter e ON e.encounter_id = t.encounter_id
|
759
|
+
AND e.program_id = 1
|
760
|
+
AND e.encounter_type = 53
|
761
|
+
AND e.voided = 0
|
762
|
+
GROUP BY t.person_id, DATE(t.obs_datetime), t.value_coded, t2.value_coded;
|
763
|
+
SQL
|
764
|
+
end
|
765
|
+
|
766
|
+
def insert_data_sanitizer_adherence
|
767
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
768
|
+
INSERT INTO #{schema}.data_sanitizer_adherence (patient_id, visit_date, adherence)
|
769
|
+
SELECT o.person_id, DATE(o.visit_date) visit_date, ROUND(MAX(CASE WHEN (REPLACE(adherence, '%', '')) BETWEEN 95 AND 105 THEN (REPLACE(adherence, '%', '')) ELSE 0 END)) AS adherence
|
770
|
+
FROM (
|
771
|
+
SELECT obs.person_id,
|
772
|
+
DATE(obs_datetime) AS visit_date,
|
773
|
+
(CASE WHEN value_numeric IS NULL THEN value_text ELSE value_numeric END) AS adherence
|
774
|
+
FROM #{schema}.obs
|
775
|
+
INNER JOIN #{schema}.encounter e ON e.encounter_type = 68
|
776
|
+
AND e.encounter_id = obs.encounter_id
|
777
|
+
AND e.program_id = 1
|
778
|
+
WHERE obs.voided = 0
|
779
|
+
AND obs.concept_id = 6987
|
780
|
+
AND (obs.value_numeric IS NOT NULL OR obs.value_text IS NOT NULL)
|
781
|
+
) AS o
|
782
|
+
GROUP BY o.person_id, o.visit_date
|
783
|
+
ORDER BY o.person_id, o.visit_date;
|
784
|
+
SQL
|
785
|
+
end
|
786
|
+
|
787
|
+
def insert_data_sanitizer_appointment
|
788
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
789
|
+
INSERT INTO #{schema}.data_sanitizer_appointment (patient_id, value_datetime, visit_date)
|
790
|
+
SELECT e.patient_id,
|
791
|
+
DATE(value_datetime),
|
792
|
+
DATE(obs.obs_datetime) visit_date
|
793
|
+
FROM #{schema}.encounter e
|
794
|
+
INNER JOIN #{schema}.obs ON e.patient_id = obs.person_id
|
795
|
+
AND e.voided = 0
|
796
|
+
AND e.encounter_type = 7
|
797
|
+
AND e.program_id = 1
|
798
|
+
AND obs.voided = 0
|
799
|
+
AND obs.concept_id = 5096
|
800
|
+
GROUP BY obs.person_id, DATE(obs.obs_datetime)
|
801
|
+
ORDER BY obs_datetime DESC;
|
802
|
+
SQL
|
803
|
+
end
|
804
|
+
|
805
|
+
def insert_data_sanitizer_arv_medication
|
806
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
807
|
+
INSERT INTO #{schema}.data_sanitizer_arv_medication (patient_id, order_id, visit_date, drug_runout_date, num_unique_arvs, unique_arvs_given, drug_names)
|
808
|
+
SELECT e.patient_id, o.order_id ,
|
809
|
+
DATE(o.start_date) AS visit_date,
|
810
|
+
DATE(MIN(o.auto_expire_date)) AS drug_runout_date,
|
811
|
+
COUNT(DISTINCT d.drug_id) AS num_unique_arvs,
|
812
|
+
GROUP_CONCAT(DISTINCT d.drug_id SEPARATOR ', ') AS unique_arvs_given,
|
813
|
+
GROUP_CONCAT(DISTINCT d.name SEPARATOR ', ') AS drug_names
|
814
|
+
FROM #{schema}.orders o
|
815
|
+
INNER JOIN #{schema}.drug_order da ON da.order_id = o.order_id
|
816
|
+
AND o.voided = 0
|
817
|
+
AND da.quantity > 0
|
818
|
+
INNER JOIN #{schema}.drug d ON d.drug_id = da.drug_inventory_id
|
819
|
+
INNER JOIN #{schema}.obs ON obs.order_id = o.order_id
|
820
|
+
AND obs.voided = 0
|
821
|
+
INNER JOIN #{schema}.encounter e ON e.program_id = 1
|
822
|
+
AND e.encounter_id = obs.encounter_id
|
823
|
+
AND e.encounter_type = 54
|
824
|
+
INNER JOIN #{schema}.arv_drug ON arv_drug.drug_id = d.drug_id
|
825
|
+
GROUP BY obs.person_id, o.order_id, DATE(o.start_date);
|
826
|
+
SQL
|
827
|
+
end
|
828
|
+
|
829
|
+
def insert_data_sanitizer_arv_orders
|
830
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
831
|
+
INSERT INTO #{schema}.data_sanitizer_arv_orders(patient_id, order_id, encounter_id, visit_date, drug_id, drug_name, units, equivalent_daily_dose, instructions, start_date, runout_date, quantity)
|
832
|
+
SELECT
|
833
|
+
m.patient_id, o.order_id, orders.encounter_id , m.visit_date,
|
834
|
+
d.drug_id, d.name, d.units, o.equivalent_daily_dose, orders.instructions,
|
835
|
+
orders.start_date, orders.auto_expire_date,SUM(o.quantity)
|
836
|
+
FROM #{schema}.data_sanitizer_arv_medication m
|
837
|
+
INNER JOIN #{schema}.drug_order o ON o.order_id = m.order_id
|
838
|
+
INNER JOIN #{schema}.drug d ON d.drug_id = o.drug_inventory_id
|
839
|
+
INNER JOIN #{schema}.orders ON orders.order_id = o.order_id
|
840
|
+
GROUP BY d.drug_id, o.order_id, m.visit_date;
|
841
|
+
SQL
|
842
|
+
end
|
843
|
+
|
844
|
+
def insert_data_sanitizer_encounter_dates
|
845
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
846
|
+
INSERT INTO #{schema}.data_sanitizer_encounter_dates(patient_id, visit_date)
|
847
|
+
SELECT patient_id, DATE(encounter_datetime)
|
848
|
+
FROM #{schema}.encounter
|
849
|
+
WHERE program_id = 1 AND voided = 0
|
850
|
+
GROUP BY patient_id, DATE(encounter_datetime)
|
851
|
+
SQL
|
852
|
+
end
|
853
|
+
|
854
|
+
def insert_data_sanitizer_patient_outcomes
|
855
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
856
|
+
INSERT INTO #{schema}.data_sanitizer_patient_outcomes(patient_id, visit_date, end_date, state, concept_id, outcome)
|
857
|
+
SELECT p.patient_id,s.start_date, s.end_date, s.state, pws.concept_id, cn.name
|
858
|
+
FROM #{schema}.patient_program p
|
859
|
+
INNER JOIN #{schema}.patient_state s ON p.patient_program_id = s.patient_program_id
|
860
|
+
AND p.program_id = 1 AND p.voided = 0 AND s.voided = 0 AND s.state IS NOT NULL
|
861
|
+
INNER JOIN #{schema}.program_workflow_state pws ON s.state = pws.program_workflow_state_id AND pws.retired = 0 AND pws.terminal = 1
|
862
|
+
INNER JOIN #{schema}.concept_name cn ON cn.concept_id = pws.concept_id AND cn.voided = 0 AND cn.name IS NOT NULL AND LENGTH(cn.name) > 0
|
863
|
+
GROUP BY p.patient_id, DATE(s.start_date), DATE(p.date_enrolled)
|
864
|
+
ORDER BY DATE(s.start_date) DESC, DATE(p.date_enrolled) DESC;
|
865
|
+
SQL
|
866
|
+
end
|
867
|
+
|
868
|
+
def insert_data_sanitizer_patient_who_stage
|
869
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
870
|
+
INSERT INTO #{schema}.data_sanitizer_patient_who_stage(patient_id, visit_date, who_stage)
|
871
|
+
SELECT e.patient_id, DATE(t1.obs_datetime) visit_date, cn.name FROM #{schema}.encounter e
|
872
|
+
INNER JOIN #{schema}.obs t1 ON t1.encounter_id = e.encounter_id AND e.voided = 0
|
873
|
+
AND t1.voided = 0 AND e.encounter_type = 52 AND t1.concept_id = 7562
|
874
|
+
INNER JOIN #{schema}.concept_name cn ON cn.concept_id = t1.value_coded AND cn.voided = 0
|
875
|
+
WHERE LENGTH(cn.name) > 0
|
876
|
+
GROUP BY e.patient_id ORDER BY t1.obs_datetime DESC, t1.date_created DESC
|
877
|
+
SQL
|
878
|
+
end
|
879
|
+
|
880
|
+
def insert_data_sanitizer_patient_reason_for_starting
|
881
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
882
|
+
INSERT INTO #{schema}.data_sanitizer_patient_reason_for_starting(patient_id, visit_date, reason_for_starting_art)
|
883
|
+
SELECT e.patient_id, DATE(t1.obs_datetime) visit_date, cn.name FROM #{schema}.encounter e
|
884
|
+
INNER JOIN #{schema}.obs t1 ON t1.encounter_id = e.encounter_id AND e.voided = 0
|
885
|
+
AND t1.voided = 0 AND e.encounter_type = 52 AND t1.concept_id = 7563
|
886
|
+
INNER JOIN #{schema}.concept_name cn ON cn.concept_id = t1.value_coded AND cn.voided = 0
|
887
|
+
WHERE LENGTH(cn.name) > 0
|
888
|
+
GROUP BY e.patient_id ORDER BY t1.obs_datetime DESC, t1.date_created DESC;
|
889
|
+
SQL
|
890
|
+
end
|
891
|
+
|
892
|
+
def insert_data_sanitizer_patient_detailed_side_effects
|
893
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
894
|
+
INSERT INTO #{schema}.data_sanitizer_patient_detailed_side_effects(patient_id, visit_date, peripheral_neuropathy, anemia, hepatitis,
|
895
|
+
jaundice, psychosis, skin_rash, dizziness, lipodystrophy, renal_failure, other, kidney_failure, gynaecomastia,
|
896
|
+
cough, headache, lactic_acidosis, alcohol_problem, fever, nausea, vomiting, night_sweats, other_specify, malnutrition)
|
897
|
+
SELECT
|
898
|
+
t.person_id patient_id,
|
899
|
+
DATE(t.obs_datetime) as visit_date,
|
900
|
+
MAX(CASE WHEN t2.concept_id = 821 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS peripheral_neuropathy,
|
901
|
+
MAX(CASE WHEN t2.concept_id = 3 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS anemia,
|
902
|
+
MAX(CASE WHEN t2.concept_id = 29 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS hepatitis,
|
903
|
+
MAX(CASE WHEN t2.concept_id = 215 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS jaundice,
|
904
|
+
MAX(CASE WHEN t2.concept_id = 219 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS psychosis,
|
905
|
+
MAX(CASE WHEN t2.concept_id = 512 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS skin_rash,
|
906
|
+
MAX(CASE WHEN t2.concept_id = 877 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS dizziness,
|
907
|
+
MAX(CASE WHEN t2.concept_id = 2148 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS lipodystrophy,
|
908
|
+
MAX(CASE WHEN t2.concept_id = 3681 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS renal_failure,
|
909
|
+
MAX(CASE WHEN t2.concept_id = 6408 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS other,
|
910
|
+
MAX(CASE WHEN t2.concept_id = 9242 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS kidney_failure,
|
911
|
+
MAX(CASE WHEN t2.concept_id = 9440 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS gynaecomastia,
|
912
|
+
MAX(CASE WHEN t2.concept_id = 107 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS cough,
|
913
|
+
MAX(CASE WHEN t2.concept_id = 620 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS headache,
|
914
|
+
MAX(CASE WHEN t2.concept_id = 1458 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS lactic_acidosis,
|
915
|
+
MAX(CASE WHEN t2.concept_id = 1773 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS alcohol_problem,
|
916
|
+
MAX(CASE WHEN t2.concept_id = 5945 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS fever,
|
917
|
+
MAX(CASE WHEN t2.concept_id = 5978 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS nausea,
|
918
|
+
MAX(CASE WHEN t2.concept_id = 5980 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS vomiting,
|
919
|
+
MAX(CASE WHEN t2.concept_id = 6029 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS night_sweats,
|
920
|
+
MAX(CASE WHEN t2.concept_id = 7215 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS other_specify,
|
921
|
+
MAX(CASE WHEN t2.concept_id = 8260 THEN CASE WHEN t2.value_coded = 1065 THEN 'Yes' WHEN t2.value_coded = 1066 THEN 'No' ELSE t2.value_coded END END) AS malnutrition
|
922
|
+
FROM #{schema}.obs t
|
923
|
+
LEFT JOIN #{schema}.obs t2 ON t.obs_id = t2.obs_group_id
|
924
|
+
WHERE t.concept_id IN (7755, 7951)
|
925
|
+
AND t.voided = 0
|
926
|
+
AND t2.voided = 0
|
927
|
+
AND t2.concept_id IN (821, 3, 29, 215, 219, 512, 877, 2148, 3681, 6408, 9242, 9440, 107, 620, 877, 1458, 1773, 5945, 5978, 5980, 6029, 7215, 8260)
|
928
|
+
GROUP BY t.person_id, DATE(t.obs_datetime)
|
929
|
+
ORDER BY t.person_id, visit_date;
|
930
|
+
SQL
|
931
|
+
end
|
932
|
+
|
933
|
+
def insert_data_sanitizer_visits
|
934
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
935
|
+
INSERT INTO #{schema}.data_sanitizer_visits (patient_id, visit_date, who_stage, reason_for_starting_antiretroviral_treatment_construct, patient_present, guardian_present, height, weight,
|
936
|
+
peripheral_neuropathy, anemia, hepatitis,jaundice, psychosis, skin_rash, dizziness, lipodystrophy, renal_failure, other, kidney_failure, gynaecomastia,
|
937
|
+
cough, headache, lactic_acidosis, alcohol_problem, fever, nausea, vomiting, night_sweats, other_specify, malnutrition, adherence, drugs_dispensed,
|
938
|
+
drug_end_date, outcome_concept_id, outcome_end_date, outcome, appointment_date)
|
939
|
+
SELECT
|
940
|
+
e.patient_id, e.visit_date, pws.who_stage, rfs.reason_for_starting_art, pp.patient_present, gp.guardian_present, h.height, w.weight,
|
941
|
+
peripheral_neuropathy, anemia, hepatitis,jaundice, psychosis, skin_rash, dizziness, lipodystrophy, renal_failure, other, kidney_failure, gynaecomastia,
|
942
|
+
cough, headache, lactic_acidosis, alcohol_problem, fever, nausea, vomiting, night_sweats, other_specify, malnutrition,ad.adherence, m.unique_arvs_given,
|
943
|
+
m.drug_runout_date, po.concept_id, po.end_date, po.outcome, ap.value_datetime next_appointment_date
|
944
|
+
FROM #{schema}.data_sanitizer_encounter_dates e
|
945
|
+
LEFT JOIN #{schema}.data_sanitizer_patient_present pp ON pp.patient_id = e.patient_id AND pp.visit_date = e.visit_date
|
946
|
+
LEFT JOIN #{schema}.data_sanitizer_guardian_present gp ON gp.patient_id = e.patient_id AND gp.visit_date = e.visit_date
|
947
|
+
LEFT JOIN #{schema}.data_sanitizer_patients_height h ON h.patient_id = e.patient_id AND h.visit_date = e.visit_date
|
948
|
+
LEFT JOIN #{schema}.data_sanitizer_patients_weight w ON w.patient_id = e.patient_id AND w.visit_date = e.visit_date
|
949
|
+
LEFT JOIN #{schema}.data_sanitizer_adherence ad ON ad.patient_id = e.patient_id AND ad.visit_date = e.visit_date
|
950
|
+
LEFT JOIN #{schema}.data_sanitizer_arv_medication m ON m.patient_id = e.patient_id AND m.visit_date = e.visit_date
|
951
|
+
LEFT JOIN #{schema}.data_sanitizer_appointment ap ON ap.patient_id = e.patient_id AND e.visit_date = ap.visit_date
|
952
|
+
LEFT JOIN #{schema}.data_sanitizer_patient_outcomes po ON po.patient_id = e.patient_id AND e.visit_date = po.visit_date
|
953
|
+
LEFT JOIN #{schema}.data_sanitizer_patient_who_stage pws ON pws.patient_id = e.patient_id AND e.visit_date = pws.visit_date
|
954
|
+
LEFT JOIN #{schema}.data_sanitizer_patient_reason_for_starting rfs ON rfs.patient_id = e.patient_id AND e.visit_date = rfs.visit_date
|
955
|
+
LEFT JOIN #{schema}.data_sanitizer_patient_detailed_side_effects se ON se.patient_id = e.patient_id AND se.visit_date = e.visit_date;
|
956
|
+
SQL
|
957
|
+
end
|
958
|
+
# rubocop:enable Metrics/MethodLength
|
959
|
+
|
960
|
+
# ========================
|
961
|
+
# DATABASE HELPER METHODS
|
962
|
+
# ========================
|
963
|
+
|
964
|
+
def check_if_table_exists(table_name)
|
965
|
+
result = ActiveRecord::Base.connection.select_one <<~SQL
|
966
|
+
SELECT COUNT(*) AS count
|
967
|
+
FROM INFORMATION_SCHEMA.TABLES
|
968
|
+
WHERE table_schema = '#{schema}'
|
969
|
+
AND table_name = '#{table_name}'
|
970
|
+
SQL
|
971
|
+
result['count'].to_i.positive?
|
972
|
+
end
|
973
|
+
|
974
|
+
def count_table_columns(table_name)
|
975
|
+
result = ActiveRecord::Base.connection.select_one <<~SQL
|
976
|
+
SELECT COUNT(*) AS count
|
977
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
978
|
+
WHERE table_schema = '#{schema}'
|
979
|
+
AND table_name = '#{table_name}'
|
980
|
+
SQL
|
981
|
+
result['count'].to_i
|
982
|
+
end
|
983
|
+
end
|
984
|
+
# rubocop:enable Metrics/ClassLength
|
985
|
+
end
|