seekia/internal/genetics/myCouples/myCouples.go

178 lines
5.1 KiB
Go

// myCouples provides functions to manage a user's genome couples
// A couple is recorded as 2 person identifiers.
package myCouples
import "seekia/internal/myDatastores/myMapList"
import "seekia/internal/genetics/myAnalyses"
import "sync"
import "errors"
// This will be locked anytime Couples are being added/deleted
var updatingMyCouplesMutex sync.Mutex
var myGenomeCouplesMapListDatastore *myMapList.MyMapList
// This function must be called whenever an app user signs in
func InitializeMyGenomeCouplesDatastore()error{
updatingMyCouplesMutex.Lock()
defer updatingMyCouplesMutex.Unlock()
newMyGenomeCouplesMapListDatastore, err := myMapList.CreateNewMapList("MyGenomeCouples")
if (err != nil) { return err }
myGenomeCouplesMapListDatastore = newMyGenomeCouplesMapListDatastore
return nil
}
//Outputs:
// -[]map[string]string
// -PersonAIdentifier -> Person A Identifier
// -PersonBIdentifier -> Person B Identifier
// -error
func GetMyGenomeCouplesMapList()([]map[string]string, error){
couplesMapList, err := myGenomeCouplesMapListDatastore.GetMapList()
if (err != nil) { return nil, err }
return couplesMapList, nil
}
//Outputs:
// -bool: Couple already exists
// -error
func AddCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)(bool, error){
personAIdentifier, personBIdentifier, err := getPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
if (err != nil) { return false, err }
updatingMyCouplesMutex.Lock()
defer updatingMyCouplesMutex.Unlock()
couplesMapList, err := myGenomeCouplesMapListDatastore.GetMapList()
if (err != nil) { return false, err }
for _, coupleMap := range couplesMapList{
currentPersonAIdentifier, exists := coupleMap["PersonAIdentifier"]
if (exists == false){
return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing PersonAIdentifier")
}
currentPersonBIdentifier, exists := coupleMap["PersonBIdentifier"]
if (exists == false){
return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing PersonBIdentifier")
}
if (currentPersonAIdentifier == personAIdentifier && currentPersonBIdentifier == personBIdentifier){
return true, nil
}
}
// Couple does not exist. We add it.
newPersonMap := map[string]string{
"PersonAIdentifier": personAIdentifier,
"PersonBIdentifier": personBIdentifier,
}
newCouplesMapList := append(couplesMapList, newPersonMap)
err = myGenomeCouplesMapListDatastore.OverwriteMapList(newCouplesMapList)
if (err != nil) { return false, err }
return false, nil
}
func DeleteCouple(inputPersonAIdentifier string, inputPersonBIdentifier string)error{
personAIdentifier, personBIdentifier, err := getPeopleIdentifiersSortedForCouple(inputPersonAIdentifier, inputPersonBIdentifier)
if (err != nil) { return err }
updatingMyCouplesMutex.Lock()
defer updatingMyCouplesMutex.Unlock()
mapToDelete := map[string]string{
"PersonAIdentifier": personAIdentifier,
"PersonBIdentifier": personBIdentifier,
}
err = myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDelete)
if (err != nil) { return err }
err = myAnalyses.DeleteAllAnalysesForCouple(personAIdentifier, personBIdentifier)
if (err != nil) { return err }
return nil
}
func DeleteAllCouplesForPerson(personIdentifier string)error{
updatingMyCouplesMutex.Lock()
defer updatingMyCouplesMutex.Unlock()
mapToDeleteA := map[string]string{
"PersonAIdentifier": personIdentifier,
}
err := myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDeleteA)
if (err != nil) { return err }
mapToDeleteB := map[string]string{
"PersonBIdentifier": personIdentifier,
}
err = myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDeleteB)
if (err != nil) { return err }
return nil
}
// This is used to show how many couples will be deleted if a user is deleting a person.
func GetNumberOfCouplesForPerson(personIdentifier string)(int, error){
totalCouples := 0
lookupMapA := map[string]string{
"PersonAIdentifier": personIdentifier,
}
anyItemsFoundA, matchingItemsListA, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMapA)
if (err != nil){ return 0, err }
if (anyItemsFoundA == true){
totalCouples += len(matchingItemsListA)
}
lookupMapB := map[string]string{
"PersonBIdentifier": personIdentifier,
}
anyItemsFoundB, matchingItemsListB, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMapB)
if (err != nil){ return 0, err }
if (anyItemsFoundB == true){
totalCouples += len(matchingItemsListB)
}
return totalCouples, nil
}
// This function is used to sort the person identifiers, so that each pair of identifiers will always map to the same couple when added
// The sorting method has no significance
func getPeopleIdentifiersSortedForCouple(personAIdentifier string, personBIdentifier string)(string, string, error){
if (personAIdentifier == personBIdentifier){
return "", "", errors.New("getPeopleIdentifiersSortedForCouple called with identical person identifiers: " + personAIdentifier)
}
if (personAIdentifier < personBIdentifier){
return personAIdentifier, personBIdentifier, nil
}
return personBIdentifier, personAIdentifier, nil
}