// 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 }