@spalger/kibana
Version:
Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic
196 lines (172 loc) • 5.81 kB
JavaScript
define(function (require) {
return function SearchSourceFactory(Promise, Private) {
var _ = require('lodash');
var SourceAbstract = Private(require('ui/courier/data_source/_abstract'));
var SearchRequest = Private(require('ui/courier/fetch/request/search'));
var SegmentedRequest = Private(require('ui/courier/fetch/request/segmented'));
var searchStrategy = Private(require('ui/courier/fetch/strategy/search'));
var normalizeSortRequest = Private(require('ui/courier/data_source/_normalize_sort_request'));
var rootSearchSource = require('ui/courier/data_source/_root_search_source');
_.class(SearchSource).inherits(SourceAbstract);
function SearchSource(initialState) {
SearchSource.Super.call(this, initialState, searchStrategy);
}
// expose a ready state for the route setup to read
/*****
* PUBLIC API
*****/
/**
* List of the editable state properties that turn into a
* chainable API
*
* @type {Array}
*/
SearchSource.prototype._methods = [
'type',
'query',
'filter',
'sort',
'highlight',
'aggs',
'from',
'size',
'source'
];
SearchSource.prototype.index = function (indexPattern) {
if (indexPattern === undefined) return this._state.index;
if (indexPattern === null) return delete this._state.index;
if (!indexPattern || typeof indexPattern.toIndexList !== 'function') {
throw new TypeError('expected indexPattern to be an IndexPattern duck.');
}
this._state.index = indexPattern;
return this;
};
SearchSource.prototype.extend = function () {
return (new SearchSource()).inherits(this);
};
/**
* Set a searchSource that this source should inherit from
* @param {SearchSource} searchSource - the parent searchSource
* @return {this} - chainable
*/
SearchSource.prototype.inherits = function (parent) {
this._parent = parent;
return this;
};
/**
* Get the parent of this SearchSource
* @return {undefined|searchSource}
*/
SearchSource.prototype.getParent = function (onlyHardLinked) {
var self = this;
if (self._parent === false) return;
if (self._parent) return self._parent;
return onlyHardLinked ? undefined : Private(rootSearchSource).get();
};
/**
* Temporarily prevent this Search from being fetched... not a fan but it's easy
*/
SearchSource.prototype.disable = function () {
this._fetchDisabled = true;
};
/**
* Reverse of SourceAbstract#disable(), only need to call this if source was previously disabled
*/
SearchSource.prototype.enable = function () {
this._fetchDisabled = false;
};
SearchSource.prototype.onBeginSegmentedFetch = function (initFunction) {
var self = this;
return Promise.try(function addRequest() {
var req = new SegmentedRequest(self, Promise.defer(), initFunction);
// return promises created by the completion handler so that
// errors will bubble properly
return req.defer.promise.then(addRequest);
});
};
/******
* PRIVATE APIS
******/
/**
* Gets the type of the DataSource
* @return {string}
*/
SearchSource.prototype._getType = function () {
return 'search';
};
/**
* Create a common search request object, which should
* be put into the pending request queye, for this search
* source
*
* @param {Deferred} defer - the deferred object that should be resolved
* when the request is complete
* @return {SearchRequest}
*/
SearchSource.prototype._createRequest = function (defer) {
return new SearchRequest(this, defer);
};
/**
* Used to merge properties into the state within ._flatten().
* The state is passed in and modified by the function
*
* @param {object} state - the current merged state
* @param {*} val - the value at `key`
* @param {*} key - The key of `val`
* @return {undefined}
*/
SearchSource.prototype._mergeProp = function (state, val, key) {
if (typeof val === 'function') {
var source = this;
return Promise.cast(val(this))
.then(function (newVal) {
return source._mergeProp(state, newVal, key);
});
}
if (val == null || !key || !_.isString(key)) return;
switch (key) {
case 'filter':
// user a shallow flatten to detect if val is an array, and pull the values out if it is
state.filters = _([ state.filters || [], val ])
.flatten()
// Yo Dawg! I heard you needed to filter out your filters
.reject(function (filter) {
return !filter || _.get(filter, 'meta.disabled');
})
.value();
return;
case 'index':
case 'type':
case 'id':
if (key && state[key] == null) {
state[key] = val;
}
return;
case 'source':
key = '_source';
addToBody();
break;
case 'sort':
val = normalizeSortRequest(val, this.get('index'));
addToBody();
break;
default:
addToBody();
}
/**
* Add the key and val to the body of the resuest
*/
function addToBody() {
state.body = state.body || {};
// ignore if we already have a value
if (state.body[key] == null) {
if (key === 'query' && _.isString(val)) {
val = { query_string: { query: val }};
}
state.body[key] = val;
}
}
};
return SearchSource;
};
});