API Docs for: 0.1.0.ee3e9e64
Show:

File: addon/lib/handlers.js

/**
  @module solr
*/

import Ember from 'ember';
import SolrCommitType from './commit-type';

const get = Ember.get,
      set = Ember.set;

/**
  An enumeration of handler types that `ember-solr`
  knows how to interact with.

  @class SolrHandlerType
  @static
*/
const SolrHandlerType = {
  /**
    Represents a requst to `select`, `search` and
    other standard request handlers.

    This is the handler type that will be used in
    `findQuery`, and when real-time get is not enabled
    it will also be used in all `find*` operations.

    See [SearchHandler](http://wiki.apache.org/solr/SearchHandler).

    @property Search
    @final
    @type {string}
  */
  Search: 'SolrHandlerType.Search',

  /**
    Represents a requst to `get` and
    other real time get handlers.

    This is the handler type that will be used when
    {{#crossLink "SolrAdapter/enableRealTimeGet:property"}}{{/crossLink}}
    is set to `true` for `find`, and `findMany`.

    See [RealTimeGet](http://wiki.apache.org/solr/RealTimeGet).

    @property RealTimeGet
    @final
    @type {string}
  */
  RealTimeGet: 'SolrHandlerType.RealTimeGet',

  /**
    Represents a requst to [UpdateRequestProcessor](http://wiki.apache.org/solr/UpdateRequestProcessor)

    @property RealTimeGet
    @final
    @type {string}
  */
  Update: 'SolrHandlerType.Update'
};

/**
  An abstract representation of a Solr request
  handler, including its type, path and HTTP method.
  @class SolrRequestHandler
*/
const SolrRequestHandler = Ember.Object.extend({
  /**
    The type of request.

    @property type
    @type {SolrHandlerType}
  */
  type: null,

  /**
    The path to route the request to. Typical
    examples include handler paths like `/search`,
    `/select`, `/get`, and `/update`.

    @property path
    @type {string}
  */
  path: null,

  /**
    The HTTP method (verb) to use in the request.

    @property method
    @type {string}
    @default 'GET'
  **/
  method: 'GET',

  /**
    The data payload to send in the request, as
    a query string or as a JSON request body.

    @property data
    @type {object}
    @default null
  */
  data: null,

  /**
    Prepares the
    {{#crossLink "SolrRequestHandler/data:property"}}{{/crossLink}}
    and optinally adjusts the
    {{#crossLink "SolrRequestHandler/path:property"}}{{/crossLink}}
    properties to send to Solr as a querystring
    or in an HTTP POST request body.

    This method mutates the state of the instance it is invoked
    on and has no return value.

    @method buildPayload
    @param {SolrAdapter} adapter the adapter invoking this method
    @param {DS.Store} the store related to the type and data
    @param {subclass of DS.Model} type the type corresponding to the operation
    @param {string} operation the operation e.g. 'find', 'updateRecord', etc.
    @param {object} data the ID(s), query or snapshot payload to prepare.
  */
  prepare: function(/*adapter, store, type, operation, data*/) {
    throw new Error('The method `buildPayload` must be overridden by a subclass.');
  }
});

