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.
@@ -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