From 72ed877ae249ec18658ce307eb4a63958e6bbfb6 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Sat, 26 May 2012 18:26:47 +0100 Subject: [PATCH] [#128,misc][s]: final wiring up to have everything working again -- fixes #128. --- app/index.html | 2 +- src/backend/base.js | 262 ++++++++++++++++---------------------------- src/model.js | 4 +- 3 files changed, 97 insertions(+), 171 deletions(-) diff --git a/app/index.html b/app/index.html index 6d9d78c2..6f52251e 100644 --- a/app/index.html +++ b/app/index.html @@ -157,7 +157,7 @@ diff --git a/src/backend/base.js b/src/backend/base.js index 9c027d87..2758f51e 100644 --- a/src/backend/base.js +++ b/src/backend/base.js @@ -6,180 +6,108 @@ this.recline = this.recline || {}; this.recline.Backend = this.recline.Backend || {}; -(function($, my) { - // ## recline.Backend.Base +// ## recline.Backend.Base +// +// Exemplar 'class' for backends showing what a base class would look like. +this.recline.Backend.Base = function() { + // ### __type__ // - // Base class for backends providing a template and convenience functions. - // You do not have to inherit from this class but even when not it does - // provide guidance on the functions you must implement. + // 'type' of this backend. This should be either the class path for this + // object as a string (e.g. recline.Backend.Memory) or for Backends within + // recline.Backend module it may be their class name. // - // Note also that while this (and other Backends) are implemented as Backbone models this is just a convenience. - my.Base = Backbone.Model.extend({ - // ### __type__ - // - // 'type' of this backend. This should be either the class path for this - // object as a string (e.g. recline.Backend.Memory) or for Backends within - // recline.Backend module it may be their class name. - // - // This value is used as an identifier for this backend when initializing - // backends (see recline.Model.Dataset.initialize). - __type__: 'base', + // This value is used as an identifier for this backend when initializing + // backends (see recline.Model.Dataset.initialize). + this.__type__ = 'base'; + // ### readonly + // + // Class level attribute indicating that this backend is read-only (that + // is, cannot be written to). + this.readonly = true; - // ### readonly - // - // Class level attribute indicating that this backend is read-only (that - // is, cannot be written to). - readonly: true, - - // ### sync - // - // An implementation of Backbone.sync that will be used to override - // Backbone.sync on operations for Datasets and Documents which are using this backend. - // - // For read-only implementations you will need only to implement read method - // for Dataset models (and even this can be a null operation). The read method - // should return relevant metadata for the Dataset. We do not require read support - // for Documents because they are loaded in bulk by the query method. - // - // For backends supporting write operations you must implement update and delete support for Document objects. - // - // All code paths should return an object conforming to the jquery promise API. - sync: function(method, model, options) { - }, - - // ### query - // - // Query the backend for documents returning them in bulk. This method will - // be used by the Dataset.query method to search the backend for documents, - // retrieving the results in bulk. - // - // @param {recline.model.Dataset} model: Dataset model. - // - // @param {Object} queryObj: object describing a query (usually produced by - // using recline.Model.Query and calling toJSON on it). - // - // The structure of data in the Query object or - // Hash should follow that defined in issue 34. - // (Of course, if you are writing your own backend, and hence - // have control over the interpretation of the query object, you - // can use whatever structure you like). - // - // @returns {Promise} promise API object. The promise resolve method will - // be called on query completion with a QueryResult object. - // - // A QueryResult has the following structure (modelled closely on - // ElasticSearch - see this issue for more - // details): - // - //
-    // {
-    //   total: // (required) total number of results (can be null)
-    //   hits: [ // (required) one entry for each result document
-    //     {
-    //        _score:   // (optional) match score for document
-    //        _type: // (optional) document type
-    //        _source: // (required) document/row object
-    //     } 
-    //   ],
-    //   facets: { // (optional) 
-    //     // facet results (as per )
-    //   }
-    // }
-    // 
- query: function(model, queryObj) { - }, - - // ### _makeRequest - // - // Just $.ajax but in any headers in the 'headers' attribute of this - // Backend instance. Example: - // - //
-    // var jqxhr = this._makeRequest({
-    //   url: the-url
-    // });
-    // 
- _makeRequest: function(data) { - var headers = this.get('headers'); - var extras = {}; - if (headers) { - extras = { - beforeSend: function(req) { - _.each(headers, function(value, key) { - req.setRequestHeader(key, value); - }); - } - }; - } - var data = _.extend(extras, data); - return $.ajax(data); - }, - - // convenience method to convert simple set of documents / rows to a QueryResult - _docsToQueryResult: function(rows) { - var hits = _.map(rows, function(row) { - return { _source: row }; - }); - return { - total: null, - hits: hits - }; - }, - - // ## _wrapInTimeout - // - // Convenience method providing a crude way to catch backend errors on JSONP calls. - // Many of backends use JSONP and so will not get error messages and this is - // a crude way to catch those errors. - _wrapInTimeout: function(ourFunction) { - var dfd = $.Deferred(); - var timeout = 5000; - var timer = setTimeout(function() { - dfd.reject({ - message: 'Request Error: Backend did not respond after ' + (timeout / 1000) + ' seconds' - }); - }, timeout); - ourFunction.done(function(arguments) { - clearTimeout(timer); - dfd.resolve(arguments); - }) - .fail(function(arguments) { - clearTimeout(timer); - dfd.reject(arguments); - }) - ; - return dfd.promise(); - } - }); - - // ### makeRequest + // ### sync + // + // An implementation of Backbone.sync that will be used to override + // Backbone.sync on operations for Datasets and Documents which are using this backend. + // + // For read-only implementations you will need only to implement read method + // for Dataset models (and even this can be a null operation). The read method + // should return relevant metadata for the Dataset. We do not require read support + // for Documents because they are loaded in bulk by the query method. + // + // For backends supporting write operations you must implement update and delete support for Document objects. + // + // All code paths should return an object conforming to the jquery promise API. + this.sync = function(method, model, options) { + }, + + // ### query + // + // Query the backend for documents returning them in bulk. This method will + // be used by the Dataset.query method to search the backend for documents, + // retrieving the results in bulk. + // + // @param {recline.model.Dataset} model: Dataset model. + // + // @param {Object} queryObj: object describing a query (usually produced by + // using recline.Model.Query and calling toJSON on it). + // + // The structure of data in the Query object or + // Hash should follow that defined in issue 34. + // (Of course, if you are writing your own backend, and hence + // have control over the interpretation of the query object, you + // can use whatever structure you like). + // + // @returns {Promise} promise API object. The promise resolve method will + // be called on query completion with a QueryResult object. // - // Just $.ajax but in any headers in the 'headers' attribute of this - // Backend instance. Example: + // A QueryResult has the following structure (modelled closely on + // ElasticSearch - see this issue for more + // details): // //
-  // var jqxhr = this._makeRequest({
-  //   url: the-url
-  // });
+  // {
+  //   total: // (required) total number of results (can be null)
+  //   hits: [ // (required) one entry for each result document
+  //     {
+  //        _score:   // (optional) match score for document
+  //        _type: // (optional) document type
+  //        _source: // (required) document/row object
+  //     } 
+  //   ],
+  //   facets: { // (optional) 
+  //     // facet results (as per )
+  //   }
+  // }
   // 
- my.makeRequest = function(data, headers) { - var extras = {}; - if (headers) { - extras = { - beforeSend: function(req) { - _.each(headers, function(value, key) { - req.setRequestHeader(key, value); - }); - } - }; - } - var data = _.extend(extras, data); - return $.ajax(data); - }; + this.query = function(model, queryObj) {} +}; - -}(jQuery, this.recline.Backend)); +// ### makeRequest +// +// Just $.ajax but in any headers in the 'headers' attribute of this +// Backend instance. Example: +// +//
+// var jqxhr = this._makeRequest({
+//   url: the-url
+// });
+// 
+this.recline.Backend.makeRequest = function(data, headers) { + var extras = {}; + if (headers) { + extras = { + beforeSend: function(req) { + _.each(headers, function(value, key) { + req.setRequestHeader(key, value); + }); + } + }; + } + var data = _.extend(extras, data); + return $.ajax(data); +}; diff --git a/src/model.js b/src/model.js index 180fb926..b1ec858b 100644 --- a/src/model.js +++ b/src/model.js @@ -44,8 +44,6 @@ my.Dataset = Backbone.Model.extend({ initialize: function(model, backend) { _.bindAll(this, 'query'); this.backend = backend; - this.backendType = 'memory'; - this.backendURL = null; if (typeof(backend) === 'string') { this.backend = this._backendFromString(backend); } @@ -135,7 +133,7 @@ my.Dataset = Backbone.Model.extend({ if (recline && recline.Backend) { _.each(_.keys(recline.Backend), function(name) { if (name.toLowerCase() === backendString.toLowerCase()) { - backend = new recline.Backend[name](); + backend = new recline.Backend[name].Backbone(); } }); }