283 lines
8.2 KiB
Go
283 lines
8.2 KiB
Go
|
|
// myPeople provides functions to manage a user's genome people
|
|
// Each person can have many genomes and a genetic analysis
|
|
// Each person's genomes are stored in myGenomes
|
|
// This package stores each person's identifier, name, sex, and createdTime
|
|
|
|
package myPeople
|
|
|
|
import "seekia/internal/myDatastores/myMapList"
|
|
import "seekia/internal/helpers"
|
|
import "seekia/internal/genetics/myGenomes"
|
|
import "seekia/internal/genetics/myCouples"
|
|
import "seekia/internal/genetics/myAnalyses"
|
|
|
|
import "time"
|
|
import "sync"
|
|
import "errors"
|
|
|
|
// This will be locked anytime People are being added/deleted
|
|
var updatingMyPeopleMutex sync.Mutex
|
|
|
|
var myGenomePeopleMapListDatastore *myMapList.MyMapList
|
|
|
|
// This function must be called whenever an app user signs in
|
|
func InitializeMyGenomePeopleDatastore()error{
|
|
|
|
updatingMyPeopleMutex.Lock()
|
|
defer updatingMyPeopleMutex.Unlock()
|
|
|
|
newMyGenomePeopleMapListDatastore, err := myMapList.CreateNewMapList("MyGenomePeople")
|
|
if (err != nil) { return err }
|
|
|
|
myGenomePeopleMapListDatastore = newMyGenomePeopleMapListDatastore
|
|
|
|
return nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -[]map[string]string
|
|
// -PersonIdentifier -> Person Identifier
|
|
// -PersonName -> Person Name
|
|
// -CreatedTime -> Time the person was created
|
|
// -error
|
|
func GetMyGenomePeopleMapList()([]map[string]string, error){
|
|
|
|
peopleMapList, err := myGenomePeopleMapListDatastore.GetMapList()
|
|
if (err != nil) { return nil, err }
|
|
|
|
return peopleMapList, nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Person with this name already exists
|
|
// -error
|
|
func AddPerson(personName string, personSex string)(bool, error){
|
|
|
|
if (personName == ""){
|
|
return false, errors.New("AddPerson called with empty personName")
|
|
}
|
|
if (personSex != "Male" && personSex != "Female" && personSex != "Intersex"){
|
|
return false, errors.New("AddPerson called with invalid personSex: " + personSex)
|
|
}
|
|
|
|
personIdentifier, err := helpers.GetNewRandomHexString(15)
|
|
if (err != nil) { return false, err }
|
|
|
|
createdTime := time.Now().Unix()
|
|
createdTimeString := helpers.ConvertInt64ToString(createdTime)
|
|
|
|
updatingMyPeopleMutex.Lock()
|
|
defer updatingMyPeopleMutex.Unlock()
|
|
|
|
lookupMap := map[string]string{
|
|
"PersonName": personName,
|
|
}
|
|
|
|
anyExist, _, err := myGenomePeopleMapListDatastore.GetMapListItems(lookupMap)
|
|
if (err != nil) { return false, err }
|
|
if (anyExist == true){
|
|
return true, nil
|
|
}
|
|
|
|
peopleMapList, err := myGenomePeopleMapListDatastore.GetMapList()
|
|
if (err != nil) { return false, err }
|
|
|
|
newPersonMap := map[string]string{
|
|
"PersonIdentifier": personIdentifier,
|
|
"PersonName": personName,
|
|
"CreatedTime": createdTimeString,
|
|
"PersonSex": personSex,
|
|
}
|
|
|
|
newPeopleMapList := append(peopleMapList, newPersonMap)
|
|
|
|
err = myGenomePeopleMapListDatastore.OverwriteMapList(newPeopleMapList)
|
|
if (err != nil) { return false, err }
|
|
|
|
return false, nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Person with this name already exists
|
|
// -error
|
|
func EditPerson(personIdentifier string, newPersonName string, newPersonSex string)(bool, error){
|
|
|
|
if (newPersonName == ""){
|
|
return false, errors.New("EditPerson called with empty newPersonName")
|
|
}
|
|
if (newPersonSex != "Male" && newPersonSex != "Female" && newPersonSex != "Intersex"){
|
|
return false, errors.New("EditPerson called with invalid newPersonSex: " + newPersonSex)
|
|
}
|
|
|
|
updatingMyPeopleMutex.Lock()
|
|
defer updatingMyPeopleMutex.Unlock()
|
|
|
|
lookupMap := map[string]string{
|
|
"PersonName": newPersonName,
|
|
}
|
|
|
|
anyExist, _, err := myGenomePeopleMapListDatastore.GetMapListItems(lookupMap)
|
|
if (err != nil) { return false, err }
|
|
if (anyExist == true){
|
|
// Someone else already has this name
|
|
return true, nil
|
|
}
|
|
|
|
peopleMapList, err := myGenomePeopleMapListDatastore.GetMapList()
|
|
if (err != nil) { return false, err }
|
|
|
|
for _, personMap := range peopleMapList{
|
|
|
|
currentPersonIdentifier, exists := personMap["PersonIdentifier"]
|
|
if (exists == false){
|
|
return false, errors.New("MyGenomePeopleMapList malformed: contains entry missing PersonIdentifier")
|
|
}
|
|
|
|
if (currentPersonIdentifier == personIdentifier){
|
|
|
|
personMap["PersonName"] = newPersonName
|
|
personMap["PersonSex"] = newPersonSex
|
|
}
|
|
}
|
|
|
|
err = myGenomePeopleMapListDatastore.OverwriteMapList(peopleMapList)
|
|
if (err != nil) { return false, err }
|
|
|
|
return false, nil
|
|
}
|
|
|
|
// This function will delete the person, any couples with the person, and all of the person's genomes
|
|
func DeletePerson(personIdentifier string)error{
|
|
|
|
updatingMyPeopleMutex.Lock()
|
|
defer updatingMyPeopleMutex.Unlock()
|
|
|
|
err := myGenomes.DeleteAllPersonGenomes(personIdentifier)
|
|
if (err != nil) { return err }
|
|
|
|
err = myCouples.DeleteAllCouplesForPerson(personIdentifier)
|
|
if (err != nil) { return err }
|
|
|
|
mapToDelete := map[string]string{
|
|
"PersonIdentifier": personIdentifier,
|
|
}
|
|
|
|
err = myGenomePeopleMapListDatastore.DeleteMapListItems(mapToDelete)
|
|
if (err != nil) { return err }
|
|
|
|
err = myAnalyses.DeleteAllAnalysesForPerson(personIdentifier)
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Person found
|
|
// -string: Person name
|
|
// -int64: Created time
|
|
// -string: Sex ("Male"/"Female"/"Intersex")
|
|
// -error
|
|
func GetPersonInfo(personIdentifier string)(bool, string, int64, string, error){
|
|
|
|
if (personIdentifier == "111111111111111111111111111111" || personIdentifier == "222222222222222222222222222222"){
|
|
// These are the identifiers we use for sample analyses
|
|
// These are analyses the user can view if they want to see what an analysis will look like
|
|
|
|
getPersonName := func()string{
|
|
if (personIdentifier == "111111111111111111111111111111"){
|
|
return "Person A"
|
|
}
|
|
return "Person B"
|
|
}
|
|
|
|
personName := getPersonName()
|
|
|
|
currentTime := time.Now().Unix()
|
|
|
|
getPersonSex := func()string{
|
|
if (personIdentifier == "111111111111111111111111111111"){
|
|
return "Male"
|
|
}
|
|
return "Female"
|
|
}
|
|
|
|
personSex := getPersonSex()
|
|
|
|
return true, personName, currentTime, personSex, nil
|
|
}
|
|
|
|
lookupMap := map[string]string{
|
|
"PersonIdentifier": personIdentifier,
|
|
}
|
|
|
|
anyItemFound, retrievedItemsList, err := myGenomePeopleMapListDatastore.GetMapListItems(lookupMap)
|
|
if (err != nil) { return false, "", 0, "", err }
|
|
if (anyItemFound == false){
|
|
return false, "", 0, "", nil
|
|
}
|
|
if (len(retrievedItemsList) != 1){
|
|
return false, "", 0, "", errors.New("myGenomePeopleMapList malformed: Multiple entries exist for 1 person")
|
|
}
|
|
|
|
personMap := retrievedItemsList[0]
|
|
|
|
createdTime, exists := personMap["CreatedTime"]
|
|
if (exists == false) {
|
|
return false, "", 0, "", errors.New("myGenomePeopleMapList malformed: Entry missing CreatedTime")
|
|
}
|
|
|
|
createdTimeInt64, err := helpers.ConvertStringToInt64(createdTime)
|
|
if (err != nil) {
|
|
return false, "", 0, "", errors.New("myGenomePeopleMapList malformed: Invalid CreatedTime: " + createdTime)
|
|
}
|
|
|
|
personName, exists := personMap["PersonName"]
|
|
if (exists == false) {
|
|
return false, "", 0, "", errors.New("myGenomePeopleMapList malformed: Entry missing PersonName")
|
|
}
|
|
|
|
personSex, exists := personMap["PersonSex"]
|
|
if (exists == false) {
|
|
return false, "", 0, "", errors.New("myGenomePeopleMapList malformed: Entry missing PersonSex")
|
|
}
|
|
|
|
return true, personName, createdTimeInt64, personSex, nil
|
|
}
|
|
|
|
|
|
// This will return true if a person's analysis is ready
|
|
// This means it was created with all of the person's genomes using the newest available analysis version
|
|
// Outputs:
|
|
// -bool: Any Genomes exist
|
|
// -bool: Person analysis is ready
|
|
// -string: Newest ready person genetic analysis
|
|
// -error
|
|
func CheckIfPersonAnalysisIsReady(personIdentifier string)(bool, bool, string, error){
|
|
|
|
allPersonRawGenomeIdentifiersList, err := myGenomes.GetAllPersonRawGenomeIdentifiersList(personIdentifier)
|
|
if (err != nil){ return false, false, "", err }
|
|
if (len(allPersonRawGenomeIdentifiersList) == 0){
|
|
return false, false, "", nil
|
|
}
|
|
|
|
anyAnalysisFound, newestAnalysisIdentifier, _, newestAnalysisListOfGenomesAnalyzed, newerAnalysisVersionAvailable, err := myAnalyses.GetPersonNewestGeneticAnalysisInfo(personIdentifier)
|
|
if (err != nil){ return false, false, "", err }
|
|
if (anyAnalysisFound == false){
|
|
return true, false, "", nil
|
|
}
|
|
if (newerAnalysisVersionAvailable == true){
|
|
return true, false, "", nil
|
|
}
|
|
|
|
genomesAreIdentical := helpers.CheckIfTwoListsContainIdenticalItems(allPersonRawGenomeIdentifiersList, newestAnalysisListOfGenomesAnalyzed)
|
|
if (genomesAreIdentical == false){
|
|
// A newer genome has been added
|
|
return true, false, "", nil
|
|
}
|
|
|
|
return true, true, newestAnalysisIdentifier, nil
|
|
}
|
|
|
|
|
|
|