func (p *Pipeline) findMatchingDsocialGroup(ds DataStoreService, dsocialUserId string, group *Group) (extDsocialGroup *dm.Group, isSame bool, err os.Error) { emptyGroup := new(dm.Group) if group.DsocialGroupId != "" { extDsocialGroup, _, _ = ds.RetrieveDsocialGroup(dsocialUserId, group.DsocialGroupId) if extDsocialGroup != nil { _, isSame = emptyGroup.IsSimilarOrUpdated(extDsocialGroup, group.Value) fmt.Printf("[PIPELINE]: findMatchingDsocialGroup for %s with based on existing group id will use %s and isSame %v\n", group.Value.Name, extDsocialGroup.Name, isSame) } } if extDsocialGroup == nil { // this is a new group from an existing service potentialMatches, err := ds.SearchForDsocialGroups(dsocialUserId, group.Value.Name) if err != nil { return nil, false, err } for _, potentialMatch := range potentialMatches { var isSimilar bool if isSimilar, isSame = emptyGroup.IsSimilarOrUpdated(potentialMatch, group.Value); isSimilar { extDsocialGroup = potentialMatch break } } if extDsocialGroup != nil { fmt.Printf("[PIPELINE]: findMatchingDsocialGroup for %s was %s and isSame %v\n\tStoring mapping: %s/%s/%s -> %s\n", group.Value.Name, extDsocialGroup.Name, isSame, group.ExternalServiceId, group.ExternalUserId, group.ExternalGroupId, extDsocialGroup.Id) _, _, err = ds.StoreDsocialExternalGroupMapping(group.ExternalServiceId, group.ExternalUserId, group.ExternalGroupId, dsocialUserId, extDsocialGroup.Id) group.DsocialGroupId = extDsocialGroup.Id } else { fmt.Printf("[PIPELINE]: findMatchingDsocialGroup cannot find similar for %s\n", group.Value.Name) } } return extDsocialGroup, isSame, err }
func AddIdsForDsocialGroup(g *dm.Group, ds DataStoreService, dsocialUserId string) (err os.Error) { if g == nil { return } if g.UserId == "" { g.UserId = dsocialUserId } if g.Acl.OwnerId == "" { g.Acl.OwnerId = dsocialUserId } if g.Id == "" { g.Id = ds.GenerateId(dsocialUserId, "group") } return }
// Stores dsocial group // Returns: // dsocialGroup : the group, modified to include items like Id and LastModified/Created // err : error or nil func (p *InMemoryDataStore) StoreDsocialGroupForExternalGroup(externalServiceId, externalUserId, externalGroupId, dsocialUserId string, group *dm.Group) (dsocialGroup *dm.Group, err os.Error) { //k := strings.Join([]string{dsocialUserId, externalServiceId, externalUserId, externalGroupId}, "/") k := strings.Join([]string{externalServiceId, externalUserId, externalGroupId}, "|") if externalServiceId == "" || externalUserId == "" || externalGroupId == "" { panic(fmt.Sprintf("One of the following three strings are empty: externalServiceId: %s, externalUserId: %s, externalGroupId: %s\n", externalServiceId, externalUserId, externalGroupId)) } else if strings.Contains(externalServiceId, "|") || strings.Contains(externalUserId, "|") || strings.Contains(externalGroupId, "|") { panic(fmt.Sprintf("One of the following three strings contain pipe character: externalServiceId: %s, externalUserId: %s, externalGroupId: %s\n", externalServiceId, externalUserId, externalGroupId)) } extid := dsocialUserId + "/" + k bc.AddIdsForDsocialGroup(group, p, dsocialUserId) g := new(dm.Group) *g = *group g.Id = extid fmt.Printf("[DS]: Storing %s with id %v for %s\n", _INMEMORY_GROUP_FOR_EXTERNAL_GROUP_COLLECTION_NAME, extid, g.Name) p.store(dsocialUserId, _INMEMORY_GROUP_FOR_EXTERNAL_GROUP_COLLECTION_NAME, extid, g) dsocialGroup = group return }
// Stores dsocial group // Returns: // dsocialGroup : the group, modified to include items like Id and LastModified/Created // err : error or nil func (p *InMemoryDataStore) StoreDsocialGroup(dsocialUserId, dsocialGroupId string, group *dm.Group) (dsocialGroup *dm.Group, err os.Error) { if dsocialGroupId == "" { dsocialGroupId = p.GenerateId(dsocialUserId, "group") fmt.Printf("[DS]: Generated Id for storing dsocial group: %v\n", dsocialGroupId) group.Id = dsocialGroupId } else { fmt.Printf("[DS]: Using existing group id: %v\n", dsocialGroupId) } //k := strings.Join([]string{dsocialUserId, dsocialGroupId}, "/") g := new(dm.Group) *g = *group p.store(dsocialUserId, _INMEMORY_GROUP_COLLECTION_NAME, dsocialGroupId, g) dsocialGroup = group return }
func (p *Pipeline) groupImport(cs ContactsService, ds DataStoreService, dsocialUserId string, group *Group, minimumIncludes *list.List, allowAdd, allowDelete, allowUpdate bool) (*dm.Group, string, os.Error) { emptyGroup := new(dm.Group) if group == nil || group.Value == nil { return nil, "", nil } //fmt.Printf("[PIPELINE]: Syncing group: %s\n", group.Value.Name) if group.Value.ContactIds == nil { group.Value.ContactIds = make([]string, 0, 10) } if group.Value.ContactNames == nil { group.Value.ContactNames = make([]string, 0, 10) } if len(group.Value.ContactIds) == 0 && len(group.Value.ContactNames) == 0 && minimumIncludes != nil { sv1 := vector.StringVector(group.Value.ContactIds) sv2 := vector.StringVector(group.Value.ContactNames) sv1.Resize(sv1.Len(), sv1.Len()+minimumIncludes.Len()) sv2.Resize(sv2.Len(), sv2.Len()+minimumIncludes.Len()) for iter := minimumIncludes.Front(); iter != nil; iter = iter.Next() { contactRef := iter.Value.(*dm.ContactRef) sv1.Push(contactRef.Id) sv2.Push(contactRef.Name) } } else if minimumIncludes != nil { for iter := minimumIncludes.Front(); iter != nil; iter = iter.Next() { contactRef := iter.Value.(*dm.ContactRef) refLocation := -1 if contactRef.Id != "" { for i, id := range group.Value.ContactIds { if id == contactRef.Id { refLocation = i break } } } if refLocation == -1 && contactRef.Name != "" { for i, name := range group.Value.ContactNames { if name == contactRef.Name { refLocation = i break } } } if refLocation == -1 { sv1 := vector.StringVector(group.Value.ContactIds) sv2 := vector.StringVector(group.Value.ContactNames) sv1.Push(contactRef.Id) sv2.Push(contactRef.Name) } else { group.Value.ContactIds[refLocation] = contactRef.Id group.Value.ContactNames[refLocation] = contactRef.Name } } } extDsocialGroup, _, err := ds.RetrieveDsocialGroupForExternalGroup(group.ExternalServiceId, group.ExternalUserId, group.ExternalGroupId, dsocialUserId) if err != nil { return nil, "", err } var matchingGroup *dm.Group var isSame bool if extDsocialGroup == nil { // We don't have a mapping for this external group to an internal group mapping // meaning we've never imported this group previously from THIS service, but we may // already have the group in our system, so let's see if we can find it matchingGroup, isSame, err = p.findMatchingDsocialGroup(ds, dsocialUserId, group) if err != nil { return matchingGroup, "", err } if matchingGroup != nil { group.DsocialGroupId = matchingGroup.Id extGroup := cs.ConvertToExternalGroup(matchingGroup, nil, dsocialUserId) ds.StoreExternalGroup(group.ExternalServiceId, group.ExternalUserId, dsocialUserId, group.ExternalGroupId, extGroup) extDsocialGroup = cs.ConvertToDsocialGroup(extGroup, matchingGroup, dsocialUserId) if extDsocialGroup != nil { AddIdsForDsocialGroup(extDsocialGroup, ds, dsocialUserId) fmt.Printf("[PIPELINE]: groupImport() before store dsoc group ExternalGroupId: %v and extDsocialGroup.Id %v matchingGroup.Id %v\n", group.ExternalGroupId, extDsocialGroup.Id, matchingGroup.Id) //group.ExternalGroupId = extDsocialGroup.Id //extDsocialGroup.Id = group.DsocialGroupId extDsocialGroup, err = ds.StoreDsocialGroupForExternalGroup(group.ExternalServiceId, group.ExternalUserId, group.ExternalGroupId, dsocialUserId, extDsocialGroup) if extDsocialGroup == nil || err != nil { return matchingGroup, "", err } //extDsocialGroup.Id = group.DsocialGroupId fmt.Printf("[PIPELINE]: groupImport() before store mapping ExternalGroupId: %v and DsocialGroupId %v\n", group.ExternalGroupId, group.DsocialGroupId) if _, _, err = ds.StoreDsocialExternalGroupMapping(group.ExternalServiceId, group.ExternalUserId, group.ExternalGroupId, dsocialUserId, group.DsocialGroupId); err != nil { return matchingGroup, "", err } } } } else { // we have a mapping for this external group to an internal group mapping // from THIS service, therefore let's use it if group.DsocialGroupId == "" { group.DsocialGroupId, err = ds.DsocialIdForExternalGroupId(group.ExternalServiceId, group.ExternalUserId, dsocialUserId, group.ExternalGroupId) if err != nil { return nil, "", err } } if group.DsocialGroupId != "" { matchingGroup, _, err = ds.RetrieveDsocialGroup(dsocialUserId, group.DsocialGroupId) if err != nil { return nil, "", err } } } // ensure we have a contact Id if group.DsocialGroupId == "" { if matchingGroup != nil { group.DsocialGroupId = matchingGroup.Id fmt.Printf("[PIPELINE]: Will be using matchingGroup Id: %v\n", matchingGroup.Id) } if group.DsocialGroupId == "" { newGroup := &dm.Group{UserId: dsocialUserId} AddIdsForDsocialGroup(newGroup, ds, dsocialUserId) thegroup, err := ds.StoreDsocialGroup(dsocialUserId, newGroup.Id, newGroup) if err != nil { return nil, "", err } group.DsocialGroupId = thegroup.Id } } if _, isSame = emptyGroup.IsSimilarOrUpdated(extDsocialGroup, group.Value); isSame { return matchingGroup, "", nil } l := new(list.List) emptyGroup.GenerateChanges(extDsocialGroup, group.Value, nil, l) l = p.removeUnacceptedChanges(l, allowAdd, allowDelete, allowUpdate) changes := make([]*dm.Change, l.Len()) for i, iter := 0, l.Front(); iter != nil; i, iter = i+1, iter.Next() { changes[i] = iter.Value.(*dm.Change) } changeset := &dm.ChangeSet{ CreatedAt: time.UTC().Format(dm.UTC_DATETIME_FORMAT), ChangedBy: group.ExternalServiceId, ChangeImportId: group.ExternalGroupId, RecordId: group.DsocialGroupId, Changes: changes, } _, err = ds.StoreGroupChangeSet(dsocialUserId, changeset) if err != nil { return matchingGroup, changeset.Id, nil } if extDsocialGroup == nil { fmt.Printf("[PIPELINE]: OriginalExternalGroup is nil and group.DsocialGroupId is %v and group.Value.Id was %v\n", group.DsocialGroupId, group.Value.Id) group.Value.Id = group.DsocialGroupId AddIdsForDsocialGroup(group.Value, ds, dsocialUserId) group.Value, err = ds.StoreDsocialGroup(dsocialUserId, group.DsocialGroupId, group.Value) if err != nil { return matchingGroup, changeset.Id, err } storedDsocialGroup, err := ds.StoreDsocialGroupForExternalGroup(group.ExternalServiceId, group.ExternalUserId, group.ExternalGroupId, dsocialUserId, group.Value) _, _, err2 := ds.StoreDsocialExternalGroupMapping(group.ExternalServiceId, group.ExternalUserId, group.ExternalGroupId, dsocialUserId, group.DsocialGroupId) if err == nil { err = err2 } return storedDsocialGroup, changeset.Id, err } var storedDsocialGroup *dm.Group = nil if group.DsocialGroupId != "" { if storedDsocialGroup, _, err = ds.RetrieveDsocialGroup(dsocialUserId, group.DsocialGroupId); err != nil { return matchingGroup, changeset.Id, err } } if storedDsocialGroup == nil { storedDsocialGroup = new(dm.Group) } for j, iter := 0, l.Front(); iter != nil; j, iter = j+1, iter.Next() { change := iter.Value.(*dm.Change) dm.ApplyChange(storedDsocialGroup, change) changes[j] = change } AddIdsForDsocialGroup(storedDsocialGroup, ds, dsocialUserId) _, err = ds.StoreDsocialGroup(dsocialUserId, group.DsocialGroupId, storedDsocialGroup) return storedDsocialGroup, changeset.Id, err }