Skip to content
Snippets Groups Projects
Commit 94281780 authored by Rafael Dias's avatar Rafael Dias
Browse files

Issue #83:Fix test Monet and Postgres


Signed-off-by: default avatarRafael <rpd17@inf.ufpr.br>
parent 1e9df086
No related branches found
No related tags found
No related merge requests found
Pipeline #
...@@ -118,6 +118,29 @@ export class MonetAdapter extends SQLAdapter { ...@@ -118,6 +118,29 @@ export class MonetAdapter extends SQLAdapter {
}); });
pool.close(); pool.close();
} }
/**
* Asynchronously executes a query from Source and get its resut
* @param query - Query (SQL format) to be executed.
* @param cb - Callback function which contains the data read.
* @param cb.error - Error information when the method fails.
* @param cb.result - Query result.
*/
private executeQuerySource(query: string, cb: (error: Error, result?: any[]) => void): void {
let pool: any = new MDB(this.config);
pool.connect();
pool.query(query).then((result: any) => {
if (result) {
cb(null, result);
}
else {
cb(null, null);
}
}).fail((err: Error) => {
cb(err, null);
});
pool.close();
}
/** /**
* Materialize a given view. * Materialize a given view.
...@@ -136,7 +159,7 @@ export class MonetAdapter extends SQLAdapter { ...@@ -136,7 +159,7 @@ export class MonetAdapter extends SQLAdapter {
*/ */
public insertIntoSource(source: Source, data: any[], cb: (err: Error, result: any[]) => void): void { public insertIntoSource(source: Source, data: any[], cb: (err: Error, result: any[]) => void): void {
const query = this.getQueryFromSource(source, data); const query = this.getQueryFromSource(source, data);
this.executeQuery(query, cb); this.executeQuerySource(query, cb);
} }
/** /**
......
...@@ -25,11 +25,10 @@ import { MonetAdapter, MonetConfig } from "./monet"; ...@@ -25,11 +25,10 @@ import { MonetAdapter, MonetConfig } from "./monet";
import { Adapter } from "../core/adapter"; import { Adapter } from "../core/adapter";
import { Fixture as FixPostgres } from "../../test/postgres/fixture"; import { Fixture as FixPostgres } from "../../test/postgres/fixture";
import { Fixture as FixMonet } from "../../test/monet/fixture"; import { Fixture as FixMonet } from "../../test/monet/fixture";
import { ConfigParser } from "../util/configParser"; import { ConfigParser } from "../util/configParser";
import { adapterScenario } from "../../test/scenario"; import { adapterScenario } from "../../test/scenario";
describe("postgres adapter", () => { describe("Sql adapter", () => {
// Initializing // Initializing
let config: any; let config: any;
...@@ -38,6 +37,7 @@ describe("postgres adapter", () => { ...@@ -38,6 +37,7 @@ describe("postgres adapter", () => {
before(function (done): void { before(function (done): void {
// Arrow function not used to get acces to this and skip the test // Arrow function not used to get acces to this and skip the test
config = ConfigParser.parse("config/test.yaml"); config = ConfigParser.parse("config/test.yaml");
if (config.adapter === "postgres") { if (config.adapter === "postgres") {
fixture = new FixPostgres(config.connection); fixture = new FixPostgres(config.connection);
fixture.load(config.loadViews, (err) => { fixture.load(config.loadViews, (err) => {
...@@ -50,7 +50,7 @@ describe("postgres adapter", () => { ...@@ -50,7 +50,7 @@ describe("postgres adapter", () => {
} }
else if (config.adapter === "monet") { else if (config.adapter === "monet") {
fixture = new FixMonet(config.connection); fixture = new FixMonet(config.connection);
fixture.load(config.loadViews, config.struct.create, (err) => { fixture.load(config.loadViews, (err) => {
if (err) { if (err) {
throw err; throw err;
} }
......
...@@ -468,7 +468,7 @@ export abstract class SQLAdapter extends Adapter { ...@@ -468,7 +468,7 @@ export abstract class SQLAdapter extends Adapter {
consult = consult.concat(colums.join("\",\"")); consult = consult.concat(colums.join("\",\""));
consult = consult.concat("\") VALUES ('"); consult = consult.concat("\") VALUES ('");
consult = consult.concat(values.join("' , '")); consult = consult.concat(values.join("' , '"));
consult = consult.concat("');"); consult = consult.concat("')");
return consult; return consult;
} }
......
...@@ -49,7 +49,7 @@ describe("API collect controller", () => { ...@@ -49,7 +49,7 @@ describe("API collect controller", () => {
} }
else if (config.adapter === "monet") { else if (config.adapter === "monet") {
fixture = new FixMonet(config.connection); fixture = new FixMonet(config.connection);
fixture.load(config.sources, config.struct.create, (err) => { fixture.loadSource(config.sources, (err) => {
if (err) { if (err) {
throw err; throw err;
} }
......
...@@ -20,16 +20,12 @@ ...@@ -20,16 +20,12 @@
const MDB = require("monetdb")(); const MDB = require("monetdb")();
import { View, LoadView } from "../../src/core/view"; import { View, LoadView } from "../../src/core/view";
import { Source } from "../../src/core/source";
import { each, series } from "async"; import { each, series } from "async";
import { Connection } from "../../src/util/configParser"; import { Connection } from "../../src/util/configParser";
import * as fs from "fs"; import * as fs from "fs";
import { DataType } from "../../src/common/types"; import { DataType } from "../../src/common/types";
interface TransSet {
init: string;
data: string[];
}
export interface Schema { export interface Schema {
alias?: string; alias?: string;
query?: string; query?: string;
...@@ -46,7 +42,7 @@ export class Fixture { ...@@ -46,7 +42,7 @@ export class Fixture {
this.database = config.database; this.database = config.database;
} }
public load(schemas: LoadView[], create: boolean, cb: (err: Error) => void): void { public load(schemas: LoadView[], cb: (err: Error) => void): void {
let client = new MDB({ let client = new MDB({
user: this.config.user, user: this.config.user,
dbname: this.config.database, dbname: this.config.database,
...@@ -58,19 +54,12 @@ export class Fixture { ...@@ -58,19 +54,12 @@ export class Fixture {
/* /*
Loading data has 2 steps: Loading data has 2 steps:
1 - Create a table or truncate a existing one. 1 - Create a table or truncate a existing one.
Create or truncate dependes from a parameter in the configure
file, this parameter reaches this function as the create
parameter.
2 - Insert data. 2 - Insert data.
*/ */
let init: string[] = [];
let data: string[] = []; let data: string[] = [];
for (let i = 0; i < schemas.length; ++i) { for (let i = 0; i < schemas.length; ++i) {
let table: TransSet = this.createTransSet(schemas[i].view, schemas[i].data, create); data = data.concat(this.extractDataView(schemas[i].view, schemas[i].data));
init.push(table.init);
data = data.concat(table.data);
} }
client.connect(); client.connect();
/* /*
Tables must be creates before data could be inserted, so the Tables must be creates before data could be inserted, so the
...@@ -78,10 +67,20 @@ export class Fixture { ...@@ -78,10 +67,20 @@ export class Fixture {
To garantee that tables exists before start insert data, series To garantee that tables exists before start insert data, series
is used. Inside series each query is executed, using each; is used. Inside series each query is executed, using each;
*/ */
series([(callback: (err: Error) => void) => { series([(callback: (err: Error) => void) => {
each(init, (query, cback) => { each(schemas, (query, cback) => {
return client.query(query).then((result: any) => cback()) client.query(this.createTransSet(query.view, query.data, true)).then((result: any) => cback())
.fail((err: Error) => (cback(err))); .fail((errCreate: Error) => {
if (errCreate){
let regex = new RegExp(/42s01!create table: name \'.*\' already in use/);
if (regex.test(errCreate.message.toLocaleLowerCase())){
return client.query(this.createTransSet(query.view, query.data, false)).then((result: any) => cback())
.fail((errTrunc: Error) => (cback(errTrunc)));
}
}
return cback(errCreate);
});
}, (errQuery: Error) => callback(errQuery)); }, (errQuery: Error) => callback(errQuery));
}, (callback: (err: Error) => void) => { }, (callback: (err: Error) => void) => {
each(data, (query, cback) => { each(data, (query, cback) => {
...@@ -92,6 +91,7 @@ export class Fixture { ...@@ -92,6 +91,7 @@ export class Fixture {
client.close(); client.close();
cb(errQuery); cb(errQuery);
}); });
} }
private typeConvertion(t: DataType): string { private typeConvertion(t: DataType): string {
...@@ -104,47 +104,52 @@ export class Fixture { ...@@ -104,47 +104,52 @@ export class Fixture {
return "TEXT"; return "TEXT";
case DataType.BOOLEAN: case DataType.BOOLEAN:
return "BOOLEAN"; return "BOOLEAN";
case DataType.FLOAT:
return "FLOAT";
default: default:
return ""; return "TEXT";
} }
} }
private createTransSet(view: View, filePath: string, create: boolean): TransSet { private extractDataView(view: View, filePath: string): string[]{
let props = []; let name = "view_" + view.id;
let data: string[] = [];
let rows = JSON.parse(fs.readFileSync(filePath, {encoding : "utf8"}));
for (let i = 0; i < rows.length; ++i) {
let values = [];
let keys = [];
for (let key of Object.keys(rows[i])) {
keys.push("\"" + key + "\"");
values.push("'" + this.boolCast(rows[i][key]) + "'");
}
data.push("INSERT INTO " + name +
"(" + keys.join(", ") + ") " +
"VALUES (" + values.join(", ") + ")");
}
return data;
}
private createTransSet(view: View, filePath: string, create: boolean): string {
let name = "view_" + view.id;
let init: string = "";
let props = [];
for (let i = 0; i < view.metrics.length; ++i) { for (let i = 0; i < view.metrics.length; ++i) {
let met = view.metrics[i]; let met = view.metrics[i];
props.push("\"" + met.name + "\" " + this.typeConvertion(met.dataType)); props.push("\"" + met.name + "\" " + this.typeConvertion(met.dataType));
} }
for (let i = 0; i < view.dimensions.length; ++i) { for (let i = 0; i < view.dimensions.length; ++i) {
let dim = view.dimensions[i]; let dim = view.dimensions[i];
props.push("\"" + dim.name + "\" " + this.typeConvertion(dim.dataType)); props.push("\"" + dim.name + "\" " + this.typeConvertion(dim.dataType));
} }
let name = "view_" + view.id;
let transaction: TransSet = {init: "", data: []};
if (create) { if (create) {
transaction.init = "CREATE TABLE " + name + "(" + props.join(", ") + ")"; init = "CREATE TABLE " + name + "(" + props.join(", ") + ")";
} }
else { else {
transaction.init = "DELETE FROM " + name; init = "DELETE FROM " + name;
}
transaction.data = [];
let rows = JSON.parse(fs.readFileSync(filePath, {encoding : "utf8"}));
for (let i = 0; i < rows.length; ++i) {
let values = [];
let keys = [];
for (let key of Object.keys(rows[i])) {
keys.push("\"" + key + "\"");
values.push("'" + this.boolCast(rows[i][key]) + "'");
}
transaction.data.push("INSERT INTO " + name +
"(" + keys.join(", ") + ") " +
"VALUES (" + values.join(", ") + ")");
} }
return transaction; return init;
} }
private boolCast(text: string): string { private boolCast(text: string): string {
...@@ -160,4 +165,62 @@ export class Fixture { ...@@ -160,4 +165,62 @@ export class Fixture {
return text; return text;
} }
} }
public loadSource(source: Source[] , cb: (err: Error) => void): void {
let client = new MDB({
user: this.config.user,
dbname: this.config.database,
password: this.config.password,
host: this.config.host,
port: this.config.port,
});
client.connect();
series([(callback: (err: Error) => void) => {
each(source, (insere, cback) => {
client.query(this.extractData(insere, true)).then((result: any) => cback())
.fail((errCreate: Error) => {
if (errCreate) {
let regex = new RegExp(/42s01!create table: name \'.*\' already in use/);
if (regex.test(errCreate.message.toLocaleLowerCase())){
return client.query(this.extractData(insere, false)).then((result: any) => cback())
.fail((errTrunc: Error) => (cback(errTrunc)));
}
}
return cback(errCreate);
});
}, (errQuery: Error) => callback(errQuery));
}], (errQuery: Error) => {
client.close();
cb(errQuery);
});
}
private extractData(data: Source, create: boolean): string{
let name: string;
let type: DataType[];
let fields: string[];
let consult: string;
name = data.name;
type = data.fields.map((item) => item.dataType);
fields = data.fields.map((item) => item.name);
if (create){
consult = "CREATE TABLE " + name + " (" + '"';
for (let i = 0; i < fields.length; i++){
fields[i] = fields[i].concat('"' + " " + this.typeConvertion(type[i]));
}
consult = consult.concat(fields.join(", " + '"'));
consult = consult.concat(");");
}
else{
consult = "DELETE FROM " + name + ";";
}
return consult;
}
} }
...@@ -114,6 +114,8 @@ export class Fixture { ...@@ -114,6 +114,8 @@ export class Fixture {
return "TEXT"; return "TEXT";
case DataType.BOOLEAN: case DataType.BOOLEAN:
return "BOOLEAN"; return "BOOLEAN";
case DataType.FLOAT:
return "FLOAT";
default: default:
return "TEXT"; return "TEXT";
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment