// 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 // -Person1Identifier -> Person 1 Identifier // -Person2Identifier -> Person 2 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(inputPerson1Identifier string, inputPerson2Identifier string)(bool, error){ person1Identifier, person2Identifier, err := getPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier) 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{ currentPerson1Identifier, exists := coupleMap["Person1Identifier"] if (exists == false){ return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing Person1Identifier") } currentPerson2Identifier, exists := coupleMap["Person2Identifier"] if (exists == false){ return false, errors.New("MyGenomeCouplesMapList malformed: Contains entry missing Person2Identifier") } if (currentPerson1Identifier == person1Identifier && currentPerson2Identifier == person2Identifier){ return true, nil } } // Couple does not exist. We add it. newPersonMap := map[string]string{ "Person1Identifier": person1Identifier, "Person2Identifier": person2Identifier, } newCouplesMapList := append(couplesMapList, newPersonMap) err = myGenomeCouplesMapListDatastore.OverwriteMapList(newCouplesMapList) if (err != nil) { return false, err } return false, nil } func DeleteCouple(inputPerson1Identifier string, inputPerson2Identifier string)error{ person1Identifier, person2Identifier, err := getPeopleIdentifiersSortedForCouple(inputPerson1Identifier, inputPerson2Identifier) if (err != nil) { return err } updatingMyCouplesMutex.Lock() defer updatingMyCouplesMutex.Unlock() mapToDelete := map[string]string{ "Person1Identifier": person1Identifier, "Person2Identifier": person2Identifier, } err = myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDelete) if (err != nil) { return err } err = myAnalyses.DeleteAllAnalysesForCouple(person1Identifier, person2Identifier) if (err != nil) { return err } return nil } func DeleteAllCouplesForPerson(personIdentifier string)error{ updatingMyCouplesMutex.Lock() defer updatingMyCouplesMutex.Unlock() mapToDelete1 := map[string]string{ "Person1Identifier": personIdentifier, } err := myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDelete1) if (err != nil) { return err } mapToDelete2 := map[string]string{ "Person2Identifier": personIdentifier, } err = myGenomeCouplesMapListDatastore.DeleteMapListItems(mapToDelete2) 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 lookupMap1 := map[string]string{ "Person1Identifier": personIdentifier, } anyItemsFound1, matchingItemsList1, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMap1) if (err != nil){ return 0, err } if (anyItemsFound1 == true){ totalCouples += len(matchingItemsList1) } lookupMap2 := map[string]string{ "Person2Identifier": personIdentifier, } anyItemsFound2, matchingItemsList2, err := myGenomeCouplesMapListDatastore.GetMapListItems(lookupMap2) if (err != nil){ return 0, err } if (anyItemsFound2 == true){ totalCouples += len(matchingItemsList2) } 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(person1Identifier string, person2Identifier string)(string, string, error){ if (person1Identifier == person2Identifier){ return "", "", errors.New("getPeopleIdentifiersSortedForCouple called with identical person identifiers: " + person1Identifier) } if (person1Identifier < person2Identifier){ return person1Identifier, person2Identifier, nil } return person2Identifier, person1Identifier, nil }