Commit b427c5c8 authored by rafaelatc3sl's avatar rafaelatc3sl

Issue #90: Add class Query

Signed-off-by: 's avatarrafaelatc3sl <rpd17@c3sl>
parent 10dabda1
Pipeline #18624 passed with stages
in 1 minute and 20 seconds
......@@ -20,7 +20,7 @@
import * as express from "express";
import { Request } from "../types";
import { Query } from "../../common/query";
import { Query, QueryOpts } from "../../common/query";
/**
* Constroller responsable for data part from the API. In other
......@@ -48,7 +48,8 @@ export class DataCtrl {
let view;
try {
let query: Query = { metrics: [], dimensions: [], clauses: [], sort: [] };
const qOpt: QueryOpts = { metrics: [], dimensions: []};
let query = new Query(qOpt);
for (let i = 0; i < metrics.length; ++i) {
query.metrics.push(req.engine.getMetricByName(metrics[i]));
}
......
......@@ -25,7 +25,7 @@ import { Clause } from "../core/clause";
/**
* Internal representation of a query in BlenDB perspective.
*/
export interface Query {
export interface QueryOpts {
/** Set of metrics of the query. */
metrics: Metric[];
/** Set of dimensions of the query. */
......@@ -35,3 +35,24 @@ export interface Query {
/** List of metrics and dimensions to sort the query. */
sort?: (Metric|Dimension)[];
}
export class Query {
/** Set of metrics of the query. */
public readonly metrics: Metric[];
/** Set of dimensions of the query. */
public readonly dimensions: Dimension[];
/** Set of clauses of the query. */
public readonly clauses: Clause[];
/** List of metrics and dimensions to sort the query. */
public readonly sort: (Metric|Dimension)[];
/**
* Create Query
* @param opts - Parameters required to create a query.
*/
constructor(opts: QueryOpts){
this.metrics = opts.metrics.map((i) => i);
this.dimensions = opts.dimensions.map((i) => i);
this.clauses = (opts.clauses) ? opts.clauses.map((i) => i) : [];
this.sort = (opts.sort) ? opts.sort.map((i) => i) : [];
}
}
......@@ -23,7 +23,7 @@ import { Metric, MetricStrOptions } from "./metric";
import { Clause } from "./clause";
import { Filter } from "./filter";
import { View } from "./view";
import { Query } from "../common/query";
import { Query, QueryOpts } from "../common/query";
import { Graph } from "../util/graph";
import { EnumType, EnumTypeOptions} from "./enumType";
import { Source , SourceStrOptions } from "./source";
......@@ -278,14 +278,14 @@ export class Engine {
*/
private selectOptimalView (q: Query): View {
let queries: Query[] = [];
let qOpt: QueryOpts;
if (q.metrics.length > 0) {
for (let i = 0; i < q.metrics.length; ++i) {
queries.push({
metrics: [q.metrics[i]],
qOpt = { metrics: [q.metrics[i]],
dimensions: q.dimensions,
clauses: (q.clauses) ? q.clauses : [],
sort: (q.sort) ? q.sort : []
});
clauses: q.clauses,
sort: q.sort };
queries.push(new Query(qOpt));
}
const views = queries.map((query) => {
return ViewHandler.growView(query, this.getCover(query));
......@@ -295,12 +295,7 @@ export class Engine {
}
else {
let query = {
metrics: q.metrics,
dimensions: q.dimensions,
clauses: (q.clauses) ? q.clauses : [],
sort: (q.sort) ? q.sort : []
};
let query = new Query(q);
return ViewHandler.growView(query, this.getCover(query));
}
......
......@@ -27,7 +27,7 @@ import { Filter, FilterOperator } from "../core/filter";
import { Clause } from "../core/clause";
import { Graph } from "./graph";
import { AggregationType, RelationType, DataType } from "../common/types";
import { Query } from "../common/query";
import { Query, QueryOpts } from "../common/query";
describe("graph class", () => {
......@@ -193,7 +193,8 @@ describe("graph class", () => {
});
expect(g.addView(view)).to.be.true;
const query: Query = { metrics: [], dimensions: [dim] };
const qOpts: QueryOpts = {metrics: [], dimensions: [dim]};
const query = new Query (qOpts);
let children = g.cover(query);
expect(children).to.be.an("array");
expect(children).to.have.length(1);
......@@ -256,8 +257,8 @@ describe("graph class", () => {
for (let i = 0; i < views.length; ++i) {
expect(g.addView(views[i])).to.be.true;
}
const query: Query = { metrics: [mets[0], mets[1]], dimensions: [dims[0], dims[1]] };
const qOpts: QueryOpts = { metrics: [mets[0], mets[1]], dimensions: [dims[0], dims[1]]};
const query = new Query(qOpts);
let children = g.cover(query);
expect(children).to.be.an("array");
expect(children).to.have.length(1);
......@@ -295,8 +296,8 @@ describe("graph class", () => {
});
expect(g.addView(view)).to.be.true;
const query: Query = { metrics: [], dimensions: [dims[1], dims[2]] };
const qOpts: QueryOpts = { metrics: [], dimensions: [dims[1], dims[2]]};
const query = new Query(qOpts);
let children = g.cover(query);
expect(children).to.be.an("array");
expect(children).to.have.length(1);
......@@ -334,8 +335,8 @@ describe("graph class", () => {
});
expect(g.addView(view)).to.be.true;
const query: Query = { metrics: [], dimensions: [] };
const qOpts: QueryOpts = { metrics: [], dimensions: []};
const query = new Query(qOpts);
let children = g.cover(query);
expect(children).to.be.an("array");
expect(children).to.be.empty;
......@@ -389,8 +390,8 @@ describe("graph class", () => {
expect(g.addView(view1)).to.be.true;
expect(g.addView(view2)).to.be.true;
expect(g.addView(view3)).to.be.true;
const query: Query = { metrics: [], dimensions: dims, clauses: [clause2] };
const qOpts: QueryOpts = { metrics: [], dimensions: dims, clauses: [clause2]};
const query = new Query(qOpts);
let children = g.cover(query);
expect(children).to.be.an("array");
expect(children).to.have.length(2);
......@@ -502,8 +503,8 @@ describe("graph class", () => {
});
expect(g.addView(view0)).to.be.true;
const query: Query = { metrics: [], dimensions: dims, clauses: testClauses };
const qOpts: QueryOpts = { metrics: [], dimensions: dims, clauses: testClauses};
const query = new Query(qOpts);
let children = g.cover(query);
expect(children).to.have.length(1);
expect(children[0].id === view0.id).to.be.true;
......@@ -626,8 +627,8 @@ describe("graph class", () => {
for (let i = 0; i < views.length; ++i) {
expect(g.addView(views[i])).to.be.true;
}
const query: Query = { metrics: [], dimensions: dims, clauses: testClauses };
const qOpts: QueryOpts = { metrics: [], dimensions: dims, clauses: testClauses};
const query = new Query(qOpts);
let children = g.cover(query);
expect(children).to.have.length(1);
expect(children[0].id === views[0].id).to.be.true;
......
......@@ -321,7 +321,7 @@ export class Graph {
public cover(q: Query): View[] {
const metrics = q.metrics;
const dimensions = q.dimensions;
const clauses = (q.clauses) ? q.clauses : [];
const clauses = q.clauses;
let output: View[] = [];
let verticesIds = this.verticesInQuery(q);
......@@ -621,7 +621,7 @@ export class Graph {
private verticesInQuery(q: Query): string[] {
const metrics = q.metrics;
const dimensions = q.dimensions;
const clauses = (q.clauses) ? q.clauses : [];
const clauses = q.clauses;
let verticesIds = metrics.map((met) => met.name);
verticesIds = verticesIds.concat(dimensions.map((dim) => dim.name));
for (let i = 0; i < clauses.length; ++i) {
......
......@@ -21,7 +21,7 @@
import { Opcode } from "../common/expression";
import { View } from "../core/view";
import { Clause } from "../core/clause";
import { Query } from "../common/query";
import { Query, QueryOpts } from "../common/query";
import { Dimension } from "../core/dimension";
import { Metric } from "../core/metric";
......@@ -60,8 +60,8 @@ export class ViewHandler {
metrics: q.metrics,
dimensions: q.dimensions,
origin: false,
clauses: (q.clauses) ? q.clauses : [],
sort: (q.sort) ? q.sort : [],
clauses: q.clauses,
sort: q.sort,
operation: {
opcode: Opcode.JOIN,
values: views.map((i) => i)
......@@ -85,8 +85,8 @@ export class ViewHandler {
metrics: q.metrics,
dimensions: q.dimensions,
origin: false,
clauses: (q.clauses) ? q.clauses : [],
sort: (q.sort) ? q.sort : [],
clauses: q.clauses,
sort: q.sort,
operation: {
opcode: Opcode.REDUCE,
values: [view]
......@@ -109,17 +109,16 @@ export class ViewHandler {
let metView: View = null;
let partialJoin: View[] = null;
let reduced: ViewsAndClauses = null;
let partialQuery: Query = {
metrics: q.metrics,
dimensions: q.dimensions,
clauses: q.clauses,
sort: q.sort
};
let qOpt: QueryOpts;
let partialQuery = new Query(q);
partialJoin = views.map((i) => (i));
if (q.metrics.length === 0) { // ignore metView if there are 0 metrics
while (partialJoin.length > 1) {
partialQuery.clauses = clausesToCover;
qOpt = {metrics: partialQuery.metrics, dimensions: partialQuery.dimensions, clauses: clausesToCover};
partialQuery = new Query(qOpt);
reduced = ViewHandler.applyReduce(partialJoin, partialQuery);
clausesToCover = reduced.clauses;
partialJoin = ViewHandler.applyJoin(reduced.views);
......@@ -137,7 +136,8 @@ export class ViewHandler {
partialJoin.splice(metViewId, 1);
while (partialJoin.length > 1) {
partialJoin.push(metView); // MetView is now the last view
partialQuery.clauses = clausesToCover;
qOpt = {metrics: partialQuery.metrics, dimensions: partialQuery.dimensions, clauses: clausesToCover};
partialQuery = new Query(qOpt);
reduced = ViewHandler.applyReduce(partialJoin, partialQuery);
clausesToCover = reduced.clauses;
metView = reduced.views.pop();
......@@ -153,7 +153,8 @@ export class ViewHandler {
// In this case, there are exactly 2 views
reduced = ViewHandler.applyReduce(partialJoin, partialQuery);
partialJoin = ViewHandler.applyJoin(reduced.views);
partialQuery.clauses = reduced.clauses;
qOpt = {metrics: partialQuery.metrics, dimensions: partialQuery.dimensions, clauses: reduced.clauses};
partialQuery = new Query(qOpt);
return ViewHandler.applyReduce(partialJoin, partialQuery).views[0];
}
}
......@@ -355,11 +356,9 @@ export class ViewHandler {
let clauses = partial0.clauses.concat(partial1.clauses);
clauses = ViewHandler.removeDuplicatedClauses(clauses);
const partialQuery: Query = {
metrics: mets,
dimensions: dims,
clauses: clauses
};
const qOpts: QueryOpts = {metrics: mets, dimensions: dims, clauses: clauses};
const partialQuery = new Query(qOpts);
const partial = ViewHandler.queryJoin(partialQuery, [partial0, partial1]);
views.push(partial);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment