Skip to content

Data.Graph Persistence API that will ship with Data.js 0.2.0

michael edited this page Dec 17, 2010 · 2 revisions

Data.Graph Persistence API that will ship with Data.js 0.2.0

Data.js comes with a Data.Adapter for CouchDB, so this will be our first graph data-store.

Let's describe our domain model, which will serve as our type system

var domain = {

  // Person
  // --------------------

  "/type/person": {
    "type": "type",
    "name": "Person",
    "properties": {
      "name": {
        "name": "Name",
        "unique": true,
        "expected_type": "string"
      },
      "father": {
        "name": "Father",
        "unique": true,
        "expected_type": "string"
      },
      "origin": {
        "name": "Page Count",
        "unique": true,
        "expected_type": "/type/location"
      }
    }
  },

  // Location
  // --------------------

  "/type/location": {
    "type": "type",
    "name": "Location",
    "properties": {
      "name": {
        "name": "Name",
        "unique": true,
        "expected_type": "string"
      },
      "citizens": {
        "name": "Citizens",
        "unique": false,
        "expected_type": "/type/person"
      }
    }
  }
};

Now lets store our domain model in CouchDB

var Data = require('data').setAdapter('couch', {
  user: 'foo',
  password: 'bar',
  database: 'simpsons'
});

var graph = new Data.Graph(domain);
graph.save(); // Stores the Data.Graph in Couch, asynchronously

Lets add a Person object

graph.set('/person/bart', {
  name: "Bart Simpson"
});

Because of prefixing the type to every object_id we can derive the type property automatically.

We could sync with the DB now, but we wait until we've added more objects

graph.set('/location/springfield', {
  name: "Springfield",
  citizens: ["/person/bart"]
});

Now Springfield is aware of bart as a citizen, but Bart doesn't have an origin yet

graph.get('/person/bart')
  .set({origin: "/location/springfield"});

Well, now Homer wants to join the fun

graph.set('/person/homer', {
  name: "Homer Simpson",
  origin: "/location/springfield",
});

Mayor, there's a new citizen

graph.get('/location/springfield').set({
  citizens: ["/person/bart", "/person/homer"]
});

Okay, now suppose Mayor Quimby wants to display a list of inhabitants — Luckily he's got some basic Javascript skills

We start with an empty graph, supposing that we've set up the Data.Adapter already. var graph = new Data.Graph();

graph.get('/location/springfield').get('citizens').each(function(person) {
  console.log(person.get('name'));
});

The Data.Graph will start fetching nodes from the database on demand. So what we get here's is an infinitely huge object space we can traverse step by step, and on demand.

Actually, this is all about creating applications with a dynamic type system. You can at any time adjust your types by adding or removing properties.