[be/dataproxy][m]: switch dataproxy to use Memory data store (fixes #164) and switch to new backend / model setup (#162).

This commit is contained in:
Rufus Pollock
2012-06-23 18:00:30 +01:00
parent 7141b7aafd
commit 1ed3b9f423
3 changed files with 82 additions and 97 deletions

View File

@@ -3,95 +3,78 @@ this.recline.Backend = this.recline.Backend || {};
this.recline.Backend.DataProxy = this.recline.Backend.DataProxy || {}; this.recline.Backend.DataProxy = this.recline.Backend.DataProxy || {};
(function($, my) { (function($, my) {
// ## DataProxy Backend my.__type__ = 'dataproxy';
// // URL for the dataproxy
// For connecting to [DataProxy-s](http://github.com/okfn/dataproxy). my.dataproxy_url = 'http://jsonpdataproxy.appspot.com';
//
// When initializing the DataProxy backend you can set the following
// attributes in the options object:
//
// * dataproxy: {url-to-proxy} (optional). Defaults to http://jsonpdataproxy.appspot.com
//
// Datasets using using this backend should set the following attributes:
//
// * url: (required) url-of-data-to-proxy
// * format: (optional) csv | xls (defaults to csv if not specified)
//
// Note that this is a **read-only** backend.
my.Backbone = function(options) {
var self = this;
this.__type__ = 'dataproxy';
this.readonly = true;
this.dataproxy_url = options && options.dataproxy_url ? options.dataproxy_url : 'http://jsonpdataproxy.appspot.com'; // ## load
//
this.sync = function(method, model, options) { // Load data from a URL via the [DataProxy](http://github.com/okfn/dataproxy).
if (method === "read") { my.fetch = function(dataset) {
if (model.__type__ == 'Dataset') { var data = {
// Do nothing as we will get fields in query step (and no metadata to url: dataset.get('url'),
// retrieve) 'max-results': dataset.get('size') || dataset.get('rows') || 1000,
var dfd = $.Deferred(); type: dataset.get('format') || ''
dfd.resolve(model); };
return dfd.promise(); var jqxhr = $.ajax({
} url: my.dataproxy_url,
} else { data: data,
alert('This backend only supports read operations'); dataType: 'jsonp'
});
var dfd = $.Deferred();
_wrapInTimeout(jqxhr).done(function(results) {
if (results.error) {
dfd.reject(results.error);
} }
};
this.query = function(dataset, queryObj) { // Rename duplicate fieldIds as each field name needs to be
var self = this; // unique.
var data = { var seen = {};
url: dataset.get('url'), var fields = _.map(results.fields, function(field, index) {
'max-results': queryObj.size, var fieldId = field;
type: dataset.get('format') while (fieldId in seen) {
}; seen[field] += 1;
var jqxhr = $.ajax({ fieldId = field + seen[field];
url: this.dataproxy_url,
data: data,
dataType: 'jsonp'
});
var dfd = $.Deferred();
_wrapInTimeout(jqxhr).done(function(results) {
if (results.error) {
dfd.reject(results.error);
} }
if (!(field in seen)) {
// Rename duplicate fieldIds as each field name needs to be seen[field] = 0;
// unique. }
var seen = {}; return { id: fieldId, label: field }
_.map(results.fields, function(fieldId, index) {
if (fieldId in seen) {
seen[fieldId] += 1;
results.fields[index] = fieldId + "("+seen[fieldId]+")";
} else {
seen[fieldId] = 1;
}
});
dataset.fields.reset(_.map(results.fields, function(fieldId) {
return {id: fieldId};
})
);
var _out = _.map(results.data, function(doc) {
var tmp = {};
_.each(results.fields, function(key, idx) {
tmp[key] = doc[idx];
});
return tmp;
});
dfd.resolve({
total: null,
hits: _.map(_out, function(row) {
return { _source: row };
})
});
})
.fail(function(arguments) {
dfd.reject(arguments);
}); });
return dfd.promise();
// data is provided as arrays so need to zip together with fields
var records = _.map(results.data, function(doc) {
var tmp = {};
_.each(results.fields, function(key, idx) {
tmp[key] = doc[idx];
});
return tmp;
});
var store = new recline.Backend.Memory.Store(records, fields);
dataset._dataCache = store;
dataset.fields.reset(fields);
dataset.query();
dfd.resolve(dataset);
})
.fail(function(arguments) {
dfd.reject(arguments);
});
return dfd.promise();
};
my.query = function(dataset, queryObj) {
var dfd = $.Deferred();
var results = dataset._dataCache.query(queryObj);
var hits = _.map(results.records, function(row) {
return { _source: row };
});
var out = {
total: results.total,
hits: hits,
facets: results.facets
}; };
dfd.resolve(out);
return dfd.promise();
}; };
// ## _wrapInTimeout // ## _wrapInTimeout

View File

@@ -179,7 +179,7 @@ my.Dataset = Backbone.Model.extend({
current = current[parts[ii]]; current = current[parts[ii]];
} }
if (current) { if (current) {
return new current(); return current;
} }
// alternatively we just had a simple string // alternatively we just had a simple string
@@ -187,7 +187,7 @@ my.Dataset = Backbone.Model.extend({
if (recline && recline.Backend) { if (recline && recline.Backend) {
_.each(_.keys(recline.Backend), function(name) { _.each(_.keys(recline.Backend), function(name) {
if (name.toLowerCase() === backendString.toLowerCase()) { if (name.toLowerCase() === backendString.toLowerCase()) {
backend = new recline.Backend[name].Backbone(); backend = recline.Backend[name];
} }
}); });
} }

View File

@@ -67,14 +67,13 @@ var dataProxyData = {
test('DataProxy Backend', function() { test('DataProxy Backend', function() {
// needed only if not stubbing // needed only if not stubbing
// stop(); // stop();
var backend = new recline.Backend.DataProxy.Backbone(); var backend = recline.Backend.DataProxy;
ok(backend.readonly);
equal(backend.__type__, 'dataproxy'); equal(backend.__type__, 'dataproxy');
var dataset = new recline.Model.Dataset({ var dataset = new recline.Model.Dataset({
url: 'http://webstore.thedatahub.org/rufuspollock/gold_prices/data.csv' url: 'http://webstore.thedatahub.org/rufuspollock/gold_prices/data.csv'
}, },
backend 'dataproxy'
); );
var stub = sinon.stub($, 'ajax', function(options) { var stub = sinon.stub($, 'ajax', function(options) {
@@ -92,15 +91,18 @@ test('DataProxy Backend', function() {
} }
}); });
dataset.fetch().done(function(dataset) { expect(6);
dataset.query().done(function(docList) { dataset.fetch().then(function() {
deepEqual(['__id__', 'date', 'price'], _.pluck(dataset.fields.toJSON(), 'id')); deepEqual(['__id__', 'date', 'price'], _.pluck(dataset.fields.toJSON(), 'id'));
equal(null, dataset.docCount) equal(10, dataset.docCount)
equal(10, docList.length) equal(dataset.currentRecords.models[0].get('date'), "1950-01");
equal("1950-01", docList.models[0].get('date')); // needed only if not stubbing
// needed only if not stubbing // start();
start(); });
});
dataset.query({q: '1950-01'}).then(function() {
equal(dataset.docCount, 1);
equal(dataset.currentRecords.models[0].get('price'), '34.73');
}); });
$.ajax.restore(); $.ajax.restore();
}); });