Data model changes for people merging



Right now, there is no "merging" going on in the raw data exported
through the data model. Local IM contacts are represented like:

 online-desktop:/o/global
   onlineBuddies: [online-desktop:/o/pidgin-buddy/xmpp otaylor redhat com, ...]

 online-desktop:/o/pidgin-buddy/aim.owenwtaylor
    protocol: aim
    name: owenwtaylor
    alias: Owen Taylor
    status: available
    icon: data:image/png;base64;iVBOR....
    isOnline: 1

And there is separate data provided by the server:
 
 http://online.g.o/o/user/61m76k3hGbRRFS
    name: Owen
    homeUrl: http://mugshot.org/person?who=/o/user/61m76k3hGbRRFS
    aim: owenwtaylor

That can be merged together by the application. But this is bad in
several ways. First: we need complex code in every application to do the
merging. Second, when you do the coding in the applications, you have to
write a new custom API for it rather than using the standard data model
API. What we'd really want to have is the merging happening in the data
model engine, so we just have extra properties.	
 
 online-desktop:/o/pidgin-buddy/aim.owenwtaylor
    [...]
    user: http://online.g.o/o/user/61m76k3hGbRRFS

And:
   
  http://online.g.o/o/user/61m76k3hGbRRFS
    [...]
    aimBuddy: online-desktop:/o/pidgin-buddy/aim.owenwtaylor

I started to do this manually for the special case, but it got really
hairy to deal with all the cases ... local contacts being added and
removed, remote contacts being added and removed, and so forth. So I
came to the conclusion that the easier thing would be to add a generic
mechanism.

The basic idea is that you define a property as a query. We define
the <class>#<property> http://online.g.o/p/o/user#aimBuddy as:
  
   select source from online-desktop:/p/o/buddy source
      where and target.protocol = 'aim'
        and target.aim = source.name

(Without any implication of putting a SQL parser into the data model
engine! I'm just using sql to approximate the meaning.)

Issues:

 * The set of objects of a particular class in the client's memory is
   non-deterministic. It depends on what has been queried. So whether
   online-desktop:/p/o/buddy#user points to a online.g.o user depends
   not on whether we've happened to query that user's AIM address or
   not.

   In general, I think this is acceptable ... if we always query your
   contacts, we'll generally know about all the online.gnome.org
   users you *expect* to know about. We could also do explicit queries
   to the server based on the the IM contacts we see. A data model
   operation like:

    getUsersByAim(aim='owenwtaylor,johndoe532341,...')

 * The queries we want aren't entirely simple. Just the other side
   of the one above would have to be:

   online-desktop:/p/o/buddy#user:
     select source from  http://online.g.o/p/o/user source
         where (source.protocol = 'aim'
                and target.name = source.aim) or
               (source.protocol = 'xmpp'
                and target.name = source.xmpp)

 * The behavior we want for online-desktop:/p/o/buddy#user is actually
   even more complex than the above. We want:

     - The online.g.o user if one exists
     - A synthetically created user based on the contact data if the
       online.g.o doesn't exist

  Which would imply even more complexity in how the query is specified.
 
  The answer to both this point and the one above be the same: to go in
  between the original idea of writing code to update the data model
  and the full idea of expressing the property contents in a 
  declarative fashion.

 * Along with query specification, maintaining indices, and doing updates 
   to computed property values as data comes in, there is another fairly
   tricky thing that needs to be written: fetches that traverse local
   and remote data. If someone says:

   getResource('online-desktop:/o/global'
               'onlineBuddies [name;user [name;email;photoUrl]]')

   Then we have to look locally to find the user resources, then go remotely
   to get the name/email/photoUrl for the user resources if we don't
   already have them. It could get even more complex:

     'onlineBuddies user contacts aimBuddy'

   Where we look locally, then look remotely, then look locally again. So
   that's more code to write. But we've actually already run into this
   problem with the online-desktop:/o/global#self property, so it's not
   additional work.

There's quite a bit more that needs to be figured out about actual
implementation, but I think I'll stop here so there's some chance that
someone else will actually work through the above and give me feedback.

- Owen

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]