Jump To …

memory.js

this.recline = this.recline || {};
this.recline.Backend = this.recline.Backend || {};

(function($, my) {

createDataset

Convenience function to create a simple 'in-memory' dataset in one step.

@param data: list of hashes for each document/row in the data ({key: value, key: value}) @param fields: (optional) list of field hashes (each hash defining a hash as per recline.Model.Field). If fields not specified they will be taken from the data. @param metadata: (optional) dataset metadata - see recline.Model.Dataset. If not defined (or id not provided) id will be autogenerated.

  my.createDataset = function(data, fields, metadata) {
    if (!metadata) {
      var metadata = {};
    }
    if (!metadata.id) {
      metadata.id = String(Math.floor(Math.random() * 100000000) + 1);
    }
    var backend = recline.Model.backends['memory'];
    var datasetInfo = {
      documents: data,
      metadata: metadata
    };
    if (fields) {
      datasetInfo.fields = fields;
    } else {
      if (data) {
        datasetInfo.fields = _.map(data[0], function(value, key) {
          return {id: key};
        });
      }
    }
    backend.addDataset(datasetInfo);
    var dataset = new recline.Model.Dataset({id: metadata.id}, 'memory');
    dataset.fetch();
    return dataset;
  };

Memory Backend - uses in-memory data

To use it you should provide in your constructor data:

  • metadata (including fields array)
  • documents: list of hashes, each hash being one doc. A doc must have an id attribute which is unique.

Example:

 // Backend setup
 var backend = recline.Backend.Memory();
 backend.addDataset({
   metadata: {
     id: 'my-id',
     title: 'My Title'
   },
   fields: [{id: 'x'}, {id: 'y'}, {id: 'z'}],
   documents: [
       {id: 0, x: 1, y: 2, z: 3},
       {id: 1, x: 2, y: 4, z: 6}
     ]
 });
 // later ...
 var dataset = Dataset({id: 'my-id'}, 'memory');
 dataset.fetch();
 etc ...
 

  my.Memory = my.Base.extend({
    initialize: function() {
      this.datasets = {};
    },
    addDataset: function(data) {
      this.datasets[data.metadata.id] = $.extend(true, {}, data);
    },
    sync: function(method, model, options) {
      var self = this;
      if (method === "read") {
        var dfd = $.Deferred();
        if (model.__type__ == 'Dataset') {
          var rawDataset = this.datasets[model.id];
          model.set(rawDataset.metadata);
          model.fields.reset(rawDataset.fields);
          model.docCount = rawDataset.documents.length;
          dfd.resolve(model);
        }
        return dfd.promise();
      } else if (method === 'update') {
        var dfd = $.Deferred();
        if (model.__type__ == 'Document') {
          _.each(self.datasets[model.dataset.id].documents, function(doc, idx) {
            if(doc.id === model.id) {
              self.datasets[model.dataset.id].documents[idx] = model.toJSON();
            }
          });
          dfd.resolve(model);
        }
        return dfd.promise();
      } else if (method === 'delete') {
        var dfd = $.Deferred();
        if (model.__type__ == 'Document') {
          var rawDataset = self.datasets[model.dataset.id];
          var newdocs = _.reject(rawDataset.documents, function(doc) {
            return (doc.id === model.id);
          });
          rawDataset.documents = newdocs;
          dfd.resolve(model);
        }
        return dfd.promise();
      } else {
        alert('Not supported: sync on Memory backend with method ' + method + ' and model ' + model);
      }
    },
    query: function(model, queryObj) {
      var dfd = $.Deferred();
      var out = {};
      var numRows = queryObj.size;
      var start = queryObj.from;
      results = this.datasets[model.id].documents;
      _.each(queryObj.filters, function(filter) {
        results = _.filter(results, function(doc) {
          var fieldId = _.keys(filter.term)[0];
          return (doc[fieldId] == filter.term[fieldId]);
        });
      });

not complete sorting!

      _.each(queryObj.sort, function(sortObj) {
        var fieldName = _.keys(sortObj)[0];
        results = _.sortBy(results, function(doc) {
          var _out = doc[fieldName];
          return (sortObj[fieldName].order == 'asc') ? _out : -1*_out;
        });
      });
      out.facets = this._computeFacets(results, queryObj);
      var total = results.length;
      resultsObj = this._docsToQueryResult(results.slice(start, start+numRows));
      _.extend(out, resultsObj);
      out.total = total;
      dfd.resolve(out);
      return dfd.promise();
    },

    _computeFacets: function(documents, queryObj) {
      var facetResults = {};
      if (!queryObj.facets) {
        return facetsResults;
      }
      _.each(queryObj.facets, function(query, facetId) {
        facetResults[facetId] = new recline.Model.Facet({id: facetId}).toJSON();
        facetResults[facetId].termsall = {};
      });

faceting

      _.each(documents, function(doc) {
        _.each(queryObj.facets, function(query, facetId) {
          var fieldId = query.terms.field;
          var val = doc[fieldId];
          var tmp = facetResults[facetId];
          if (val) {
            tmp.termsall[val] = tmp.termsall[val] ? tmp.termsall[val] + 1 : 1;
          } else {
            tmp.missing = tmp.missing + 1;
          }
        });
      });
      _.each(queryObj.facets, function(query, facetId) {
        var tmp = facetResults[facetId];
        var terms = _.map(tmp.termsall, function(count, term) {
          return { term: term, count: count };
        });
        tmp.terms = _.sortBy(terms, function(item) {

want descending order

          return -item.count;
        });
        tmp.terms = tmp.terms.slice(0, 10);
      });
      return facetResults;
    }
  });
  recline.Model.backends['memory'] = new my.Memory();

}(jQuery, this.recline.Backend));