ModelDesignSpec

Model Design Proposal

Motivation and Summery

There are several limitations and problems with current data backend. I can mention the following list as some of them. Current data backend system:

  • is tied to a certain data provider
  • provides almost no caching and no offline access (in extend permitted by term of use: "reasonable periods in order to provide your service")
  • needs certain form of authentication (TMDb account) and being online in order to provide user-specific features (such as adding a movie to one of user's lists)

The proposed method, have the following benefits:

  • Handles multiple data providers, each providing data in it's specific domain (or general)
  • Provides caching facility and (limit-able!) offline access. no need to fetch a movie twice in a "reasonable period" of time.
  • Provides user-specific features like marking 'seen' movies, user rating or monitoring certain TV Shows, without asking user to set up multiple external account in different websites
  • If user have accounts in external services, we can sync related portion of user-specific data to these services for them as they become connected to the app.
  • We can sync their user-specific data across Ubuntu devices with u1db. no need for yet another account just to sync Cliffhanger data on phone and desktop.

* Doesn't need separate model code for singular (Movie) and plural (Movies) data. (less code repeats)

Implementation

Implementation will use JavaScript models utilizing Qt Quick local storage API as backend. Each row in each table will contain data about a single entity (a movie, a person or an episode). Entities are linked by foreign keys. every entity will have a UUID primary key and ids in multiple providers (tmdb_id, tvdb_id, imdb_id etc.)

Data fetched from deferent sources will be stored alongside each other. Because deferent sources are more accurate in certain areas, each model would implement a method to decide which one of the fetched values will be used and whether a provider API call necessary or not.

Example JavaScript DSL

example one: fetching

// suppose we know there is a movie with tmdb id 550. we try to fetch from database

m = Movie.find_by_ids({'tmdb_id': 550})

// {'attributes':
//   {'uuid': '54982b4f-133f-48ac-ba89-f21cc01ac551' ,'tmdb_id':'550',
//    trakt_id:null, 'title_cache': null, 'tmdb_title':null, 'trakt_title':null,
//    'overview_cache': null, 'tmdb_overview':null, 'trakt_overview':null, ...}, 
//   ...}

// oops, it's not in the database. but an empty row is created and saved into the database.
// No requests is sent now. It loads attributes lazily when it should hit the web

title = m.attribute('title')

// first, we checks whether a cache of title attribute is saved in database row (m.attributes.title_cache)

// The title cache is empty, we have to hit the api. we will serve empty string to the ui and then hit the
// best source for this model asynchronously. hopefully it'll have the data we need. internally we will
// do m.updateFrom('tmdb')

// if there was a cached title available, we'd have returned that value and asynchronously tried to hit the
// API and update the database record if the phone was online. we have to do this to comply with terms of
// use of must apis.

// now that we have recieved a payload from one of our sources, we'll update the database and our instance.
// internaly we'll call m.updateAttributes({'tmdb_id': 550, 'tmdb_title': 'carpe diem', 'tmdb_overview': 'carpe diem quam ...',...})
// also, the attribute cache (title_cache, etc.) will be updated each time we hit updateAttributes().

Cliffhanger/ModelDesignSpec (last edited 2013-11-27 20:32:43 by 5)