/**
  Represents a default configuration of a request
  to a Solr search handler.

  @class SolrSearchHandler
  @extends SolrRequestHandler
*/
const SolrSearchHandler = SolrRequestHandler.extend({
  /**
    @property type
    @default `SolrHandlerType.Search`
  */
  type: SolrHandlerType.Search,

  /**
    @property path
    @default 'select'
  */
  path: 'select',

  prepare: function(adapter, store, type, operation, data) {
    data = data || {};
    var key = adapter.uniqueKeyForType(type);

    if (Array.isArray(data)) {
      var query = data.map(function(id) {
        return key + ':' + id;
      }).join(' OR ');

      data = {
        q: query
      };
    } else if (typeof data !== 'object') {
      data = {
        q: key + ':' + data
      };
    }

    data = this.buildSolrQuery(adapter, store, type, operation, data);
    set(this, 'data', data);
  },

  /**
    Builds a Solr query to send in a search request.
    This method applies some defaults and converts
    idiomatic Ember query parameters to their
    Solr corollaries.

    * Sets `wt=json`
    * Converts `limit` to `rows`
    * Converts `offset` to `start`
    * Defaults to `q=*:*` when no query is specified
    * Calls {{#crossLink "SolrAdapter/filterQueryForType:method"}}{{/crossLink}}
    and sets `fq` when a non-blank filter query is returned

    Overrides of this method can return an object that includes
    other query options. Multipe `fq` parameters (and others)
    can be defined by using an array for the values:
    ```javascript
    App.ApplicationAdapter = SolrAdapter.extend({
      buildSolrQuery: function(type, query) {
        return {
          fq: [
            'type:' + type,
            'public:true'
          ]
        };
      }
    });
    ```

    See [QueryResponseWriter](https://wiki.apache.org/solr/QueryResponseWriter)
    and [CommonQueryParameters](https://wiki.apache.org/solr/CommonQueryParameters).

    @method buildSolrQuery
    @param {SolrAdapter} adapter the adapter invoking this method
    @param {String} type
    @param {String} operation
    @param {Object} query
    @return {Object} data hash for ajax request
    @protected
  */
  buildSolrQuery: function(adapter, store, type, operation, query) {
    var solrQuery = {
      wt: 'json'
    };

    if (query.limit) {
      solrQuery.rows = query.limit;
    }

    if (query.offset) {
      solrQuery.start = query.offset;
    }

    var typeFilter = !!adapter.filterQueryForType ? adapter.filterQueryForType(type, operation) : null;
    if (typeFilter) {
      solrQuery.fq = typeFilter;
    }

    solrQuery.q = query.q || '*:*';

    return solrQuery;
  },
});

/**
  Represents a default configuration of a request
  to a Solr Real Time Get handler.

  @class SolrRealTimeGetHandler
*/
const SolrRealTimeGetHandler = SolrRequestHandler.extend({
  /**
    @property type
    @default `SolrHandlerType.RealTimeGet`
  */
  type: SolrHandlerType.RealTimeGet,

  /**
    @property path
    @default 'get'
  */
  path: 'get',

  prepare: function(adapter, store, type, operation, data) {
    var key = adapter.uniqueKeyForType(type);
    var payload = {};
    payload[key] = data;
    set(this, 'data', payload);
  }
});

/**
  Represents a default configuration of a request
  to a Solr Update Request Processor.

  @class SolrUpdateHandler
*/
const SolrUpdateHandler = SolrRequestHandler.extend({
  /**
    @property type
    @default `SolrHandlerType.RealTimeGet`
  */
  type: SolrHandlerType.Update,

  /**
    @property path
    @default 'get'
  */
  path: 'update',

  /**
    @property method
    @default 'POST'
  */
  method: 'POST',

  prepare: function(adapter, store, type, operation, data) {
    data = {
      add: {
        doc: data
      }
    };

    var commitWithin = get(adapter, 'commitWithinMilliseconds');
    var commit = get(adapter, 'commit');

    if (commitWithin > 0) {
      data.add.commitWithin = commitWithin;
    } else if (commit === SolrCommitType.Hard) {
      data.commit = {};
    } else if (commit === SolrCommitType.Soft) {
      data.commit = {softCommit: true};
    }

    set(this, 'data', data);
  }
});

/**
  Represents a default configuration of a request
  to a Solr Update Request Processor for deleting
  a document by ID.

  @class SolrDeleteHandler
*/
const SolrDeleteHandler = SolrUpdateHandler.extend({
  prepare: function(adapter, store, type, operation, data) {
    var payload = {
      'delete': {}
    };

    payload['delete'][adapter.uniqueKeyForType(type)] = data.id;

    var versionFieldName = get(store.serializerFor(type), 'versionFieldName');
    if (versionFieldName && typeof data[versionFieldName] !== 'undefined') {
      var path = get(this, 'path');
      path += (path.indexOf('?') > 0) ? '&' : '?';
      path += versionFieldName + '=' + data[versionFieldName];
      set(this, 'path', path);
    }

    var commit = get(adapter, 'commit');

    if (commit === SolrCommitType.Hard) {
      payload.commit = {};
    } else if (commit === SolrCommitType.Soft) {
      payload.commit = {softCommit: true};
    }

    set(this, 'data', payload);
  }
});

export {
  SolrHandlerType,
  SolrRequestHandler,
  SolrSearchHandler,
  SolrRealTimeGetHandler,
  SolrUpdateHandler,
  SolrDeleteHandler
};