From 76b05eb846ff43ccaf7513458e8b27c1817af5db Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Thu, 26 Jan 2012 11:07:27 +0000 Subject: [PATCH] [#31,backends][m]: add BackendDataProxy, fixes #31. --- src/model.js | 94 ++++++++++++++++++++++++++++++++++++++++++-- test/model.test.js | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 4 deletions(-) diff --git a/src/model.js b/src/model.js index 3f429986..30054f4b 100644 --- a/src/model.js +++ b/src/model.js @@ -162,13 +162,12 @@ my.BackendMemory = Backbone.Model.extend({ // Webstore Backend for connecting to the Webstore // +// Initializing model argument must contain a url attribute pointing to +// relevant Webstore table. +// // Designed to only attach to one dataset and one dataset only ... // Could generalize to support attaching to different datasets my.BackendWebstore = Backbone.Model.extend({ - // require url attribute in initialization data - initialize: function() { - this.webstoreTableUrl = this.get('url'); - }, getDataset: function(id) { var dataset = new my.Dataset({ id: id @@ -227,6 +226,93 @@ my.BackendWebstore = Backbone.Model.extend({ } }); +// DataProxy Backend for connecting to the DataProxy +// +// Example initialization: +// +// BackendDataProxy({ +// model: { +// url: {url-of-data-to-proxy}, +// type: xls || csv, +// format: json || jsonp # return format (defaults to jsonp) +// dataproxy: {url-to-proxy} # defaults to http://jsonpdataproxy.appspot.com +// } +// }) +my.BackendDataProxy = Backbone.Model.extend({ + defaults: { + dataproxy: 'http://jsonpdataproxy.appspot.com' + , type: 'csv' + , format: 'jsonp' + }, + getDataset: function(id) { + var dataset = new my.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') { + var dataset = this; + // get the schema and return + var base = this.backend.get('dataproxy'); + var data = this.backend.toJSON(); + delete data['dataproxy']; + // TODO: should we cache for extra efficiency + data['max-results'] = 1; + var jqxhr = $.ajax({ + url: base + , data: data + , dataType: 'jsonp' + }); + var dfd = $.Deferred(); + jqxhr.then(function(results) { + dataset.set({ + headers: results.fields + }); + dfd.resolve(dataset, jqxhr); + }); + return dfd.promise(); + } + } else { + alert('This backend only supports read operations'); + } + }, + getDocuments: function(datasetId, numRows, start) { + if (start === undefined) { + start = 0; + } + if (numRows === undefined) { + numRows = 10; + } + var base = this.get('dataproxy'); + var data = this.toJSON(); + delete data['dataproxy']; + data['max-results'] = numRows; + var jqxhr = $.ajax({ + url: base + , data: data + , dataType: 'jsonp' + // , cache: true + }); + var dfd = $.Deferred(); + jqxhr.then(function(results) { + var _out = _.map(results.data, function(row) { + var tmp = {}; + _.each(results.fields, function(key, idx) { + tmp[key] = row[idx]; + }); + return tmp; + }); + dfd.resolve(_out); + }); + return dfd.promise(); + } +}); + return my; }(jQuery); diff --git a/test/model.test.js b/test/model.test.js index 9db2517d..4e3e3c2e 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -164,6 +164,104 @@ test('Webstore Backend', function() { equal("2009-01-01", docList.models[0].get('date')); }); }); + $.ajax.restore(); +}); + + +var dataProxyData = { + "data": [ + [ + "1", + "1950-01", + "34.73" + ], + [ + "2", + "1950-02", + "34.73" + ], + [ + "3", + "1950-03", + "34.73" + ], + [ + "4", + "1950-04", + "34.73" + ], + [ + "5", + "1950-05", + "34.73" + ], + [ + "6", + "1950-06", + "34.73" + ], + [ + "7", + "1950-07", + "34.73" + ], + [ + "8", + "1950-08", + "34.73" + ], + [ + "9", + "1950-09", + "34.73" + ], + [ + "10", + "1950-10", + "34.73" + ] + ], + "fields": [ + "__id__", + "date", + "price" + ], + "length": null, + "max_results": 10, + "url": "http://webstore.thedatahub.org/rufuspollock/gold_prices/data.csv" +}; + +test('DataProxy Backend', function() { + // needed only if not stubbing + // stop(); + var backend = new recline.Model.BackendDataProxy({ + url: 'http://webstore.thedatahub.org/rufuspollock/gold_prices/data.csv' + }); + recline.Model.setBackend(backend); + dataset = backend.getDataset(); + + var stub = sinon.stub($, 'ajax', function(options) { + var partialUrl = 'jsonpdataproxy.appspot.com'; + if (options.url.indexOf(partialUrl) != -1) { + return { + then: function(callback) { + callback(dataProxyData); + } + } + } + }); + + dataset.fetch().then(function(dataset) { + deepEqual(['__id__', 'date', 'price'], dataset.get('headers')); + equal(null, dataset.docCount) + dataset.getDocuments().then(function(docList) { + equal(10, docList.length) + equal("1950-01", docList.models[0].get('date')); + // needed only if not stubbing + start(); + }); + }); + $.ajax.restore(); }); })(this.jQuery);