blob: 5f3e3fc41a54baaf0ae0c1d1cca51ae555087349 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Filter} from '../../model/filter';
import {ColumnNamesService} from '../../service/column-names.service';
import {SearchRequest} from '../../model/search-request';
import {SortField} from '../../model/sort-field';
import {TIMESTAMP_FIELD_NAME} from '../../utils/constants';
import {GroupRequest} from '../../model/group-request';
import {Group} from '../../model/group';
import { Injectable } from '@angular/core';
export enum FilteringMode {
MANUAL = 'FilteringModeIsManual',
BUILDER = 'FilteringModeIsBuilder',
}
@Injectable()
export class QueryBuilder {
private _searchRequest = new SearchRequest();
private _groupRequest = new GroupRequest();
private _manualQuery;
private _filters: Filter[] = [];
private filteringMode: FilteringMode = FilteringMode.BUILDER;
get query(): string {
return this.searchRequest.query;
}
set query(value: string) {
this.searchRequest.query = value;
}
get displayQuery(): string {
return this.generateSelectForDisplay();
}
set filters(filters: Filter[]) {
filters.forEach(filter => {
this.addOrUpdateFilter(filter)
});
}
get filters(): Filter[] {
return this._filters;
}
get searchRequest(): SearchRequest {
this._searchRequest.query = this.getQueryString() || '*';
return this._searchRequest;
}
set searchRequest(value: SearchRequest) {
this._searchRequest = value;
this.setSearch(this._searchRequest.query);
}
groupRequest(scoreField): GroupRequest {
this._groupRequest.query = this.getQueryString() || '*';
this._groupRequest.scoreField = scoreField;
return this._groupRequest;
}
setSearch(query: string) {
this.updateFilters(query, true);
}
clearSearch() {
this._filters = [];
this._manualQuery = null;
}
addOrUpdateFilter(filter: Filter) {
let existingFilterIndex = -1;
if (filter.field === TIMESTAMP_FIELD_NAME) {
const existingTimeRangeFilter = this.filters.find(fItem => fItem.field === TIMESTAMP_FIELD_NAME);
if (existingTimeRangeFilter) {
this.removeFilter(existingTimeRangeFilter);
}
this._filters.push(filter);
return;
}
let existingFilter = this._filters.find((tFilter, index) => {
if (filter.equals(tFilter)) {
existingFilterIndex = index;
return true;
}
return false;
});
if (existingFilter) {
this._filters.splice(existingFilterIndex, 1, filter);
} else {
this._filters.push(filter);
}
}
private getQueryString() {
if (this.filteringMode === FilteringMode.MANUAL) {
return this.getManualQuery();
} else {
return this.getBuilderQueryString();
}
}
private getBuilderQueryString() {
return this._filters.map(filter => filter.getQueryString()).join(' AND ');
}
generateNameForSearchRequest() {
let select = this._filters.map(filter => ColumnNamesService.getColumnDisplayValue(filter.field) + ':' + filter.value).join(' AND ');
return (select.length === 0) ? '*' : select;
}
generateSelectForDisplay() {
return this._filters.reduce((appliedFilters, filter) => {
if (filter.display) {
appliedFilters.push(ColumnNamesService.getColumnDisplayValue(filter.field) + ':' + filter.value);
}
return appliedFilters;
}, []).join(' AND ') || '*';
}
isTimeStampFieldPresent(): boolean {
return this._filters.some(filter => (filter.field === TIMESTAMP_FIELD_NAME && !isNaN(Number(filter.value))));
}
removeFilter(filter: Filter) {
this._filters = this._filters.filter(fItem => fItem !== filter );
}
removeFilterByField(field: string): void {
this._filters = this._filters.filter(fItem => fItem.field !== field );
}
setFromAndSize(from: number, size: number) {
this.searchRequest.from = from;
this.searchRequest.size = size;
}
setGroupby(groups: string[]) {
this._groupRequest.groups = groups.map(groupName => new Group(groupName));
}
setSort(sortBy: string, order: string) {
let sortField = new SortField(sortBy, order);
this.searchRequest.sort = [sortField];
}
setFilteringMode(mode: FilteringMode) {
this.filteringMode = mode;
}
getFilteringMode() {
return this.filteringMode;
}
setManualQuery(query: string) {
this._manualQuery = query;
}
getManualQuery(): string {
if (!this._manualQuery) {
this._manualQuery = this.getBuilderQueryString() || '*';
}
return this._manualQuery;
}
private updateFilters(query: string, updateNameTransform = false) {
this.removeDisplayedFilters();
if (query && query !== '' && query !== '*') {
let terms = query.split(' AND ');
for (let term of terms) {
let [field, value] = this.splitTerm(term);
field = updateNameTransform ? ColumnNamesService.getColumnDisplayKey(field) : field;
value = value.trim();
this.addOrUpdateFilter(new Filter(field, value));
}
}
}
private splitTerm(term): string[] {
const lastIdxOfSeparator = term.lastIndexOf(':');
return [ term.substring(0, lastIdxOfSeparator), term.substring(lastIdxOfSeparator + 1) ];
}
private removeDisplayedFilters() {
for (let i = this._filters.length - 1; i >= 0; i--) {
if (this._filters[i].display) {
this._filters.splice(i, 1);
}
}
}
}