diff --git a/config/ci_test.env.example b/config/ci_test.env.example index 370623dcba16e54d4c6f7f9676b141344f7348eb..433eeb1292e090f1309b8d1bdad1873cf0df963a 100644 --- a/config/ci_test.env.example +++ b/config/ci_test.env.example @@ -3,7 +3,5 @@ BLENDB_DB_NAME=blendb_fixture BLENDB_DB_PASSWORD= BLENDB_DB_HOST=postgres BLENDB_DB_PORT=5432 -BLENDB_ST_CREATE=true -BLENDB_ST_INSERT=true BLENDB_ADAPTER=postgres PORT=3000 diff --git a/config/config.env.example b/config/config.env.example index 7188cc4955ea678debfaca3852350d4b3c20b782..565344bf4ef511a0bc4987e7f28dc99ed76535e1 100644 --- a/config/config.env.example +++ b/config/config.env.example @@ -3,7 +3,5 @@ BLENDB_DB_NAME=blendb-test BLENDB_DB_PASSWORD=secret BLENDB_DB_HOST=localhost BLENDB_DB_PORT=5432 -BLENDB_ST_CREATE=false -BLENDB_ST_INSERT=false BLENDB_ADAPTER=postgres PORT=3000 diff --git a/src/adapter/postgres.spec.ts b/src/adapter/postgres.spec.ts index d9c5a2d71e7d649b890a350f79c407f0d1693489..ddbb00f671b1e192864fd2f91ae2b80acf348e28 100644 --- a/src/adapter/postgres.spec.ts +++ b/src/adapter/postgres.spec.ts @@ -40,7 +40,7 @@ describe("postgres adapter", () => { config = ConfigParser.parse("config/test.yaml"); if (config.adapter === "postgres") { fixture = new FixPostgres(config.connection); - fixture.load(config.loadViews, config.struct.create, (err) => { + fixture.load(config.loadViews, (err) => { if (err) { throw err; } diff --git a/src/api/controllers/collect.spec.ts b/src/api/controllers/collect.spec.ts index 57d7cd37b3c5c33013a5fc0a510404aa252e5424..d770c87d57a7a6debbd8e6ffbf8d4524f72cc46f 100644 --- a/src/api/controllers/collect.spec.ts +++ b/src/api/controllers/collect.spec.ts @@ -39,7 +39,7 @@ describe("API collect controller", () => { config = ConfigParser.parse("config/test.yaml"); if (config.adapter === "postgres") { fixture = new FixPostgres(config.connection); - fixture.LoadSource(config.sources, config.struct.create, (err) => { + fixture.loadSource(config.sources, (err) => { if (err) { throw err; } diff --git a/src/util/configParser.ts b/src/util/configParser.ts index 47cfc4b693b7973a7acc9b8c3f3256aedaf7471b..8dbf87f669a53d7062fb2ebabf75ed3c47041354 100644 --- a/src/util/configParser.ts +++ b/src/util/configParser.ts @@ -77,15 +77,6 @@ interface BuildView { alias: string; } -/** Information required to conduct fixture loading. */ -export interface LoadStruct{ - /** True if is required create structures in the database before loading. */ - create: boolean; - /** True any fixture is loaded yet. */ - insert: boolean; -} - -/** Configuration file representation with objects, not strings. */ export interface ParsedConfig { /** What adapter is in use. */ adapter: string; @@ -101,9 +92,6 @@ export interface ParsedConfig { enumTypes: EnumType[]; /** Set of all dimensions available. */ dimensions: Dimension[]; - /** Fixture loading policy. */ - struct: LoadStruct; - /** Fixture data configuration. */ loadViews: LoadView[]; /** SQL views build configuration. */ buildViews: BuildView[]; @@ -175,15 +163,6 @@ export class ConfigParser { host: process.env.BLENDB_DB_HOST, port: parseInt(process.env.BLENDB_DB_PORT, 10) }; - - const strCreate = process.env.BLENDB_ST_CREATE; - const strInsert = process.env.BLENDB_ST_INSERT; - - let struct: LoadStruct = { - create: (strCreate) ? strCreate.toLowerCase() === "true" : false, - insert: (strInsert) ? strInsert.toLowerCase() === "true" : false - }; - let metricsOpts = config.metrics; let viewsOpts = config.views; let dimensionsOpts = config.dimensions; @@ -196,7 +175,6 @@ export class ConfigParser { metrics: [], enumTypes: [], dimensions: [], - struct: struct, loadViews: [], buildViews: [], sources: [] diff --git a/test/postgres/fixture.ts b/test/postgres/fixture.ts index d560d7eb52485ae886dd9e999498e4fe22399eb6..a9a2abd8cd01b7ed5c7ed6c8f726b83b67d3f981 100644 --- a/test/postgres/fixture.ts +++ b/test/postgres/fixture.ts @@ -52,31 +52,23 @@ export class Fixture { 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 Client(this.config); /* Loading data has 2 steps: 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. */ - let init: string[] = []; let data: string[] = []; for (let i = 0; i < schemas.length; ++i) { - let table: TransSet = this.createTransSet(schemas[i].view, schemas[i].data, create); - init.push(table.init); - data = data.concat(table.data); + data = data.concat(this.extractDataView(schemas[i].view, schemas[i].data)); } - client.connect((error) => { if (error) { cb(error); return; } - /* Tables must be creates before data could be inserted, so the queries that create and insert are splited in 2 arrays. @@ -84,12 +76,20 @@ export class Fixture { is used. Inside series each query is executed, using each; */ series([(callback: (err: Error) => void) => { - each(init, (query, cback) => { - return client.query(query, [], (err: Error) => cback(err)); + each(schemas, (query, cback) => { + client.query(this.createTransSet(query.view, query.data, true), [], (errCreate: Error) => { + if (errCreate) { + let regex = new RegExp(/relation \".*\" already exists/); + if (regex.test(errCreate.message.toLowerCase())){ + return client.query(this.createTransSet(query.view, query.data, false), [], (errTrunc: Error) => cback(errTrunc)); + } + } + return cback(errCreate); + }); }, (errQuery: Error) => callback(errQuery)); }, (callback: (err: Error) => void) => { each(data, (query, cback) => { - return client.query(query, [], (err: Error) => cback(err)); + return client.query( query, [], (err: Error) => cback(err)); }, (errQuery: Error) => callback(errQuery)); }], (errQuery: Error) => { if (errQuery) { @@ -119,63 +119,68 @@ export class Fixture { } } - private createTransSet(view: View, filePath: string, create: boolean): TransSet { - let props = []; + private extractDataView(view: View, filePath: string): string[]{ + 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("'" + 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) { let met = view.metrics[i]; props.push("\"" + met.name + "\" " + this.typeConvertion(met.dataType)); } - for (let i = 0; i < view.dimensions.length; ++i) { let dim = view.dimensions[i]; props.push("\"" + dim.name + "\" " + this.typeConvertion(dim.dataType)); } - - let name = "view_" + view.id; - let transaction: TransSet = {init: "", data: []}; if (create) { - transaction.init = "CREATE TABLE " + name + "(" + props.join(", ") + ")"; + init = "CREATE TABLE " + name + "(" + props.join(", ") + ")"; } else { - transaction.init = "TRUNCATE TABLE " + 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("'" + rows[i][key] + "'"); - } - transaction.data.push("INSERT INTO " + name + - "(" + keys.join(", ") + ") " + - "VALUES (" + values.join(", ") + ")"); + init = "TRUNCATE TABLE " + name; } - return transaction; + return init; } - public LoadSource(source: Source[], create: boolean , cb: (err: Error) => void): void { + public loadSource(source: Source[] , cb: (err: Error) => void): void { let client = new Client(this.config); - let query: string[] = []; - for (let i = 0; i < source.length; i++ ){ - query[i] = this.ExtractData(source[i], create); - } - client.connect((error) => { if (error) { cb(error); return; } - series([(callback: (err: Error) => void) => { - each(query, (insere, cback) => { - return client.query(insere , [], (err: Error) => cback(err)); + each(source, (insere, cback) => { + client.query ( this.extractData(insere, true), [], (errCreate: Error) => { + if (errCreate) { + let regex = new RegExp(/relation \".*\" already exists/); + if (regex.test(errCreate.message.toLowerCase())){ + return client.query ( this.extractData(insere, false), [], (errTrunc: Error) => cback(errTrunc)); + } + } + return cback(errCreate); + }); }, (errQuery: Error) => callback(errQuery)); - }], (errQuery: Error) => { + }], (errQuery: Error) => { if (errQuery) { client.end(); cb(errQuery); @@ -183,11 +188,11 @@ export class Fixture { client.end((err) => { cb(err); }); - }); - }); + }); + }); } - private ExtractData(data: Source , create: boolean): string{ + private extractData(data: Source, create: boolean): string{ let name: string; let type: DataType[]; let fields: string[]; @@ -208,6 +213,7 @@ export class Fixture { else{ consult = "TRUNCATE TABLE " + name + ";"; } + return consult; }