Skip to content

Commit

Permalink
[candidate] Create Sex table and remove Sex enum (#9025)
Browse files Browse the repository at this point in the history
This changes the datatype of the candidate table columns "Sex" and ProbandSex" from enum to varchar(255), instead creating a constraint on the columns determined by a new "sex" table.

The "sex" table contains optional values for candidate sex and candidate proband sex. Projects can add or remove Sex options by simply inserting into or dropping from this table.
  • Loading branch information
CamilleBeau authored Feb 12, 2024
1 parent 52162d1 commit e2d6f04
Show file tree
Hide file tree
Showing 22 changed files with 105 additions and 57 deletions.
2 changes: 1 addition & 1 deletion .phan/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"php",
"htdocs",
"modules",
"src",
"src",
"vendor",
"test"
],
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ changes in the following format: PR #1234***
#### Features
- Add OpenID Connect authorization support to LORIS (PR #8255)

#### Updates and Improvements
- Create new `sex` table to hold candidate sex options, and change Sex and ProbandSex columns of `candidate` table to a varchar(255) datatype that is restricted by the `sex` table (PR #9025)

#### Bug Fixes
- Fix examiner site display (PR #8967)
- bvl_feedback updates in real-time (PR #8966)
Expand Down
17 changes: 14 additions & 3 deletions SQL/0000-00-00-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ CREATE TABLE `language` (
INSERT INTO language (language_code, language_label) VALUES
('en-CA', 'English');

CREATE TABLE `sex` (
`Name` varchar(255) NOT NULL,
PRIMARY KEY `Name` (`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Stores sex options available for candidates in LORIS';

INSERT INTO sex (Name) VALUES ('Male'), ('Female'), ('Other');

CREATE TABLE `users` (
`ID` int(10) unsigned NOT NULL auto_increment,
`UserID` varchar(255) NOT NULL default '',
Expand Down Expand Up @@ -151,7 +158,7 @@ CREATE TABLE `candidate` (
`DoB` date DEFAULT NULL,
`DoD` date DEFAULT NULL,
`EDC` date DEFAULT NULL,
`Sex` enum('Male','Female','Other') DEFAULT NULL,
`Sex` varchar(255) DEFAULT NULL,
`RegistrationCenterID` integer unsigned NOT NULL DEFAULT '0',
`RegistrationProjectID` int(10) unsigned NOT NULL,
`Ethnicity` varchar(255) DEFAULT NULL,
Expand All @@ -166,7 +173,7 @@ CREATE TABLE `candidate` (
`flagged_other_status` enum('not_answered') DEFAULT NULL,
`Testdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`Entity_type` enum('Human','Scanner') NOT NULL DEFAULT 'Human',
`ProbandSex` enum('Male','Female','Other') DEFAULT NULL,
`ProbandSex` varchar(255) DEFAULT NULL,
`ProbandDoB` date DEFAULT NULL,
PRIMARY KEY (`CandID`),
UNIQUE KEY `ID` (`ID`),
Expand All @@ -175,9 +182,13 @@ CREATE TABLE `candidate` (
KEY `CandidateActive` (`Active`),
KEY `FK_candidate_2_idx` (`flagged_reason`),
KEY `PSCID` (`PSCID`),
KEY `FK_candidate_sex_1` (`Sex`),
KEY `FK_candidate_sex_2` (`ProbandSex`),
CONSTRAINT `FK_candidate_1` FOREIGN KEY (`RegistrationCenterID`) REFERENCES `psc` (`CenterID`),
CONSTRAINT `FK_candidate_2` FOREIGN KEY (`flagged_reason`) REFERENCES `caveat_options` (`ID`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `FK_candidate_RegistrationProjectID` FOREIGN KEY (`RegistrationProjectID`) REFERENCES `Project` (`ProjectID`) ON UPDATE CASCADE
CONSTRAINT `FK_candidate_RegistrationProjectID` FOREIGN KEY (`RegistrationProjectID`) REFERENCES `Project` (`ProjectID`) ON UPDATE CASCADE,
CONSTRAINT `FK_candidate_sex_1` FOREIGN KEY (`Sex`) REFERENCES `sex` (`Name`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `FK_candidate_sex_2` FOREIGN KEY (`ProbandSex`) REFERENCES `sex` (`Name`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `session` (
Expand Down
14 changes: 14 additions & 0 deletions SQL/New_patches/2024-01-29-create-sex-table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CREATE TABLE `sex` (
`Name` varchar(255) NOT NULL,
PRIMARY KEY `Name` (`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Stores sex options available for candidates in LORIS';

INSERT INTO sex (Sex) VALUES ('Male'), ('Female'), ('Other');

ALTER TABLE candidate
MODIFY COLUMN sex varchar(255) DEFAULT NULL,
MODIFY COLUMN ProbandSex varchar(255) DEFAULT NULL,
ADD KEY `FK_candidate_sex_1` (`Sex`),
ADD KEY `FK_candidate_sex_2` (`ProbandSex`),
ADD CONSTRAINT `FK_candidate_sex_1` FOREIGN KEY (`Sex`) REFERENCES `sex` (`Name`) ON DELETE RESTRICT ON UPDATE CASCADE,
ADD CONSTRAINT `FK_candidate_sex_2` FOREIGN KEY (`ProbandSex`) REFERENCES `sex` (`Name`) ON DELETE RESTRICT ON UPDATE CASCADE;
6 changes: 1 addition & 5 deletions modules/candidate_list/jsx/candidateListIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,7 @@ class CandidateListIndex extends Component {
name: 'sex',
type: 'select',
hide: this.state.hideFilter,
options: {
'Male': 'Male',
'Female': 'Female',
'Other': 'Other',
},
options: options.Sex,
},
},
{
Expand Down
1 change: 1 addition & 0 deletions modules/candidate_list/php/candidate_list.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class Candidate_List extends \DataFrameworkMenu
'cohort' => $cohort_options,
'participantstatus' => $participant_status_options,
'useedc' => $config->getSetting("useEDC"),
'Sex' => \Utility::getSexList(),
];
}

Expand Down
1 change: 1 addition & 0 deletions modules/candidate_parameters/ajax/getData.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ function getProbandInfoFields()
'ageDifference' => $ageDifference,
'extra_parameters' => $extra_parameters,
'parameter_values' => $parameter_values,
'sexOptions' => \Utility::getSexList(),
];

return $result;
Expand Down
15 changes: 10 additions & 5 deletions modules/candidate_parameters/jsx/ProbandInfo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import Loader from 'Loader';
import {
FormElement,
StaticElement,
SelectElement,
ButtonElement,
DateElement,
TextareaElement,
} from 'jsx/Form';

/**
* Proband Info Component.
Expand All @@ -16,11 +24,7 @@ class ProbandInfo extends Component {
super(props);

this.state = {
sexOptions: {
Male: 'Male',
Female: 'Female',
Other: 'Other',
},
sexOptions: {},
Data: [],
formData: {},
updateResult: null,
Expand Down Expand Up @@ -66,6 +70,7 @@ class ProbandInfo extends Component {
formData: formData,
Data: data,
isLoaded: true,
sexOptions: data.sexOptions,
});
},
error: (error) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace LORIS\candidate_parameters;
use LORIS\Data\Scope;
use LORIS\Data\Cardinality;
use LORIS\Data\Dictionary\DictionaryItem;
use LORIS\Data\Types\Enumeration;

/**
* A CandidateQueryEngine providers a QueryEngine interface to query
Expand Down Expand Up @@ -54,6 +55,8 @@ class CandidateQueryEngine extends \LORIS\Data\Query\SQLQueryEngine
"Demographics",
"Candidate Demographics",
);
$sexList = \Utility::getSexList();
$t = new Enumeration(...$sexList);
$demographics = $demographics->withItems(
[
new DictionaryItem(
Expand All @@ -74,7 +77,7 @@ class CandidateQueryEngine extends \LORIS\Data\Query\SQLQueryEngine
"Sex",
"Candidate's biological sex",
$candscope,
new \LORIS\Data\Types\Enumeration('Male', 'Female', 'Other'),
$t,
new Cardinality(Cardinality::SINGLE),
),
new DictionaryItem(
Expand Down
5 changes: 1 addition & 4 deletions modules/genomic_browser/jsx/tabs_content/cnv.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,7 @@ class CNV extends Component {
filter: {
name: 'Sex',
type: 'select',
options: {
Male: 'Male',
Female: 'Female',
},
options: options.Sex,
},
},
{
Expand Down
5 changes: 1 addition & 4 deletions modules/genomic_browser/jsx/tabs_content/methylation.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@ class Methylation extends Component {
filter: {
name: 'Sex',
type: 'select',
options: {
Male: 'Male',
Female: 'Female',
},
options: options.Sex,
},
},
{
Expand Down
5 changes: 1 addition & 4 deletions modules/genomic_browser/jsx/tabs_content/profiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,7 @@ class Profiles extends Component {
filter: {
name: 'Sex',
type: 'select',
options: {
Male: 'Male',
Female: 'Female',
},
options: options.Sex,
},
},
{
Expand Down
5 changes: 1 addition & 4 deletions modules/genomic_browser/jsx/tabs_content/snp.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@ class SNP extends Component {
filter: {
name: 'Sex',
type: 'select',
options: {
Male: 'Male',
Female: 'Female',
},
options: options.Sex,
},
},
{
Expand Down
1 change: 1 addition & 0 deletions modules/genomic_browser/php/views/cnv.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class CNV
'Sites' => $sites,
'Cohorts' => $cohorts,
'Platform' => $platform_options,
'Sex' => \Utility::getSexList(),
];
}

Expand Down
1 change: 1 addition & 0 deletions modules/genomic_browser/php/views/methylation.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Methylation
'genotyping_platform',
'Name'
),
'Sex' => \Utility::getSexList(),
];
}

Expand Down
1 change: 1 addition & 0 deletions modules/genomic_browser/php/views/profiles.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Profiles
$this->_formElement = [
'Sites' => $sites,
'Cohorts' => $cohorts,
'Sex' => \Utility::getSexList(),
];
}

Expand Down
1 change: 1 addition & 0 deletions modules/genomic_browser/php/views/snp.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class SNP
'Sites' => $sites,
'Cohorts' => $cohorts,
'Platform' => $platform_options,
'Sex' => \Utility::getSexList(),
];
}

Expand Down
13 changes: 5 additions & 8 deletions modules/new_profile/php/new_profile.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,11 @@ class New_Profile extends \NDB_Form
$ageMin = $config->getSetting('ageMin');
$dobFormat = $config->getSetting('dobFormat');
$edc = $config->getSetting('useEDC');
$sex = [
'Male' => 'Male',
'Female' => 'Female',
'Other' => 'Other',
];
$pscidSet = "false";
$minYear = (isset($startYear, $ageMax)) ? $startYear - $ageMax : null;
$maxYear = (isset($endYear, $ageMin)) ? $endYear - $ageMin : null;
$sex = \Utility::getSexList();

$pscidSet = "false";
$minYear = (isset($startYear, $ageMax)) ? $startYear - $ageMax : null;
$maxYear = (isset($endYear, $ageMin)) ? $endYear - $ageMin : null;

// Get sites for the select dropdown
$user_list_of_sites = $user->getCenterIDs();
Expand Down
17 changes: 17 additions & 0 deletions php/libraries/Utility.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,23 @@ class Utility
return $result;
}

/**
* Returns list of sex options in the database
*
* @return array An associative array of sex values.
*/
static function getSexList(): array
{
$factory = NDB_Factory::singleton();
$DB = $factory->database();

$query = "SELECT Name FROM sex";

$result = $DB->pselectCol($query, []);

return array_combine($result, $result);
}

/**
* Returns a list of sites in the database
*
Expand Down
19 changes: 9 additions & 10 deletions src/StudyEntities/Candidate/Sex.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ class Sex implements \JsonSerializable
/* @var string */
public $value;

private const VALID_VALUES = array(
'Male',
'Female',
'Other',
);
private $validValues = [];

/**
* Calls validate() immediately.
Expand All @@ -43,10 +39,12 @@ class Sex implements \JsonSerializable
*/
public function __construct(string $value)
{
if (!self::validate($value)) {
$this->validValues = \Utility::getSexList();

if (!self::validate($value, $this->validValues)) {
throw new \DomainException(
'The value is not valid. Must be one of: '
. implode(', ', self::VALID_VALUES)
. implode(', ', array_values($this->validValues))
);
}
$this->value = $value;
Expand All @@ -55,13 +53,14 @@ public function __construct(string $value)
/**
* Ensures that the value is well-formed.
*
* @param string $value The value to be validated
* @param string $value The value to be validated
* @param array $laidValues The restricted optional values of $value
*
* @return bool True if the value format is valid
*/
public static function validate(string $value): bool
public static function validate(string $value, array $validValues): bool
{
return in_array($value, self::VALID_VALUES, true);
return in_array($value, array_values($validValues), true);
}

/**
Expand Down
Loading

0 comments on commit e2d6f04

Please sign in to comment.