diff --git a/src/adapter/postgresAdapter.ts b/src/adapter/postgresAdapter.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1e8cae4bafc475b1171e98b5caac23f6c76b178d
--- /dev/null
+++ b/src/adapter/postgresAdapter.ts
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { View } from "../core/view";
+import { Adapter } from "../core/adapter";
+import { AggregationType } from "../common/aggregationType";
+
+interface ParsedView {
+    query: string;
+    view: View;
+    alias: string;
+};
+
+export class PostGresAdapter extends Adapter{
+    public getDataFromView(view: View): string {
+        return this.queryfyView(view, "v0");
+    }
+
+    public materializeView(view: View): string {
+        return null;
+    }
+
+    private queryfyView (view: View, alias: string, degree: number = 0): string {
+        let ident = "    ".repeat(degree + 1);
+        let lessIdent  =  "    ".repeat(degree);
+        let sql: string = lessIdent + "(\n";
+        let metrics: string[] = view.metrics.map((metric: string) => {
+            let func: string = this.metricFunction(view, metric);
+            let extMetric: string = func + "(" + metric + ")";
+            return extMetric;
+        });
+        let dimensions: string[] = view.dimensions.map((item: string) => {
+            return alias + "." + item;
+        });
+        if (view.materialized) {
+            sql += ident + "SELECT " + metrics.join(", ") + ", " + dimensions.join(", ") + "\n";
+            sql += ident + "FROM " + view.id + "\n";
+            sql += ident + "GROUP BY " + dimensions.join(", ") + "\n";
+            sql += lessIdent + ") AS " + alias + "\n";
+        }
+
+        else {
+            let children: ParsedView[] = view.childViews.map((item: View, idx: number) => {
+                let childAlias: string = "v" + idx;
+                return {
+                    query: this.queryfyView(item, childAlias, degree + 1),
+                    view: item,
+                    alias: childAlias
+                };
+            });
+
+            let covered: Map<string, string> = new Map();
+            view.dimensions.forEach((item: string) => covered.set(item, ""));
+            view.metrics.forEach((item: string) => covered.set(item, ""));
+
+            let projection: string = ident + "SELECT ";
+            let viewsFrom: string = ident + "FROM";
+            let selection: string = ident + "WHERE ";
+            let grouping: string = ident + "GROUP BY ";
+
+            let elements: string[] = [];
+            let group: string[] = [];
+
+            children.forEach((child: ParsedView) => {
+                let selected: string[] = [];
+                child.view.dimensions.forEach((dimension: string) => {
+                    let first: string = covered.get(dimension);
+                    let extDimension = child.alias + "." + dimension;
+                    if (first === "") {
+                        covered.set(dimension, child.alias);
+                        elements.push(extDimension);
+                        group.push(extDimension);
+                    }
+
+                    else {
+                        let extFirst = first + "." + dimension;
+                        selected.push(extDimension + " = " + extFirst);
+                    }
+                });
+
+                child.view.metrics.forEach((metric: string) => {
+                    let first: string = covered.get(metric);
+                    let func: string = this.metricFunction(child.view, metric);
+                    let extMetric: string = func + "(" + child.alias + "." + metric + ")";
+                    if (first === "") {
+                        covered.set(metric, child.alias);
+                        elements.push(extMetric);
+                    }
+
+                });
+
+                viewsFrom += "\n" + child.query;
+
+                if (selected.length > 0) {
+                    selection += selected.join(" AND ");
+                }
+            });
+
+            projection += elements.join(", ") + "\n";
+            selection += "\n";
+            grouping += group.join(", ") + "\n";
+            alias += "\n";
+
+            sql += projection + viewsFrom + selection + grouping + lessIdent + ") AS " + alias;
+        }
+
+        return sql;
+    }
+
+    private metricFunction(view: View, metric: string): string{
+        let map: Map<string, AggregationType> = view.aggregationMap;
+        let func: string = "";
+        if (map.has(metric)) {
+            switch (map.get(metric)) {
+                case AggregationType.SUM:
+                    func =  "SUM";
+                    break;
+                case AggregationType.AVG:
+                    func = "AVG";
+                    break;
+                case AggregationType.COUNT:
+                    func = "COUNT";
+                    break;
+                default:
+                    func =  "";
+                    break;
+            }
+        }
+
+        return func;
+    }
+}
diff --git a/src/common/aggregationType.ts b/src/common/aggregationType.ts
new file mode 100644
index 0000000000000000000000000000000000000000..23b6f0b191393716f7f59efa43e036ae9b492a6c
--- /dev/null
+++ b/src/common/aggregationType.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ export enum AggregationType {
+    SUM,
+    AVG,
+    COUNT
+ };
diff --git a/src/common/query.ts b/src/common/query.ts
new file mode 100644
index 0000000000000000000000000000000000000000..70a46d5b749af87c11468de0bc53e47cea137b67
--- /dev/null
+++ b/src/common/query.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+export interface Query {
+    public metrics: string[];
+    public dimensions: string[];
+
+}
diff --git a/src/core/adapter.ts b/src/core/adapter.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f2981953b9f362da9e07cdab004454865facc304
--- /dev/null
+++ b/src/core/adapter.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { View } from "./view";
+
+export abstract class Adapter {
+    public abstract getDataFromView(view: View): string;
+    public abstract materializeView(view: View): string;
+}
diff --git a/src/core/engine.spec.ts b/src/core/engine.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..94c6456d49dcd78de71b7ccb263f076bb3abcfdc
--- /dev/null
+++ b/src/core/engine.spec.ts
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blendb.
+ *
+ * blendb is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blendb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blendb.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { expect } from "chai";
+
+import { Engine } from "./engine";
+import { View } from "./view";
+import { ViewOptions } from "./view";
+import { Query } from "../common/query";
+import { AggregationType } from "../common/aggregationType";
+
+describe("engine class", () => {
+    let query: Query = {
+        metrics: [],
+        dimensions: []
+    };
+
+    let views: View[] = [];
+
+    let viewBuilder: Query[] = [
+        { metrics: ["met:1", "met:2", "met:3"], dimensions: ["dim:1", "dim:2"]},
+        { metrics: ["met:1", "met:3", "met:5"], dimensions: ["dim:1", "dim:2"]},
+        { metrics: ["met:3", "met:4", "met:7"], dimensions: ["dim:4", "dim:5"]},
+        { metrics: ["met:6", "met:7"], dimensions: ["dim:3", "dim:4", "dim:5", "dim:6"]},
+        { metrics: ["met:8", "met:2", "met:3"], dimensions: ["dim:1", "dim:2", "dim:7"]},
+        { metrics: ["met:1", "met:2", "met:3"], dimensions: ["dim:1", "dim:2"]},
+        { metrics: ["met:2", "met:4"], dimensions: ["dim:1", "dim:2"]},
+        { metrics: ["met:8"], dimensions: ["dim:8", "dim:9", "dim:10"]},
+        { metrics: ["met:9"], dimensions: ["dim:8", "dim:9", "dim:10"]},
+        { metrics: ["met:10"], dimensions: ["dim:8", "dim:9", "dim:10"]}
+    ];
+
+    let iterable: [string, AggregationType][] = [
+        ["met:1", AggregationType.SUM],
+        ["met:2", AggregationType.AVG],
+        ["met:3", AggregationType.AVG],
+        ["met:4", AggregationType.SUM],
+        ["met:5", AggregationType.SUM],
+        ["met:6", AggregationType.AVG],
+        ["met:7", AggregationType.COUNT],
+        ["met:8", AggregationType.COUNT],
+        ["met:9", AggregationType.SUM],
+        ["met:10", AggregationType.COUNT],
+    ];
+
+    let map: Map<string, AggregationType> = new Map(iterable);
+
+    for (let i: number = 0; i < 10; ++ i) {
+        query.metrics.push("met:" + (i + 1));
+        query.dimensions.push("dim:" + (i + 1));
+        let options: ViewOptions = {
+            metrics: viewBuilder[i].metrics,
+            dimensions: viewBuilder[i].dimensions,
+            materialized: true,
+            aggregationMap: map,
+            childViews: []
+        };
+        views.push(new View (options));
+    }
+
+    views.push(new View({
+        metrics: ["met:1", "met:2", "met:3", "met:4", "met:5"],
+        dimensions: ["dim:1", "dim:2"],
+        materialized: false,
+        aggregationMap: map,
+        childViews: [views[0], views[6]]
+    }));
+
+    views.push(new View({
+        metrics: ["met:8", "met:9", "met:10"],
+        dimensions: ["dim:8", "dim:9", "dim:10"],
+        materialized: false,
+        aggregationMap: map,
+        childViews: [views[7], views[8], views[9]]
+    }));
+
+    it("should be create a fill that cover the query and has 4 children", () => {
+        let engine: Engine = new Engine (views);
+        let optimalView = engine.query(query);
+        expect(optimalView).to.be.an("object");
+        expect(optimalView).to.have.property("metrics");
+        expect(optimalView).to.have.property("dimensions");
+        expect(optimalView).to.have.property("childViews");
+        expect(optimalView.metrics).to.be.an("array");
+        expect(optimalView.dimensions).to.be.an("array");
+        expect(optimalView.childViews).to.be.an("array");
+        expect(optimalView.metrics.length === 10);
+        expect(optimalView.dimensions.length === 10);
+        expect(optimalView.childViews.length === 4);
+        let metAux: number[] = optimalView.metrics.sort().map((item: string) => {
+            return Number(item.split(":")[1]);
+        });
+        let dimAux: number[] = optimalView.dimensions.sort().map((item: string) => {
+            return Number(item.split(":")[1]);
+        });
+        for (let i: number = 1; i <= 10; ++i) {
+            expect(dimAux[i] === i);
+            expect(metAux[i] === i);
+        }
+    });
+    it("should throw an exception, query with non-existent metric", () => {
+        let engine: Engine = new Engine (views);
+        let error: boolean = false;
+        try {
+            engine.query({metrics: ["met:11"], dimensions: ["dim:1"]});
+        }
+        catch (e){
+            error = true;
+            expect(e.message).to.be.equal("Engine views cannot cover the query");
+
+        }
+        expect(error);
+    });
+
+    it("should throw an exception, query with non-existent dimension", () => {
+        let engine: Engine = new Engine (views);
+        let error: boolean = false;
+        try {
+            engine.query({metrics: ["met:1"], dimensions: ["dim:11"]});
+        }
+        catch (e){
+            error = true;
+            expect(e.message).to.be.equal("Engine views cannot cover the query");
+
+        }
+        expect(error);
+    });
+});
diff --git a/src/core/engine.ts b/src/core/engine.ts
new file mode 100644
index 0000000000000000000000000000000000000000..55057a96165f158e9d7af24fb45791c1225285c0
--- /dev/null
+++ b/src/core/engine.ts
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { Query } from "../common/query";
+import { View } from "./view";
+import { ViewOptions } from "./view";
+import { AggregationType } from "../common/aggregationType";
+
+export class Engine {
+    private views: View[];
+
+    constructor (v: View[]) {
+        this.views = v;
+    }
+
+    public query (q: Query) { return this.selectOptimalView(q); }
+    public insert (data: any) { /*to Implement*/ }
+    private selectOptimalView (q: Query) {
+        let objective: string[] = q.metrics.concat(q.dimensions);
+        let optimalViews: View[] = [];
+        let activeViews: View[] = this.views;
+
+        while (objective.length  > 0) {
+            let actual: View;
+            let actualDistance: number = objective.length + 1;
+            activeViews = activeViews.filter((view: View) => {
+                let intersection: string[] = [];
+                let cover: string[] = view.metrics.concat(view.dimensions);
+                intersection = cover.filter((item: string) => {
+                    return objective.indexOf(item) !== -1;
+                });
+
+                if (intersection.length > 0) {
+                    let distance: number = objective.length - intersection.length;
+
+                    if (distance < actualDistance) {
+                        actual = view;
+                        actualDistance = distance;
+                    }
+                    return true;
+                }
+
+                return false;
+            });
+
+            if (actualDistance  === objective.length + 1) {
+                throw new Error ("Engine views cannot cover the query");
+            }
+
+            optimalViews.push(actual);
+            objective = objective.filter((item: string) => {
+                let aux: string[] = actual.dimensions.concat(actual.metrics);
+                return aux.indexOf(item) === -1;
+            });
+        }
+
+        if (optimalViews.length === 1) {
+            return optimalViews.pop();
+        }
+
+        else {
+            let map: Map<string, AggregationType> = new Map();
+            optimalViews.forEach((view: View) => {
+                view.aggregationMap.forEach((value: AggregationType, key: string) => {
+                    map.set(key, value);
+                });
+            });
+
+            let options: ViewOptions = {
+                metrics: q.metrics,
+                dimensions: q.dimensions,
+                materialized: false,
+                aggregationMap: map,
+                childViews: optimalViews
+            };
+
+            let view: View = new View(options);
+            this.views.push(view);
+            return view;
+        }
+    }
+}
diff --git a/src/core/view.ts b/src/core/view.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4c0131a4ef1f9584aa6b2b83c140746287bb190f
--- /dev/null
+++ b/src/core/view.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana
+ *
+ * This file is part of blend.
+ *
+ * blend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * blend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with blend.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { Hash } from "../util/hash";
+import { AggregationType } from "../common/aggregationType";
+
+export interface ViewOptions {
+    metrics: string[];
+    dimensions: string[];
+    materialized: boolean;
+    aggregationMap: Map <string, AggregationType>;
+    childViews: View[];
+}
+
+export class View {
+    public readonly id: string;
+    public readonly metrics: string[];
+    public readonly dimensions: string[];
+    public readonly materialized: boolean;
+    public readonly aggregationMap: Map<string, AggregationType>;
+
+    public childViews: View[];
+
+    constructor (options: ViewOptions) {
+        this.metrics = options.metrics;
+        this.dimensions = options.dimensions;
+        this.materialized = options.materialized;
+        this.childViews = options.childViews;
+        this.aggregationMap = options.aggregationMap;
+        this.id = "view_" + Hash.sha1(options.metrics.sort(), options.dimensions.sort());
+    }
+
+}