From 5eb06b982e056dd75d5f7ab0467c453e669f0405 Mon Sep 17 00:00:00 2001 From: rgrp Date: Mon, 7 Nov 2011 21:52:07 +0000 Subject: [PATCH] [model][m]: working Webstore Backend (fixes #8). --- src/model.js | 76 +++++++++++++++++++++++++++++++-- test/model.test.js | 104 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 175 insertions(+), 5 deletions(-) diff --git a/src/model.js b/src/model.js index 7b0bb1e8..1699a8f5 100644 --- a/src/model.js +++ b/src/model.js @@ -20,6 +20,13 @@ recline.DocumentList = Backbone.Collection.extend({ model: recline.Document }) +// Backends section +// ================ + +recline.setBackend = function(backend) { + Backbone.sync = backend.sync; +}; + // Backend which just caches in memory // // Does not need to be a backbone model but provides some conveience @@ -73,7 +80,68 @@ recline.BackendMemory = Backbone.Model.extend({ } }); -recline.setBackend = function(backend) { - Backbone.sync = backend.sync; -}; - +// Webstore Backend for connecting to the Webstore +// +// Designed to only attached to only dataset and one dataset only ... +// Could generalize to support attaching to different datasets +recline.BackendWebstore = Backbone.Model.extend({ + // require url attribute in initialization data + initialize: function() { + this.webstoreTableUrl = this.get('url'); + }, + getDataset: function(id) { + var dataset = new recline.Dataset({ + id: id + }); + dataset.backend = this; + return dataset; + }, + sync: function(method, model, options) { + if (method === "read") { + // this switching on object type is rather horrible + // think may make more sense to do work in individual objects rather than in central Backbone.sync + if (this.__type__ == 'Dataset') { + // get the schema and return + var base = this.backend.get('url'); + var schemaUrl = base + '/schema.json'; + var jqxhr = $.ajax({ + url: schemaUrl, + dataType: 'jsonp', + jsonp: '_callback' + }); + var dfd = $.Deferred(); + jqxhr.then(function(schema) { + headers = _.map(schema.data, function(item) { + return item.name; + }); + dataset.set({ + headers: headers + }); + dataset.rowCount = schema.count; + dfd.resolve(dataset, jqxhr); + }); + return dfd.promise(); + } + } + }, + getRows: function(datasetId, numRows, start) { + if (start === undefined) { + start = 0; + } + if (numRows === undefined) { + numRows = 10; + } + var base = this.get('url'); + var jqxhr = $.ajax({ + url: base + '.json', + dataType: 'jsonp', + jsonp: '_callback', + cache: true + }); + var dfd = $.Deferred(); + jqxhr.then(function(results) { + dfd.resolve(results.data); + }); + return dfd.promise(); + } +}); diff --git a/test/model.test.js b/test/model.test.js index 6563332e..452349c6 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -43,7 +43,109 @@ test('new Dataset', function () { }); }); -test('Local Data Sync', function() { +// TODO: move to fixtures +var webstoreSchema = { + "count": 3, + "data": [ + { + "name": "__id__", + "type": "integer", + "values_url": "/rufuspollock/demo/data/distinct/__id__" + }, + { + "name": "date", + "type": "text", + "values_url": "/rufuspollock/demo/data/distinct/date" + }, + { + "name": "geometry", + "type": "text", + "values_url": "/rufuspollock/demo/data/distinct/geometry" + }, + { + "name": "amount", + "type": "text", + "values_url": "/rufuspollock/demo/data/distinct/amount" + } + ], + "fields": [ + { + "name": "type" + }, + { + "name": "name" + }, + { + "name": "values_url" + } + ] +}; + +webstoreData = { + "count": null, + "data": [ + { + "__id__": 1, + "amount": "100", + "date": "2009-01-01", + "geometry": null + }, + { + "__id__": 2, + "amount": "200", + "date": "2010-01-01", + "geometry": null + }, + { + "__id__": 3, + "amount": "300", + "date": "2011-01-01", + "geometry": null + } + ], + "fields": [ + { + "name": "__id__" + }, + { + "name": "date" + }, + { + "name": "geometry" + }, + { + "name": "amount" + } + ] +}; + +test('Webstore Backend', function() { + stop(); + var backend = new recline.BackendWebstore({ + url: 'http://webstore.test.ckan.org/rufuspollock/demo/data' + }); + recline.setBackend(backend); + dataset = backend.getDataset(); + + var stub = sinon.stub($, 'ajax', function(options) { + return { + then: function(callback) { + callback(webstoreSchema); + } + } + }); + + dataset.fetch().then(function(dataset) { + equal(['__id__', 'date', 'geometry', 'amount'], dataset.get('headers')); + equal(3, dataset.rowCount) + // restore mocked method + $.ajax.restore(); + dataset.getRows().then(function(rows) { + start(); + equal(3,rows.length) + equal("2009-01-01", rows[0].date); + }); + }); }); })(this.jQuery);