func (p *Pipeline) findMatchingDsocialContact(ds DataStoreService, dsocialUserId string, contact *Contact) (extDsocialContact *dm.Contact, isSame bool, err os.Error) { emptyContact := new(dm.Contact) if contact.DsocialContactId != "" { extDsocialContact, _, _ = ds.RetrieveDsocialContact(dsocialUserId, contact.DsocialContactId) if extDsocialContact != nil { _, isSame = emptyContact.IsSimilarOrUpdated(extDsocialContact, contact.Value) fmt.Printf("[PIPELINE]: findMatchingDsocialContact for %s with based on existing contact id will use %s and isSame %v\n", contact.Value.DisplayName, extDsocialContact.DisplayName, isSame) } } if extDsocialContact == nil { // this is a new contact from an existing service potentialMatches, err := ds.SearchForDsocialContacts(dsocialUserId, contact.Value) if err != nil { return nil, false, err } for _, potentialMatch := range potentialMatches { var isSimilar bool if isSimilar, isSame = emptyContact.IsSimilarOrUpdated(potentialMatch, contact.Value); isSimilar { extDsocialContact = potentialMatch break } } if extDsocialContact != nil { fmt.Printf("[PIPELINE]: findMatchingDsocialContact for %s was %s and isSame %v\n\tStoring mapping: %s/%s/%s -> %s\n", contact.Value.DisplayName, extDsocialContact.DisplayName, isSame, contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, extDsocialContact.Id) _, _, err = ds.StoreDsocialExternalContactMapping(contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, dsocialUserId, extDsocialContact.Id) contact.DsocialContactId = extDsocialContact.Id } else { fmt.Printf("[PIPELINE]: findMatchingDsocialContact cannot find similar for %s\n", contact.Value.DisplayName) } } return extDsocialContact, isSame, err }
// Stores dsocial contact // Returns: // dsocialContact : the contact, modified to include items like Id and LastModified/Created // err : error or nil func (p *InMemoryDataStore) StoreDsocialContactForExternalContact(externalServiceId, externalUserId, externalContactId, dsocialUserId string, contact *dm.Contact) (dsocialContact *dm.Contact, err os.Error) { //k := strings.Join([]string{dsocialUserId, externalServiceId, externalUserId, externalContactId}, "/") k := strings.Join([]string{externalServiceId, externalUserId, externalContactId}, "|") if externalServiceId == "" || externalUserId == "" || externalContactId == "" { panic(fmt.Sprintf("One of the following three strings are empty: externalServiceId: %s, externalUserId: %s, externalContactId: %s\n", externalServiceId, externalUserId, externalContactId)) } else if strings.Contains(externalServiceId, "|") || strings.Contains(externalUserId, "|") || strings.Contains(externalContactId, "|") { panic(fmt.Sprintf("One of the following three strings contain pipe character: externalServiceId: %s, externalUserId: %s, externalContactId: %s\n", externalServiceId, externalUserId, externalContactId)) } extid := dsocialUserId + "/" + k bc.AddIdsForDsocialContact(contact, p, dsocialUserId) c := new(dm.Contact) *c = *contact c.Id = extid p.store(dsocialUserId, _INMEMORY_CONTACT_FOR_EXTERNAL_CONTACT_COLLECTION_NAME, extid, c) dsocialContact = contact return }
func (p *InMemoryDataStore) SearchForDsocialContacts(dsocialUserId string, contact *dm.Contact) (contacts []*dm.Contact, err os.Error) { if contact == nil { return make([]*dm.Contact, 0), nil } collection := p.retrieveContactCollection() l := list.New() for _, v := range collection.Data { if c, ok := v.(*dm.Contact); ok && c != nil { if isSimilar, _ := contact.IsSimilarOrUpdated(contact, c); isSimilar { c2 := new(dm.Contact) *c2 = *c l.PushBack(c2) } } } rc := make([]*dm.Contact, l.Len()) for i, iter := 0, l.Front(); iter != nil; i, iter = i+1, iter.Next() { if iter.Value != nil { rc[i] = iter.Value.(*dm.Contact) } } return rc, nil }
// Stores dsocial contact // Returns: // dsocialContact : the contact, modified to include items like Id and LastModified/Created // err : error or nil func (p *InMemoryDataStore) StoreDsocialContact(dsocialUserId, dsocialContactId string, contact *dm.Contact) (dsocialContact *dm.Contact, err os.Error) { if dsocialContactId == "" { dsocialContactId = p.GenerateId(dsocialUserId, "contact") fmt.Printf("[DS]: Generated Id for storing dsocial contact: %v\n", dsocialContactId) contact.Id = dsocialContactId } else { fmt.Printf("[DS]: Using existing contact id: %v\n", dsocialContactId) } bc.AddIdsForDsocialContact(contact, p, dsocialUserId) //k := strings.Join([]string{dsocialUserId, dsocialContactId}, "/") c := new(dm.Contact) *c = *contact p.store(dsocialUserId, _INMEMORY_CONTACT_COLLECTION_NAME, dsocialContactId, c) dsocialContact = contact return }
func (p *Pipeline) contactImport(cs ContactsService, ds DataStoreService, dsocialUserId string, contact *Contact, allowAdd, allowDelete, allowUpdate bool) (*dm.Contact, string, os.Error) { emptyContact := new(dm.Contact) if contact == nil || contact.Value == nil { return nil, "", nil } fmt.Printf("[PIPELINE]: Importing contact with ExternalServiceId = %v, ExternalUserId = %v, ExternalContactId = %v, DsocialUserId = %v, DsocialContactId = %v\n", contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, contact.DsocialUserId, contact.DsocialContactId) extDsocialContact, _, err := ds.RetrieveDsocialContactForExternalContact(contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, dsocialUserId) if err != nil { return nil, "", err } var matchingContact *dm.Contact var isSame bool if extDsocialContact == nil { // We don't have a mapping for this external contact to an internal contact mapping // meaning we've never imported this contact previously from THIS service, but we may // already have the contact in our system, so let's see if we can find it matchingContact, isSame, err = p.findMatchingDsocialContact(ds, dsocialUserId, contact) if err != nil { return matchingContact, "", err } if matchingContact != nil { contact.DsocialContactId = matchingContact.Id extContact := cs.ConvertToExternalContact(matchingContact, nil, dsocialUserId) ds.StoreExternalContact(contact.ExternalServiceId, contact.ExternalUserId, dsocialUserId, contact.ExternalContactId, extContact) extDsocialContact = cs.ConvertToDsocialContact(extContact, matchingContact, dsocialUserId) if extDsocialContact != nil { AddIdsForDsocialContact(extDsocialContact, ds, dsocialUserId) //contact.ExternalContactId = extDsocialContact.Id extDsocialContact, err = ds.StoreDsocialContactForExternalContact(contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, dsocialUserId, extDsocialContact) if extDsocialContact == nil || err != nil { return matchingContact, "", err } if contact.DsocialContactId != "" { if _, _, err = ds.StoreDsocialExternalContactMapping(contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, dsocialUserId, contact.DsocialContactId); err != nil { return matchingContact, "", err } } } } } else { // we have a mapping for this external contact to an internal contact mapping // from THIS service, therefore let's use it if contact.DsocialContactId == "" { contact.DsocialContactId, err = ds.DsocialIdForExternalContactId(contact.ExternalServiceId, contact.ExternalUserId, dsocialUserId, contact.ExternalContactId) if err != nil { return nil, "", err } } if contact.DsocialContactId != "" { matchingContact, _, err = ds.RetrieveDsocialContact(dsocialUserId, contact.DsocialContactId) if err != nil { return nil, "", err } } } // ensure we have a contact Id if contact.DsocialContactId == "" { if matchingContact != nil { contact.DsocialContactId = matchingContact.Id fmt.Printf("[PIPELINE]: Will be using matchingContact Id: %v\n", matchingContact.Id) } if contact.DsocialContactId == "" { newContact := &dm.Contact{UserId: dsocialUserId} AddIdsForDsocialContact(newContact, ds, dsocialUserId) thecontact, err := ds.StoreDsocialContact(dsocialUserId, newContact.Id, newContact) if err != nil { return nil, "", err } contact.DsocialContactId = thecontact.Id } } if _, isSame = emptyContact.IsSimilarOrUpdated(extDsocialContact, contact.Value); isSame { return matchingContact, "", nil } l := new(list.List) emptyContact.GenerateChanges(extDsocialContact, contact.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: contact.ExternalServiceId, ChangeImportId: contact.ExternalContactId, RecordId: contact.DsocialContactId, Changes: changes, } _, err = ds.StoreContactChangeSet(dsocialUserId, changeset) if err != nil { return matchingContact, changeset.Id, err } if extDsocialContact == nil { fmt.Printf("[PIPELINE]: OriginalExternalContact is nil and contact.DsocialContactId is %v and contact.Value.Id was %v\n", contact.DsocialContactId, contact.Value.Id) contact.Value.Id = contact.DsocialContactId AddIdsForDsocialContact(contact.Value, ds, dsocialUserId) contact.Value, err = ds.StoreDsocialContact(dsocialUserId, contact.DsocialContactId, contact.Value) fmt.Printf("[PIPELINE]: After storing contact.Value, contact.Value.Id is %v\n", contact.Value.Id) if err != nil { return matchingContact, changeset.Id, err } storedDsocialContact, err := ds.StoreDsocialContactForExternalContact(contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, dsocialUserId, contact.Value) fmt.Printf("[PIPELINE]: After storing external contact, contact.Value.Id is %v\n", contact.Value.Id) _, _, err2 := ds.StoreDsocialExternalContactMapping(contact.ExternalServiceId, contact.ExternalUserId, contact.ExternalContactId, dsocialUserId, contact.DsocialContactId) if err == nil { err = err2 } return storedDsocialContact, changeset.Id, err } var storedDsocialContact *dm.Contact = nil if contact.DsocialContactId != "" { if storedDsocialContact, _, err = ds.RetrieveDsocialContact(dsocialUserId, contact.DsocialContactId); err != nil { return matchingContact, changeset.Id, err } } if storedDsocialContact == nil { storedDsocialContact = new(dm.Contact) } for j, iter := 0, l.Front(); iter != nil; j, iter = j+1, iter.Next() { change := iter.Value.(*dm.Change) dm.ApplyChange(storedDsocialContact, change) changes[j] = change } AddIdsForDsocialContact(storedDsocialContact, ds, dsocialUserId) _, err = ds.StoreDsocialContact(dsocialUserId, contact.DsocialContactId, storedDsocialContact) return storedDsocialContact, changeset.Id, err }
func AddIdsForDsocialContact(c *dm.Contact, ds DataStoreService, dsocialUserId string) (err os.Error) { if c == nil { return } if c.UserId == "" { c.UserId = dsocialUserId } if c.Acl.OwnerId == "" { c.Acl.OwnerId = dsocialUserId } if c.Id == "" { c.Id = ds.GenerateId(dsocialUserId, "contact") } if c.PostalAddresses != nil { for _, addr := range c.PostalAddresses { if addr.Acl.OwnerId == "" { addr.Acl.OwnerId = dsocialUserId } if addr.Id == "" { addr.Id = ds.GenerateId(dsocialUserId, "address") } } } if c.Educations != nil { for _, ed := range c.Educations { if ed.Acl.OwnerId == "" { ed.Acl.OwnerId = dsocialUserId } if ed.Id == "" { ed.Id = ds.GenerateId(dsocialUserId, "education") } } } if c.WorkHistories != nil { for _, wh := range c.WorkHistories { if wh.Acl.OwnerId == "" { wh.Acl.OwnerId = dsocialUserId } if wh.Id == "" { wh.Id = ds.GenerateId(dsocialUserId, "workhistory") } } } if c.PhoneNumbers != nil { for _, p := range c.PhoneNumbers { if p.Acl.OwnerId == "" { p.Acl.OwnerId = dsocialUserId } if p.Id == "" { p.Id = ds.GenerateId(dsocialUserId, "phone") } } } if c.EmailAddresses != nil { for _, e := range c.EmailAddresses { if e.Acl.OwnerId == "" { e.Acl.OwnerId = dsocialUserId } if e.Id == "" { e.Id = ds.GenerateId(dsocialUserId, "email") } } } if c.Uris != nil { for _, u := range c.Uris { if u.Acl.OwnerId == "" { u.Acl.OwnerId = dsocialUserId } if u.Id == "" { u.Id = ds.GenerateId(dsocialUserId, "uri") } } } if c.Ims != nil { for _, im := range c.Ims { if im.Acl.OwnerId == "" { im.Acl.OwnerId = dsocialUserId } if im.Id == "" { im.Id = ds.GenerateId(dsocialUserId, "im") } } } if c.Relationships != nil { for _, r := range c.Relationships { if r.Acl.OwnerId == "" { r.Acl.OwnerId = dsocialUserId } if r.Id == "" { r.Id = ds.GenerateId(dsocialUserId, "relationship") } } } if c.Dates != nil { for _, d := range c.Dates { if d.Acl.OwnerId == "" { d.Acl.OwnerId = dsocialUserId } if d.Id == "" { d.Id = ds.GenerateId(dsocialUserId, "date") } } } if c.DateTimes != nil { for _, d := range c.DateTimes { if d.Acl.OwnerId == "" { d.Acl.OwnerId = dsocialUserId } if d.Id == "" { d.Id = ds.GenerateId(dsocialUserId, "datetime") } } } if c.Certifications != nil { for _, cert := range c.Certifications { if cert.Acl.OwnerId == "" { cert.Acl.OwnerId = dsocialUserId } if cert.Id == "" { cert.Id = ds.GenerateId(dsocialUserId, "certification") } } } if c.Skills != nil { for _, s := range c.Skills { if s.Acl.OwnerId == "" { s.Acl.OwnerId = dsocialUserId } if s.Id == "" { s.Id = ds.GenerateId(dsocialUserId, "skill") } } } if c.Languages != nil { for _, l := range c.Languages { if l.Acl.OwnerId == "" { l.Acl.OwnerId = dsocialUserId } if l.Id == "" { l.Id = ds.GenerateId(dsocialUserId, "language") } } } return }