140 lines
4.0 KiB
JavaScript
140 lines
4.0 KiB
JavaScript
this.recline = this.recline || {};
|
|
this.recline.Backend = this.recline.Backend || {};
|
|
this.recline.Backend.Ckan = this.recline.Backend.Ckan || {};
|
|
|
|
(function($, my) {
|
|
// ## CKAN Backend
|
|
//
|
|
// This provides connection to the CKAN DataStore (v2)
|
|
//
|
|
// General notes
|
|
//
|
|
// We need 2 things to make most requests:
|
|
//
|
|
// 1. CKAN API endpoint
|
|
// 2. ID of resource for which request is being made
|
|
//
|
|
// There are 2 ways to specify this information.
|
|
//
|
|
// EITHER (checked in order):
|
|
//
|
|
// * Every dataset must have an id equal to its resource id on the CKAN instance
|
|
// * The dataset has an endpoint attribute pointing to the CKAN API endpoint
|
|
//
|
|
// OR:
|
|
//
|
|
// Set the url attribute of the dataset to point to the Resource on the CKAN instance. The endpoint and id will then be automatically computed.
|
|
|
|
my.__type__ = 'ckan';
|
|
|
|
// Default CKAN API endpoint used for requests (you can change this but it will affect every request!)
|
|
//
|
|
// DEPRECATION: this will be removed in v0.7. Please set endpoint attribute on dataset instead
|
|
my.API_ENDPOINT = 'http://datahub.io/api';
|
|
|
|
// ### fetch
|
|
my.fetch = function(dataset) {
|
|
if (dataset.endpoint) {
|
|
var wrapper = my.DataStore(dataset.endpoint);
|
|
} else {
|
|
var out = my._parseCkanResourceUrl(dataset.url);
|
|
dataset.id = out.resource_id;
|
|
var wrapper = my.DataStore(out.endpoint);
|
|
}
|
|
var dfd = $.Deferred();
|
|
var jqxhr = wrapper.search({resource_id: dataset.id, limit: 0});
|
|
jqxhr.done(function(results) {
|
|
// map ckan types to our usual types ...
|
|
var fields = _.map(results.result.fields, function(field) {
|
|
field.type = field.type in CKAN_TYPES_MAP ? CKAN_TYPES_MAP[field.type] : field.type;
|
|
return field;
|
|
});
|
|
var out = {
|
|
fields: fields,
|
|
useMemoryStore: false
|
|
};
|
|
dfd.resolve(out);
|
|
});
|
|
return dfd.promise();
|
|
};
|
|
|
|
// only put in the module namespace so we can access for tests!
|
|
my._normalizeQuery = function(queryObj, dataset) {
|
|
var actualQuery = {
|
|
resource_id: dataset.id,
|
|
q: queryObj.q,
|
|
limit: queryObj.size || 10,
|
|
offset: queryObj.from || 0
|
|
};
|
|
if (queryObj.sort && queryObj.sort.length > 0) {
|
|
var _tmp = _.map(queryObj.sort, function(sortObj) {
|
|
return sortObj.field + ' ' + (sortObj.order || '');
|
|
});
|
|
actualQuery.sort = _tmp.join(',');
|
|
}
|
|
return actualQuery;
|
|
}
|
|
|
|
my.query = function(queryObj, dataset) {
|
|
if (dataset.endpoint) {
|
|
var wrapper = my.DataStore(dataset.endpoint);
|
|
} else {
|
|
var out = my._parseCkanResourceUrl(dataset.url);
|
|
dataset.id = out.resource_id;
|
|
var wrapper = my.DataStore(out.endpoint);
|
|
}
|
|
var actualQuery = my._normalizeQuery(queryObj, dataset);
|
|
var dfd = $.Deferred();
|
|
var jqxhr = wrapper.search(actualQuery);
|
|
jqxhr.done(function(results) {
|
|
var out = {
|
|
total: results.result.total,
|
|
hits: results.result.records,
|
|
};
|
|
dfd.resolve(out);
|
|
});
|
|
return dfd.promise();
|
|
};
|
|
|
|
// ### DataStore
|
|
//
|
|
// Simple wrapper around the CKAN DataStore API
|
|
//
|
|
// @param endpoint: CKAN api endpoint (e.g. http://datahub.io/api)
|
|
my.DataStore = function(endpoint) {
|
|
var that = {
|
|
endpoint: endpoint || my.API_ENDPOINT
|
|
};
|
|
that.search = function(data) {
|
|
var searchUrl = that.endpoint + '/3/action/datastore_search';
|
|
var jqxhr = $.ajax({
|
|
url: searchUrl,
|
|
data: data,
|
|
dataType: 'json'
|
|
});
|
|
return jqxhr;
|
|
}
|
|
|
|
return that;
|
|
};
|
|
|
|
// Parse a normal CKAN resource URL and return API endpoint etc
|
|
//
|
|
// Normal URL is something like http://demo.ckan.org/dataset/some-dataset/resource/eb23e809-ccbb-4ad1-820a-19586fc4bebd
|
|
my._parseCkanResourceUrl = function(url) {
|
|
parts = url.split('/');
|
|
var len = parts.length;
|
|
return {
|
|
resource_id: parts[len-1],
|
|
endpoint: parts.slice(0,[len-4]).join('/') + '/api'
|
|
}
|
|
};
|
|
|
|
var CKAN_TYPES_MAP = {
|
|
'int4': 'integer',
|
|
'int8': 'integer',
|
|
'float8': 'float'
|
|
};
|
|
|
|
}(jQuery, this.recline.Backend.Ckan));
|