1 from PySide2 import QtSql as qts, QtWidgets
2 from PySide2 import QtWidgets as qtw
3 from PySide2 import QtCore as qtc
10 # noinspection PyTypeChecker
11 from utils import resource_path
14 class Database(qtc.QObject):
18 def get_instance(mainWindow):
19 if Database.__instance is None:
21 return Database.__instance
27 if not self.db.open():
30 'open db: ' + self.db.lastError().text()
33 all_sqls = open(resource_path('db/database.sql'), encoding='utf8').read().split(';')
35 query = qts.QSqlQuery(self.db)
40 'creating db: ' + self.db.lastError().text()
44 def __init__(self, mainWindow):
46 if Database.__instance is not None:
47 raise Exception("This class is a singleton!")
48 self.mainWindow = mainWindow
49 self.db = qts.QSqlDatabase.addDatabase('QSQLITE')
50 db_path = mainWindow.settings.value('db_path', None, type=str)
51 if db_path is None or not path.exists(db_path):
52 db_path = QtWidgets.QFileDialog.getExistingDirectory(mainWindow, 'Select a folder to store your data', '.', QtWidgets.QFileDialog.ShowDirsOnly)
53 if db_path is None or len(db_path.strip()) == 0:
55 mainWindow.settings.setValue('db_path', db_path)
56 if not path.exists(db_path):
58 self.db.setDatabaseName('{}/minimizer.db'.format(db_path))
59 if not os.path.exists('{}/minimizer.db'.format(db_path)):
62 if not self.db.open():
64 self.tr('DB Connection Error'),
65 self.tr('Could not open database file {}').format(self.db.lastError().text())
68 required_tables = {'trials', 'discarded_identifiers', 'treatments', 'factors', 'levels', 'subjects',
69 'subject_levels', 'preloads'}
70 missing_tables = required_tables - set(self.db.tables())
73 self.tr('DB Integrity Error'),
74 self.tr('Missing tables, please repair DB {}').format(missing_tables)
77 if not self.checkForeignKeys():
79 Database.__instance = self
81 def checkForeignKeys(self):
82 query = qts.QSqlQuery(self.db)
83 query.prepare('PRAGMA foreign_keys;')
85 self.show_query_error(query)
88 self.show_query_error(query)
91 query.prepare('PRAGMA foreign_keys = ON;')
93 self.show_query_error(query)
94 query.prepare('PRAGMA foreign_keys;')
97 return query.value(0) > 0
101 def get_treatment_title(self, treatment_id):
102 query = qts.QSqlQuery(self.db)
103 query.prepare('SELECT title FROM treatments WHERE id = :treatment_id')
104 query.bindValue(':treatment_id', treatment_id)
105 if not query.exec_():
106 self.show_query_error(query)
108 return query.value('title')
110 def update_subject_treatment_id(self, subject_id, treatment_id):
111 query = qts.QSqlQuery(self.db)
112 query.prepare('''UPDATE subjects set treatment_id = :treatment_id,
113 modified = CURRENT_TIMESTAMP WHERE id = :subject_id''')
114 query.bindValue(':treatment_id', treatment_id)
115 query.bindValue(':subject_id', subject_id)
116 if not query.exec_():
117 self.show_query_error(query)
119 def get_subject_treatment_id(self, subject_id):
120 query = qts.QSqlQuery(self.db)
121 query.prepare("SELECT treatment_id FROM subjects WHERE id = :subject_id")
122 query.bindValue(':subject_id', subject_id)
123 if not query.exec_():
124 self.show_query_error(query)
127 return query.value('treatment_id')
129 def get_subject(self, subject_id):
130 query = qts.QSqlQuery(self.db)
131 query.prepare("SELECT * FROM subjects WHERE id = :subject_id")
132 query.bindValue(':subject_id', subject_id)
133 if not query.exec_():
134 self.show_query_error(query)
139 def get_subjects(self, trial_id):
140 query = qts.QSqlQuery(self.db)
141 query.prepare('''SELECT id, treatment_id, identifier_value, enrolled,
142 modified FROM subjects WHERE trial_id = :trial_id''')
143 query.bindValue(':trial_id', trial_id)
144 if not query.exec_():
145 self.show_query_error(query)
150 query.value('treatment_id'),
151 query.value('identifier_value'),
152 query.value('enrolled'),
153 query.value('modified')
155 subjects.append(subject)
158 def get_subject_level_titles(self, subject_levels):
159 query = qts.QSqlQuery(self.db)
161 for factor_id, level_id in subject_levels:
162 query.prepare('SELECT title FROM levels WHERE id = :level_id')
163 query.bindValue(':level_id', level_id)
164 if not query.exec_():
165 self.show_query_error(query)
168 level_title.append(query.value('title'))
171 def get_subject_levels(self, subject_id):
172 query = qts.QSqlQuery(self.db)
173 query.prepare("SELECT factor_id, level_id FROM subject_levels WHERE subject_id = :subject_id ORDER BY id")
174 query.bindValue(':subject_id', subject_id)
175 if not query.exec_():
176 self.show_query_error(query)
179 subject_level = [query.value('factor_id'), query.value('level_id')]
180 subject_levels.append(subject_level)
181 return subject_levels
183 def get_freq(self, trial_id):
184 subjects = self.get_subjects(trial_id)
185 freq = self.get_empty_freq(trial_id)
186 for subject in subjects:
187 subject_levels = self.get_subject_levels(subject[0])
188 for subject_level in subject_levels:
189 key = (subject[1], subject_level[0], subject_level[1])
193 def get_empty_freq(self, trial_id):
195 treatments = self.read_treatments(trial_id)
196 factors = self.read_factors(trial_id)
197 if not treatments or not factors:
199 for treatment in treatments:
200 for factor in factors:
201 levels = self.factor_levels(factor[0])
203 key = (treatment[0], factor[0], level[0])
209 def get_preload(self, trial_id):
210 query = qts.QSqlQuery(self.db)
211 preload = self.get_empty_freq(trial_id)
212 query.prepare("SELECT treatment_id, factor_id, level_id, count FROM preloads WHERE trial_id = :trial_id")
213 query.bindValue(':trial_id', trial_id)
214 if not query.exec_():
215 self.show_query_error(query)
218 row = [query.value('treatment_id'), query.value('factor_id'), query.value('level_id'), query.value('count')]
221 key = (row[0], row[1], row[2])
222 preload[key] = row[3]
225 def get_preload_with_freq(self, trial_id):
226 freq = self.get_freq(trial_id)
227 preload = self.get_preload(trial_id)
228 if freq is None or preload is None:
230 preload_with_freq = {}
232 preload_with_freq[key] = freq[key] + preload[key]
233 return preload_with_freq
235 def insert_level(self, trial_id, factor_id, title):
236 query = qts.QSqlQuery(self.db)
237 query.prepare('INSERT INTO levels (trial_id, factor_id, title) VALUES (:trial_id, :factor_id, :title)')
238 query.bindValue(':trial_id', trial_id)
239 query.bindValue(':factor_id', factor_id)
240 query.bindValue(':title', title)
241 if not query.exec_():
242 self.show_query_error(query)
243 return query.lastInsertId()
245 def insert_factor(self, trial_id, title):
246 query = qts.QSqlQuery(self.db)
247 query.prepare('INSERT INTO factors (trial_id, title) VALUES (:trial_id, :title)')
248 query.bindValue(':title', title)
249 query.bindValue(':trial_id', trial_id)
250 if not query.exec_():
251 self.show_query_error(query)
252 return query.lastInsertId()
254 def insert_treatment(self, trial_id, title):
255 query = qts.QSqlQuery(self.db)
256 query.prepare('INSERT INTO treatments (trial_id, title) VALUES (:trial_id, :title)')
257 query.bindValue(':title', title)
258 query.bindValue(':trial_id', trial_id)
259 if not query.exec_():
260 self.show_query_error(query)
261 return query.lastInsertId()
263 def insert_trial(self, title):
264 query = qts.QSqlQuery(self.db)
265 query.prepare('INSERT INTO trials (title) VALUES (:title)')
266 query.bindValue(':title', title)
267 if not query.exec_():
268 self.show_query_error(query)
269 return query.lastInsertId()
271 def delete_level(self, level_id):
272 query = qts.QSqlQuery(self.db)
273 query.prepare('DELETE FROM levels WHERE id = :id')
274 query.bindValue(':id', level_id)
275 if not query.exec_():
276 self.show_query_error(query)
278 def delete_treatment(self, treatment_id):
279 query = qts.QSqlQuery(self.db)
280 query.prepare('DELETE FROM treatments WHERE id = :id')
281 query.bindValue(':id', treatment_id)
282 if not query.exec_():
283 self.show_query_error(query)
285 def delete_factor(self, factor_id):
286 query = qts.QSqlQuery(self.db)
287 query.prepare('DELETE FROM factors WHERE id = :id')
288 query.bindValue(':id', factor_id)
289 if not query.exec_():
290 self.show_query_error(query)
292 def delete_trial(self, trial_id):
293 query = qts.QSqlQuery(self.db)
294 query.prepare('DELETE FROM trials WHERE id = :id')
295 query.bindValue(':id', trial_id)
296 if not query.exec_():
297 self.show_query_error(query)
299 def get_title(self, row_id, table):
300 query = qts.QSqlQuery(self.db)
301 query.prepare('SELECT title FROM {} WHERE id = :row_id'.format(table))
302 query.bindValue(':row_id', row_id)
303 if not query.exec_():
304 self.show_query_error(query)
306 return query.value('title')
308 def update_level(self, level_id, title):
309 query = qts.QSqlQuery(self.db)
310 query.prepare('UPDATE levels set title = :title WHERE id = :id')
311 query.bindValue(':title', title)
312 query.bindValue(':id', level_id)
313 if not query.exec_():
314 if self.show_query_error(query):
315 return self.get_title(level_id, 'levels')
317 def update_factor(self, factor_id, column, value):
318 query = qts.QSqlQuery(self.db)
319 query.prepare('UPDATE factors set {} = :value WHERE id = :id'.format(column))
320 query.bindValue(':value', value)
321 query.bindValue(':id', factor_id)
322 if not query.exec_():
323 if self.show_query_error(query):
324 return self.get_title(factor_id, 'factors')
326 def update_treatment(self, treatment_id, column, value):
327 query = qts.QSqlQuery(self.db)
328 query.prepare('UPDATE treatments set {} = :value WHERE id = :id'.format(column))
329 query.bindValue(':value', value)
330 query.bindValue(':id', treatment_id)
331 if not query.exec_():
332 if self.show_query_error(query):
333 return self.get_title(treatment_id, 'treatments')
335 print(query.result())
338 def update_trial(self, trial_id, column, value):
339 query = qts.QSqlQuery(self.db)
340 query.prepare('UPDATE trials SET {} = :value, modified = CURRENT_TIMESTAMP WHERE id = :id'.format(column))
341 query.bindValue(':value', value)
342 query.bindValue(':id', trial_id)
343 if not query.exec_():
344 if self.show_query_error(query):
345 return self.get_title(trial_id, 'trials')
347 def load_levels(self, factor_id):
348 query = qts.QSqlQuery(self.db)
349 query.prepare('SELECT * FROM levels WHERE factor_id = :factor_id ORDER BY id')
350 query.bindValue(':factor_id', factor_id)
351 if not query.exec_():
352 self.show_query_error(query)
355 def load_treatments(self, trial_id):
356 query = qts.QSqlQuery(self.db)
357 query.prepare('SELECT * FROM treatments WHERE trial_id = :trial_id ORDER BY id')
358 query.bindValue(':trial_id', trial_id)
359 if not query.exec_():
360 self.show_query_error(query)
363 def load_factors(self, trial_id):
364 query = qts.QSqlQuery(self.db)
365 query.prepare('SELECT * FROM factors WHERE trial_id = :trial_id ORDER BY id')
366 query.bindValue(':trial_id', trial_id)
367 if not query.exec_():
368 self.show_query_error(query)
371 def get_levels(self, factor_id):
372 query = qts.QSqlQuery(self.db)
373 query.prepare('SELECT title FROM levels WHERE factor_id = :factor_id ORDER BY id')
374 query.bindValue(':factor_id', factor_id)
375 if not query.exec_():
376 qtw.QMessageBox.critical(
378 self.tr('DB read Error'),
379 query.lastError().text()
384 levels.append(query.value('title'))
385 return ', '.join(levels)
387 def get_used_identifiers(self, trial_id):
388 query = qts.QSqlQuery(self.db)
389 query.prepare('SELECT identifier_value FROM subjects WHERE trial_id = :trial_id')
390 query.bindValue(':trial_id', trial_id)
391 if not query.exec_():
392 self.show_query_error(query)
395 ret.append(query.value('identifier_value'))
398 def get_discarded_identifiers(self, trial_id):
399 query = qts.QSqlQuery(self.db)
400 query.prepare('SELECT identifier FROM discarded_identifiers WHERE trial_id = :trial_id')
401 query.bindValue(':trial_id', trial_id)
402 if not query.exec_():
403 self.show_query_error(query)
406 ret.append(query.value('identifier'))
409 def get_count_discarded_identifiers(self, trial_id):
410 query = qts.QSqlQuery(self.db)
411 query.prepare('SELECT COUNT(*) FROM discarded_identifiers WHERE trial_id = :trial_id')
412 query.bindValue(':trial_id', trial_id)
413 if not query.exec_():
414 self.show_query_error(query)
416 return query.value(0)
418 def get_num_treatments(self, trial_id):
419 query = qts.QSqlQuery(self.db)
420 query.prepare('SELECT COUNT(*) FROM treatments WHERE trial_id = :trial_id')
421 query.bindValue(':trial_id', trial_id)
422 if not query.exec_():
423 self.show_query_error(query)
425 return query.value(0)
427 def get_factor_level_indices(self, factor_id):
428 query = qts.QSqlQuery(self.db)
429 query.prepare('SELECT COUNT(*) FROM levels WHERE factor_id = :factor_id')
430 query.bindValue(':factor_id', factor_id)
431 if not query.exec_():
432 self.show_query_error(query)
434 return list(range(query.value(0)))
436 def get_factor_weights(self, trial_id):
437 factors = self.read_factors(trial_id)
440 return [factor[2] for factor in factors]
442 def get_factors_level_indices(self, trial_id):
443 factors = self.read_factors(trial_id)
447 for factor in factors:
448 fli.append(self.get_factor_level_indices(factor[0]))
451 def get_allocation_ratios(self, trial_id):
452 treatments = self.read_treatments(trial_id)
455 return [treatment[2] for treatment in treatments]
457 def get_treatments_id_dict(self, trial_id):
458 query = qts.QSqlQuery(self.db)
459 query.prepare('SELECT id from treatments WHERE trial_id = :trial_id ORDER BY id')
460 query.bindValue(':trial_id', trial_id)
461 if not query.exec_():
462 self.show_query_error(query)
465 rows.append(query.value('id'))
466 return {row: i for i, row in enumerate(rows)}
468 def get_allocations(self, trial_id):
469 treatment_dict = self.get_treatments_id_dict(trial_id)
471 subjects = self.get_subjects(trial_id)
472 for subject in subjects:
473 allocation = {'allocation': treatment_dict[subject[1]], 'levels': [], 'UI': subject[2]}
474 levels = self.get_subject_levels(subject[0])
476 level_dict = self.get_factor_level_dict(level[0])
477 allocation['levels'].append(level_dict[level[1]])
478 allocations.append(allocation)
481 def get_min_allocation_ratio_group_index(self, trial_id):
482 query = qts.QSqlQuery(self.db)
483 query.prepare('SELECT id FROM treatments WHERE trial_id = :trial_id AND ratio = (SELECT min(ratio) FROM treatments);')
484 query.bindValue(':trial_id', trial_id)
485 if not query.exec_():
486 self.show_query_error(query)
488 result = query.value('id')
489 treatment_dict = self.get_treatments_id_dict(trial_id)
490 return treatment_dict[result]
492 def get_factor_level_dict(self, factor_id):
493 query = qts.QSqlQuery(self.db)
494 query.prepare('SELECT id FROM levels WHERE factor_id = :factor_id ORDER BY id')
495 query.bindValue(':factor_id', factor_id)
496 if not query.exec_():
497 self.show_query_error(query)
500 rows.append(query.value('id'))
501 return {row: i for i, row in enumerate(rows)}
503 def update_trial_setting(self, trial_id, ui):
504 title = ui.trialTitleLineEdit.text()
505 if len(title.strip()) == 0:
507 code = ui.trialCodeLineEdit.text()
508 prob_method = ui.trialProbMethodComboBox.currentIndex()
509 base_prob = ui.trialBaseProbabilitySlider.value() / 100.0
510 dist_method = ui.trialDistanceMethodComboBox.currentIndex()
511 identifier_type = ui.trialIdentifierTypeComboBox.currentIndex()
512 identifier_order = ui.trialIentifierOrderComboBox.currentIndex()
513 identifier_length = ui.trialIdentifierLengthSpinBox.value()
514 recycle_ids = 1 if ui.trialRecycleIdsCheckBox.isChecked() else 0
515 new_subject_random = 1 if ui.trialNewSubjectRandomCheckBox.isChecked() else 0
516 arms_weight = ui.trialArmsWeightDoubleSlider.value()
517 query = qts.QSqlQuery(self.db)
518 query.prepare('UPDATE trials set '
521 'modified = CURRENT_TIMESTAMP, '
522 'prob_method = :prob_method, '
523 'base_prob = :base_prob, '
524 'dist_method = :dist_method, '
525 'identifier_type = :identifier_type, '
526 'identifier_order = :identifier_order, '
527 'identifier_length = :identifier_length, '
528 'recycle_ids = :recycle_ids, '
529 'new_subject_random = :new_subject_random, '
530 'arms_weight = :arms_weight '
533 query.bindValue(':title', title)
534 query.bindValue(':code', code)
535 query.bindValue(':prob_method', prob_method)
536 query.bindValue(':base_prob', base_prob)
537 query.bindValue(':dist_method', dist_method)
538 query.bindValue(':identifier_type', identifier_type)
539 query.bindValue(':identifier_order', identifier_order)
540 query.bindValue(':identifier_length', identifier_length)
541 query.bindValue(':recycle_ids', recycle_ids)
542 query.bindValue(':new_subject_random', new_subject_random)
543 query.bindValue(':arms_weight', arms_weight)
544 query.bindValue(':id', trial_id)
545 if not query.exec_():
546 self.show_query_error(query)
548 def get_trial_setting(self, trial_id):
549 query = qts.QSqlQuery(self.db)
550 query.prepare('SELECT * FROM trials WHERE id = :id')
551 query.bindValue(':id', trial_id)
552 if not query.exec_():
553 self.show_query_error(query)
558 def clear_trial_setting(self, ui):
559 ui.trialCreatedValueLabel.setText('')
560 ui.trialModifiedValueLabel.setText('')
561 ui.trialTitleLineEdit.setText('')
562 ui.trialCodeLineEdit.setText('')
563 ui.trialProbMethodComboBox.setCurrentIndex(0)
564 ui.trialBaseProbabilitySlider.setValue(0.7 * 100)
565 ui.trialDistanceMethodComboBox.setCurrentIndex(0)
566 ui.trialIdentifierTypeComboBox.setCurrentIndex(0)
567 ui.trialIentifierOrderComboBox.setCurrentIndex(0)
568 ui.trialIdentifierLengthSpinBox.setValue(3)
569 ui.trialRecycleIdsCheckBox.setChecked(False)
570 ui.trialNewSubjectRandomCheckBox.setChecked(False)
571 ui.trialArmsWeightDoubleSlider.setValue(1.0)
573 def map_trial_setting(self, query, ui):
574 ui.trialCreatedValueLabel.setText(query.value('created'))
575 ui.trialModifiedValueLabel.setText(query.value('modified'))
576 ui.trialTitleLineEdit.setText(query.value('title'))
577 ui.trialCodeLineEdit.setText(query.value('code'))
578 ui.trialProbMethodComboBox.setCurrentIndex(query.value('prob_method'))
579 ui.trialBaseProbabilitySlider.setValue(query.value('base_prob') * 100)
580 ui.trialDistanceMethodComboBox.setCurrentIndex(query.value('dist_method'))
581 ui.trialIdentifierTypeComboBox.setCurrentIndex(query.value('identifier_type'))
582 ui.trialIentifierOrderComboBox.setCurrentIndex(query.value('identifier_order'))
583 ui.trialIdentifierLengthSpinBox.setValue(query.value('identifier_length'))
584 ui.trialRecycleIdsCheckBox.setChecked(query.value('recycle_ids') != 0)
585 ui.trialNewSubjectRandomCheckBox.setChecked(query.value('new_subject_random') != 0)
586 ui.trialArmsWeightDoubleSlider.setValue(query.value('arms_weight'))
588 def load_trial_setting(self, trial_id, ui):
589 self.clear_trial_setting(ui)
590 query = self.get_trial_setting(trial_id)
593 self.map_trial_setting(query, ui)
595 def read_factors(self, trial_id):
596 query = qts.QSqlQuery(self.db)
597 query.prepare('SELECT id, title, weight FROM factors WHERE trial_id = :trial_id ORDER BY id')
598 query.bindValue(':trial_id', trial_id)
599 if not query.exec_():
600 self.show_query_error(query)
603 factor = [query.value('id'), query.value('title'), query.value('weight')]
604 factors.append(factor)
607 def read_treatments(self, trial_id):
608 query = qts.QSqlQuery(self.db)
609 query.prepare('SELECT id, title, ratio FROM treatments WHERE trial_id = :trial_id ORDER BY id')
610 query.bindValue(':trial_id', trial_id)
611 if not query.exec_():
612 self.show_query_error(query)
615 treatment = [query.value('id'), query.value('title'), query.value('ratio')]
616 treatments.append(treatment)
619 def get_factor_level(self, trial_id):
620 factors = self.read_factors(trial_id)
624 for factor in factors:
625 query = qts.QSqlQuery(self.db)
626 query.prepare('SELECT id, title FROM levels WHERE factor_id = :factor_id ORDER BY id')
627 query.bindValue(':factor_id', factor[0])
631 levels.append([query.value('id'), query.value('title')])
635 def factor_levels(self, factor_id):
636 query = qts.QSqlQuery(self.db)
637 query.prepare("SELECT id, title FROM levels WHERE factor_id = :factor_id ORDER BY id")
638 query.bindValue(':factor_id', factor_id)
642 levels.append([query.value('id'), query.value('title')])
645 def insert_subject(self, identifier_value, treatment_id, trial_id):
646 query = qts.QSqlQuery(self.db)
647 query.prepare('''INSERT INTO subjects (trial_id, identifier_value, treatment_id)
648 VALUES (:trial_id, :identifier_value, :treatment_id)''')
649 query.bindValue(':trial_id', trial_id)
650 query.bindValue(':identifier_value', identifier_value)
651 query.bindValue(':treatment_id', treatment_id)
652 if not query.exec_():
653 self.show_query_error(query)
654 return query.lastInsertId()
656 def insert_subject_levels(self, trial_id, subject_id, subject_levels):
657 query = qts.QSqlQuery(self.db)
658 for factor_id, level_id in subject_levels:
659 query.prepare('''INSERT INTO subject_levels (trial_id, subject_id, factor_id, level_id)
660 VALUES (:trial_id, :subject_id, :factor_id, :level_id);''')
661 query.bindValue(':trial_id', trial_id)
662 query.bindValue(':subject_id', subject_id)
663 query.bindValue(':factor_id', factor_id)
664 query.bindValue(':level_id', level_id)
665 if not query.exec_():
666 self.show_query_error(query)
667 return self.get_subject_level_titles(subject_levels)
669 def clear_preload(self, trial_id):
670 query = qts.QSqlQuery(self.db)
671 query.prepare('DELETE FROM preloads WHERE trial_id = :trial_id')
672 query.bindValue(':trial_id', trial_id)
675 def delete_subject_levels(self, subject_id):
676 query = qts.QSqlQuery(self.db)
677 query.prepare('DELETE FROM subject_levels WHERE subject_id = :subject_id')
678 query.bindValue(':subject_id', subject_id)
679 if not query.exec_():
680 self.show_query_error(query)
682 def delete_subject(self, subject_id, id_value=None, trial_id=None):
683 query = qts.QSqlQuery(self.db)
684 query.prepare('DELETE FROM subjects WHERE id = :subject_id;')
685 query.bindValue(':subject_id', subject_id)
686 if not query.exec_():
687 self.show_query_error(query)
690 query.prepare('''INSERT INTO discarded_identifiers (trial_id, identifier)
691 VALUES (:trial_id, :identifier)''')
692 query.bindValue(':trial_id', trial_id)
693 query.bindValue(':identifier', id_value)
694 if not query.exec_():
695 self.show_query_error(query)
697 def delete_subjects(self, trial_id):
698 query = qts.QSqlQuery(self.db)
699 query.prepare('DELETE FROM subjects WHERE trial_id = :trial_id;')
700 query.bindValue(':trial_id', trial_id)
701 if not query.exec_():
702 self.show_query_error(query)
703 query.prepare('DELETE FROM discarded_identifiers WHERE trial_id = :trial_id')
704 query.bindValue(':trial_id', trial_id)
705 if not query.exec_():
706 self.show_query_error(query)
708 def save_preload(self, trial_id, preload):
709 query = qts.QSqlQuery(self.db)
713 query.prepare('''INSERT INTO preloads (trial_id, treatment_id, factor_id, level_id, count)
714 VALUES (:trial_id, :treatment_id, :factor_id, :level_id, :count)''')
715 query.bindValue(':trial_id', trial_id)
716 query.bindValue(':treatment_id', t)
717 query.bindValue(':factor_id', f)
718 query.bindValue(':level_id', lv)
719 query.bindValue(':count', c)
722 def show_error(self, title, text):
723 qtw.QMessageBox.critical(self.mainWindow, title, text)
725 def show_query_error(self, query):
726 qtw.QMessageBox.critical(
729 query.lastError().text()
731 fatal = 'UNIQUE constraint failed' not in query.lastError().text()
738 def has_preload(self, trial_id):
739 query = qts.QSqlQuery(self.db)
740 query.prepare('SELECT COUNT(*) FROM preloads WHERE trial_id = :trial_id')
741 query.bindValue(':trial_id', trial_id)
742 if not query.exec_():
743 self.show_query_error(query)
746 return query.value(0) > 0
748 def get_subject_count(self, trial_id):
749 query = qts.QSqlQuery(self.db)
750 query.prepare('SELECT COUNT(*) FROM subjects WHERE trial_id = :trial_id')
751 query.bindValue(':trial_id', trial_id)
752 if not query.exec_():
753 self.show_query_error(query)
756 return query.value(0)
758 def has_subject(self, trial_id):
759 subject_count = self.get_subject_count(trial_id)
760 if not subject_count:
762 return subject_count > 0
764 def get_first_trial_setting(self):
765 query = qts.QSqlQuery(self.db)
766 query.prepare('SELECT min(id) FROM trials')
767 if not query.exec_():
768 self.show_query_error(query)
771 trial_id = query.value(0)
772 return self.get_trial_setting(trial_id)
774 def trial_title_exists(self, title):
775 query = qts.QSqlQuery(self.db)
776 query.prepare('SELECT COUNT(*) FROM trials WHERE title = :title')
777 query.bindValue(':title', title)
778 if not query.exec_():
779 self.show_query_error(query)
781 return query.value(0) > 0
783 def treatment_title_exists(self, title, trial_id):
784 query = qts.QSqlQuery(self.db)
785 query.prepare('SELECT COUNT(*) FROM treatments WHERE title = :title and trial_id = :trial_id')
786 query.bindValue(':title', title)
787 query.bindValue(':trial_id', trial_id)
788 if not query.exec_():
789 self.show_query_error(query)
791 return query.value(0) > 0
793 def factor_title_exists(self, title, trial_id):
794 query = qts.QSqlQuery(self.db)
795 query.prepare('SELECT COUNT(*) FROM factors WHERE title = :title and trial_id = :trial_id')
796 query.bindValue(':title', title)
797 query.bindValue(':trial_id', trial_id)
798 if not query.exec_():
799 self.show_query_error(query)
801 return query.value(0) > 0
803 def level_title_exists(self, title, factor_id):
804 query = qts.QSqlQuery(self.db)
805 query.prepare('SELECT COUNT(*) FROM levels WHERE title = :title and factor_id = :factor_id')
806 query.bindValue(':title', title)
807 query.bindValue(':factor_id', factor_id)
808 if not query.exec_():
809 self.show_query_error(query)
811 return query.value(0) > 0