...
 
Commits (34)
/artwork
/config
/config/*.yaml
!/config/*.example
/coverage
/database
/doc
......
......@@ -21,3 +21,4 @@
/service
schema.sql
/doc/code
.nyc_output/*
image: node:6.12.2
image: node:10.16.3
services:
- postgres:latest
......@@ -11,7 +11,7 @@ variables:
POSTGRES_USER: 'runner'
POSTGRES_PASSWORD: ''
MONETDB_NAME: 'blendb_fixture'
PKG_VERSION: 'latest'
PKG_VERSION: '1.0-alpha'
DOCKER_URL: 'dockerregistry.c3sl.ufpr.br:5000/c3sl/blendb:'
cache:
......@@ -24,22 +24,11 @@ stages:
- deploy
run_test_postgres:
run_test:
stage: test
script:
- yarn install --frozen-lockfile --silent --non-interactive
- mv config/ci_postgres_test.env.example config/test.env
- yarn test
- yarn run lint
tags:
- node
- postgres
run_test_monet:
stage: test
script:
- yarn install --frozen-lockfile --silent --non-interactive
- mv config/ci_monet_test.env.example config/test.env
- mv config/test.env.example config/test.env
- yarn test
- yarn run lint
tags:
......@@ -69,5 +58,4 @@ deploy:
- docker
- build
only:
- master
- develop
# Avoid the use of floating tags like: latest, boron, argon and carbon
ARG VERSION=6.12.2
ARG VERSION=10.16.3
FROM node:$VERSION
LABEL autor="C3SL - Centro de Computação Científica e Software Livre"
......
-
name: "dim:2"
dataType: "integer"
description: "A dimension of Blendb. Has 5 possible values."
-
name: "dim:3"
dataType: "string"
description: "A dimension of Blendb. Has 5 possible values."
-
name: "dim:4"
dataType: "string"
description: "A dimension of Blendb. Has 5 possible values."
-
name: "dim:5"
dataType: "boolean"
description: "A dimension of Blendb. Has 2 possible values."
-
name: "dim:6"
dataType: "integer"
description: "A dimension of Blendb. Has 5 possible values."
-
name: "dim:7"
dataType: "integer"
description: "A dimension of Blendb. Has 5 possible values."
-
name: "dim:8"
dataType: "integer"
description: "A dimension of Blendb. Has 5 possible values."
-
name: "dim:9"
dataType: "integer"
parent: "dim:0"
relation: "day"
description: "A dimension of Blendb. Has 30 possible values."
-
name: "dim:10"
dataType: "integer"
parent: "dim:0"
relation: "month"
description: "A dimension of Blendb. Has 12 possible values."
-
name: "dim:11"
dataType: "integer"
parent: "dim:0"
relation: "year"
description: "A dimension of Blendb. Has 1 possible value."
-
name: "enumtype:1"
values:
- "test_4"
- "test_5"
- "test_6"
- "string"
-
name: "enumtype:2"
values:
- "test_7"
- "test_8"
-
name: "enumtype:3"
values:
- "test_9"
-
name: "met:2"
dataType: "integer"
aggregation: "avg"
description: "No meaning, just used for test"
-
name: "met:3"
dataType: "integer"
aggregation: "sum"
description: "No meaning, just used for test"
-
name: "met:4"
dataType: "integer"
aggregation: "sum"
description: "No meaning, just used for test"
-
name: "met:5"
dataType: "integer"
aggregation: "avg"
description: "No meaning, just used for test"
-
name: "met:6"
dataType: "integer"
aggregation: "count"
description: "No meaning, just used for test"
-
name: "met:7"
dataType: "integer"
aggregation: "count"
description: "No meaning, just used for test"
-
name: "met:8"
dataType: "integer"
aggregation: "sum"
description: "No meaning, just used for test"
-
name: "met:9"
dataType: "integer"
aggregation: "count"
description: "No meaning, just used for test"
-
name: "met:10"
dataType: "integer"
aggregation: "max"
description: "No meaning, just used for test"
-
name: "met:11"
dataType: "integer"
aggregation: "min"
description: "No meaning, just used for test"
BLENDB_DB_USER=monetdb
BLENDB_DB_NAME=blendb_fixture
BLENDB_DB_PASSWORD=monetdb
BLENDB_DB_HOST=monet
BLENDB_DB_PORT=50000
BLENDB_ADAPTER=monet
BLENDB_SCHEMA_FILE=config/ci_test.yaml.example
PORT=3000
BLENDB_DB_USER=runner
BLENDB_DB_NAME=blendb_fixture
BLENDB_DB_PASSWORD=
BLENDB_DB_HOST=postgres
BLENDB_DB_PORT=5432
BLENDB_ADAPTER=postgres
BLENDB_SCHEMA_FILE=config/ci_test.yaml.example
PORT=3000
-
name: "source_1"
description: "source with 2 entries"
fields:
-
name: "fields:0"
description: "first entry"
dataType: "enumtype"
enumType: "enumtype:0"
-
name: "fields:1"
description: "second entry"
dataType: "string"
-
name: "source_2"
description: "source with one entry and undefined dataType"
fields:
-
name: "fields:0"
description: "first entry"
dataType: "string"
-
name: "source_3"
description: "source with one entry and without description"
fields:
-
name: "fields:0"
dataType: "string"
-
name: "source_4"
description: "source with all core types from blendb"
fields:
-
name: "fields:0"
description: "first entry"
dataType: "integer"
-
name: "fields:1"
description: "second entry"
dataType: "float"
-
name: "fields:2"
description: "third entry"
dataType: "string"
-
name: "fields:3"
description: "fourth entry"
dataType: "boolean"
-
name: "fields:4"
description: "fifth entry"
dataType: "date"
# gitignore ignores files.yaml in this folder
# however a config file for tests in CI is required
# so this example file in fact is the CI test file
tags:
links:
- config/market_tags.yaml.example
obj:
-
name: "noDescription"
description: "Related with seller"
views:
links:
- config/ci_views.yaml.example
- config/market_views.yaml.example
obj:
-
alias: "View 0"
data: "test/postgres/fixtures/view0.json"
alias: "view:Seller"
data: "test/postgres/fixtures/seller.json"
origin: true
aliasAsName: true
dimensions:
- "dim:0"
- "dim:7"
- "dim:seller:name"
- "dim:seller:sex"
- "dim:seller:cpf"
- "dim:seller:id"
- "dim:seller:status"
metrics:
- "met:0"
- "met:1"
- "met:2"
- "met:10"
- "met:seller:avg:age"
- "met:seller:max:age"
- "met:seller:min:age"
- "met:seller:count:age"
metrics:
links:
- config/ci_metrics.yaml.example
- config/ci_metrics_1.yaml.example
- config/market_metrics.yaml.example
obj:
-
name: "met:0"
dataType: "integer"
aggregation: "sum"
description: "No meaning, just used for test"
-
name: "met:1"
dataType: "integer"
-
name: "met:seller:avg:age"
dataType: "float"
aggregation: "avg"
description: "No meaning, just used for test"
description: "The seller average age"
tags:
- "seller"
- "age"
dimensions:
links:
- config/ci_dimensions.yaml.example
- config/market_dimensions.yaml.example
obj:
-
name: "dim:0"
dataType: "date"
description: "A dimension of Blendb. Has 5 possible values."
-
name: "dim:1"
dataType: "date"
description: "A dimension of Blendb. Has 5 possible values."
name: "dim:seller:name"
dataType: "string"
description: "Name of the seller from market"
tags:
- "seller"
enumTypes:
links:
- config/ci_enumtypes.yaml.example
- config/market_enum.yaml.example
obj:
-
name: "enumtype:0"
values:
- "male"
- "female"
- "binary"
- "undecided"
- []
sources:
links:
- config/ci_sources.yaml.example
- config/market_sources.yaml.example
- config/source_test_only.yaml.example
obj:
-
name: "source_0"
description: "source with 3 entries"
name: "Seller"
description: "Market worker"
fields:
-
name: "fields:0"
description: "first entry"
dataType: "string"
-
name: "fields:1"
description: "second entry"
name: "name"
description: "Seller name"
dataType: "string"
-
name: "fields:2"
description: "third entry"
name: "age"
description: "Seller age"
dataType: "integer"
-
name: "sex"
description: "Seller sex"
enumType: "enumsex"
dataType: "enumtype"
-
name: "CPF"
description: "Seller CPF"
dataType: "string"
-
name: "id"
description: "Seller id"
dataType: "integer"
-
alias: "View 1"
data: "test/postgres/fixtures/view1.json"
origin: true
dimensions:
- "dim:1"
- "dim:8"
metrics:
- "met:3"
- "met:4"
-
alias: "View 2"
data: "test/postgres/fixtures/view2.json"
origin: true
dimensions:
- "dim:2"
metrics:
- "met:5"
- "met:6"
- "met:11"
-
alias: "View 3"
data: "test/postgres/fixtures/view3.json"
origin: true
dimensions:
- "dim:2"
- "dim:3"
- "dim:4"
-
alias: "View 4"
data: "test/postgres/fixtures/view4.json"
origin: true
dimensions:
- "dim:2"
- "dim:7"
- "dim:8"
-
alias: "View 5"
data: "test/postgres/fixtures/view5.json"
origin: true
dimensions:
- "dim:3"
metrics:
- "met:7"
-
alias: "View 6"
data: "test/postgres/fixtures/view6.json"
origin: true
dimensions:
- "dim:4"
metrics:
- "met:8"
-
alias: "View 7"
data: "test/postgres/fixtures/view7.json"
origin: true
dimensions:
- "dim:4"
- "dim:5"
- "dim:6"
-
alias: "View 8"
data: "test/postgres/fixtures/view8.json"
origin: true
dimensions:
- "dim:5"
- "dim:6"
metrics:
- "met:9"
-
alias: "view 9"
data: "test/postgres/fixtures/view9.json"
origin: false
dimensions:
- "dim:2"
metrics:
- "met:5"
- "met:6"
- "met:7"
clauses:
- "dim:2!=1"
BLENDB_DB_USER=blendb
BLENDB_DB_NAME=blendb-test
BLENDB_DB_PASSWORD=secret
BLENDB_DB_HOST=localhost
BLENDB_DB_PORT=5432
BLENDB_ADAPTER=postgres
BLENDB_SCHEMA_FILE=config/config.yaml
BLENDB_SCHEMA_FILE=config/config.yaml.example
PORT=3000
BLENDB_LOG_FILE=/var/log/blendb.log
BLENDB_LOG_LEVEL=debug
BLENDB_N_DB=1
BLENDB_DB0_USER=blendb
BLENDB_DB0_NAME=blendb-test
BLENDB_DB0_PASSWORD=secret
BLENDB_DB0_HOST=localhost
BLENDB_DB0_PORT=5432
BLENDB_DB0_ADAPTER=postgres
connection:
user: 'blendb'
database: 'blendb-test'
password: 'secret'
host: 'localhost'
port: 5432
max: 10
idleTimeoutMillis: 30000
struct:
create: false
insert: false
schema:
views:
metrics:
dimensions:
# gitignore ignores files.yaml in this folder
# however a config file for tests in CI is required
# so this example file in fact is the CI test file
tags:
links:
- config/market_tags.yaml.example
obj:
-
name: "noDescription"
description: "Related with seller"
views:
links:
- config/market_views.yaml.example
obj:
-
alias: "view:Seller"
data: "test/postgres/fixtures/seller.json"
origin: true
aliasAsName: true
dimensions:
- "dim:seller:name"
- "dim:seller:sex"
- "dim:seller:cpf"
- "dim:seller:id"
- "dim:seller:status"
metrics:
- "met:seller:avg:age"
- "met:seller:max:age"
- "met:seller:min:age"
- "met:seller:count:age"
metrics:
links:
- config/market_metrics.yaml.example
obj:
-
name: "met:seller:avg:age"
dataType: "float"
aggregation: "avg"
description: "The seller average age"
tags:
- "seller"
- "age"
dimensions:
links:
- config/market_dimensions.yaml.example
obj:
-
name: "dim:seller:name"
dataType: "string"
description: "Name of the seller from market"
tags:
- "seller"
enumTypes:
links:
- config/market_enum.yaml.example
obj:
- []
sources:
links:
- config/market_sources.yaml.example
- config/source_test_only.yaml.example
obj:
-
name: "Seller"
description: "Market worker"
fields:
-
name: "name"
description: "Seller name"
dataType: "string"
-
name: "age"
description: "Seller age"
dataType: "integer"
-
name: "sex"
description: "Seller sex"
enumType: "enumsex"
dataType: "enumtype"
-
name: "CPF"
description: "Seller CPF"
dataType: "string"
-
name: "id"
description: "Seller id"
dataType: "integer"
......@@ -8,78 +8,74 @@
dataType: "string"
description: "CPF of the seller from market"
-
name: "dim:seller:id"
dataType: "integer"
description: "id of the seller from market"
name: "dim:seller:status"
dataType: "enumtype"
enumType: "workingStatus"
description: "The status of the seller from market"
-
name: "dim:product:name"
dataType: "string"
description: "Name of the product from market"
description: "Name of the product from market"
-
name: "dim:product:validity"
dataType: "date"
description: "Validity of the product from market"
-
name: "dim:product:id"
dataType: "integer"
description: "id of the product from market"
-
name: "dim:client:name"
dataType: "string"
description: "Name of the client from market"
-
-
name: "dim:client:cpf"
dataType: "string"
description: "CPF of the client from market"
-
name: "dim:client:id"
dataType: "integer"
description: "id of the client from market"
-
name: "dim:sell:registered"
dataType: "boolean"
description: "Check if the client is registered"
-
name: "dim:sell:product.id"
dataType: "integer"
description: "id of the product from market"
description: "Check if the client is registered"
-
name: "dim:sell:seller.id"
name: "dim:seller:id"
dataType: "integer"
description: "id of the seller from market"
description: "id of the seller from market"
-
name: "dim:sell:client.id"
name: "dim:client:id"
dataType: "integer"
description: "id of the client from market"
-
name: "dim:sell:datein"
dataType: "date"
description: "Date of the sell was realized"
description: "Date of the sell was realized"
-
name: "dim:buyout:datein"
dataType: "date"
description: "Date of the buyout was realized"
-
name: "dim:buyout:provider.id"
dataType: "integer"
description: "id of the provider from market"
description: "Date of the buyout was realized"
-
name: "dim:buyout:product.id"
name: "dim:product:id"
dataType: "integer"
description: "id of the product from market"
description: "id of the product from market"
-
name: "dim:provider:name"
dataType: "string"
description: "Name of the provider from market"
description: "Name of the provider from market"
-
name: "dim:provider:id"
dataType: "string"
description: "id of the provider from market"
-
name: "dim:buyout:day"
dataType: "integer"
description: "id of the provider from market"
parent: "dim:buyout:datein"
relation: "day"
description: "Date of the buyout was realized"
-
name: "dim:distribute:provider.id"
dataType: "string"
description: "id of the provider from market"
name: "dim:buyout:month"
dataType: "integer"
parent: "dim:buyout:datein"
relation: "month"
description: "Date of the buyout was realized"
-
name: "dim:distribute:product.id"
dataType: "string"
description: "id of the product from market"
name: "dim:buyout:year"
dataType: "integer"
parent: "dim:buyout:datein"
relation: year
description: "Date of the buyout was realized"
......@@ -5,4 +5,12 @@
- "female"
- "nonbinary"
- "undecided"
-
name: "workingStatus"
values:
- "active"
- "inactive"
- "vacation"
- "sick leave"
- "maternity leave"
- "stand by"
......@@ -3,14 +3,15 @@ views:
- config/market_views.yaml.example
obj:
-
alias: "Seller"
data: "test/postgres/fixtures/view10.json"
alias: "view:Seller"
data: "test/postgres/fixtures/seller.json"
origin: true
dimensions:
- "dim:seller:name"
- "dim:seller:sex"
- "dim:seller:cpf"
- "dim:seller:id"
- "dim:seller:status"
metrics:
- "met:seller:avg:age"
- "met:seller:max:age"
......
......@@ -3,46 +3,70 @@
dataType: "integer"
aggregation: "max"
description: "The seller highest age"
tags:
- "seller"
- "age"
- "max"
-
name: "met:seller:min:age"
dataType: "integer"
aggregation: "min"
description: "The seller lowest age"
tags:
- "seller"
- "age"
-
name: "met:seller:count:age"
dataType: "integer"
aggregation: "count"
description: "The number of seller's"
tags:
- "seller"
- "age"
-
name: "met:product:avg:pricein"
dataType: "float"
aggregation: "avg"
description: "The average product pricein"
tags:
- "product"
-
name: "met:product:max:pricein"
dataType: "float"
aggregation: "max"
description: "The highest product pricein"
tags:
- "product"
- "max"
-
name: "met:product:min:pricein"
dataType: "float"
aggregation: "min"
description: "The lowest product pricein"
tags:
- "product"
-
name: "met:product:avg:priceout"
dataType: "float"
aggregation: "avg"
description: "The average product priceout"
tags:
- "product"
-
name: "met:product:max:priceout"
dataType: "float"
aggregation: "max"
description: "The highest product priceout"
tags:
- "product"
- "max"
-
name: "met:product:min:priceout"
dataType: "float"
aggregation: "min"
description: "The lowest product priceout"
tags:
- "product"
-
name: "met:sell:sum:quantity"
dataType: "integer"
......@@ -63,13 +87,20 @@
dataType: "float"
aggregation: "avg"
description: "The average of quantity bought"
tags:
- "buyout"
-
name: "met:buyout:max:quantity"
dataType: "integer"
aggregation: "max"
description: "The highest quantity bought"
tags:
- "buyout"
- "max"
-
name: "met:buyout:min:quantity"
dataType: "integer"
aggregation: "min"
description: "The lowest quantity bought"
tags:
- "buyout"
-
name: "seller"
description: "Related with seller"
-
name: "age"
description: "Related with age"
-
name: "product"
description: "Related with product"
-
name: "client"
description: "Related with client"
-
name: "buyout"
description: "Related with buyout"
-
name: "provider"
description: "Related with provider"
-
name: "max"
description: "Aggregation Max"
-
alias: "Product"
data: "test/postgres/fixtures/view11.json"
alias: "view:Product"
data: "test/postgres/fixtures/product.json"
origin: true
aliasAsName: true
dimensions:
- "dim:product:name"
- "dim:product:validity"
......@@ -14,50 +15,76 @@
- "met:product:max:priceout"
- "met:product:min:priceout"
-
alias: "Client"
data: "test/postgres/fixtures/view12.json"
alias: "view:Client"
data: "test/postgres/fixtures/client.json"
origin: true
aliasAsName: true
dimensions:
- "dim:client:name"
- "dim:client:cpf"
- "dim:client:id"
-
alias: "Sell"
data: "test/postgres/fixtures/view13.json"
alias: "view:Sell"
data: "test/postgres/fixtures/sell.json"
origin: true
aliasAsName: true
dimensions:
- "dim:sell:registered"
- "dim:sell:product.id"
- "dim:sell:seller.id"
- "dim:sell:client.id"
- "dim:product:id"
- "dim:seller:id"
- "dim:client:id"
- "dim:sell:datein"
metrics:
- "met:sell:sum:quantity"
- "met:sell:avg:quantity"
- "met:sell:count:quantity"
-
alias: "Buyout"
data: "test/postgres/fixtures/view14.json"
alias: "view:Buyout"
data: "test/postgres/fixtures/buyout.json"
origin: true
aliasAsName: true
dimensions:
- "dim:buyout:datein"
- "dim:buyout:provider.id"
- "dim:buyout:product.id"
- "dim:provider:id"
- "dim:product:id"
metrics:
- "met:buyout:avg:quantity"
- "met:buyout:max:quantity"
- "met:buyout:min:quantity"
-
alias: "Provider"
data: "test/postgres/fixtures/view15.json"
alias: "view:Provider"
data: "test/postgres/fixtures/provider.json"
origin: true
aliasAsName: true
dimensions:
- "dim:provider:name"
- "dim:provider:id"
-
alias: "Distribute"
data: "test/postgres/fixtures/view16.json"
alias: "view:Distribute"
data: "test/postgres/fixtures/distribute.json"
origin: true
aliasAsName: true
dimensions:
- "dim:provider:id"
- "dim:product:id"
-
alias: "view:ActiveSeller"
data: "test/postgres/fixtures/activeseller.json"
origin: true
aliasAsName: true
dimensions:
- "dim:seller:name"
- "dim:seller:status"
metrics:
- "met:seller:max:age"
clauses:
- "dim:seller:status==active"
-
alias: "view:SellerStatus"
data: "test/postgres/fixtures/sellerstatus.json"
origin: false
aliasAsName: true
metrics:
- "met:seller:count:age"
dimensions:
- "dim:distribute:provider.id"
- "dim:distribute:product.id"
- "dim:seller:status"
-
name: "test"
description:
fields:
-
name: "noDescriptionString"
description:
dataType: "string"
PORT=3000
BLENDB_N_DB=2
BLENDB_LOG_FILE=/var/log/blendb.log
BLENDB_LOG_LEVEL=debug
BLENDB_DB0_USER=runner
BLENDB_DB0_NAME=blendb_fixture
BLENDB_DB0_PASSWORD=
BLENDB_DB0_HOST=postgres
BLENDB_DB0_PORT=5432
BLENDB_DB0_ADAPTER=postgres
BLENDB_DB1_USER=monetdb
BLENDB_DB1_NAME=blendb_fixture
BLENDB_DB1_PASSWORD=monetdb
BLENDB_DB1_HOST=monet
BLENDB_DB1_PORT=50000
BLENDB_DB1_ADAPTER=monet
BLENDB_SCHEMA_FILE=config/ci_test.yaml.example
version: '3.3'
services:
blendb-postgres:
image: postgres:10
container_name: postgres
environment:
POSTGRES_PASSWORD: passwd
PGDATA: /var/lib/postgresql/docker/pgdata
ports:
- 5432:5432
restart: unless-stopped
security_opt:
- no-new-privileges
blendb:
image: marula.c3sl.ufpr.br:5000/c3sl/blendb:latest
# image: marula.c3sl.ufpr.br:5000/c3sl/blendb:latest
image: blendb
build: .
container_name: blendb
# depends_on:
# - db
environment:
BLENDB_DB_USER: ${BLENDB_DB_USER}
BLENDB_DB_PASSWORD: ${BLENDB_DB_PASSWORD}
BLENDB_DB_NAME: ${BLENDB_DB_NAME}
BLENDB_DB_HOST: ${BLENDB_DB_HOST}
BLENDB_DB_PORT: ${BLENDB_DB_PORT}
BLENDB_ST_CREATE: ${BLENDB_ST_CREATE}
BLENDB_ST_INSERT: ${BLENDB_ST_INSERT}
BLENDB_ADAPTER: ${BLENDB_ADAPTER}
volumes:
-
type: bind
source: ./config
target: /home/node/app/config
-
type: tmpfs
target: /tmp
BLENDB_SCHEMA_FILE: config/config.yaml.example
PORT: 3000
BLENDB_N_DB: 1
BLENDB_DB0_USER: postgres
BLENDB_DB0_NAME: postgres
BLENDB_DB0_PASSWORD: passwd
BLENDB_DB0_HOST: postgres
BLENDB_DB0_PORT: 5432
BLENDB_DB0_ADAPTER: postgres
ports:
- 3000:3000
command: ["yarn","test-mode"]
restart: unless-stopped
read_only: 'true'
security_opt:
- no-new-privileges
# db:
# image: postgres:9.6
# container_name: db
# ports:
# - "5432"
# restart: unless-stopped
# #read_only: 'true'
# security_opt:
# - no-new-privileges
volumes:
-
type: tmpfs
target: /tmp
......@@ -4,15 +4,34 @@
"description": "BlenDB",
"main": "index.js",
"scripts": {
"start": "env $(cat config/config.env) node index",
"start": "env $(cat config/config.env ) node index",
"lint": "tslint -s node_modules/tslint-stylish -t stylish src/**/*.ts test/**/*.ts",
"test": "env $(cat config/test.env) ts-node node_modules/istanbul/lib/cli.js cover -x \"**/*.spec.ts\" -e .ts _mocha",
"test": "env $(cat config/test.env) ts-node node_modules/nyc/bin/nyc.js mocha",
"show-coverage": "xdg-open coverage/lcov-report/index.html",
"doc-api": "raml2html -i specs/blendb-api-v1.raml -o doc/api-v1-reference.html",
"schema": "env $(cat config/config.env ) ts-node scripts/schema.ts config/config.yaml schema.sql",
"service": "./scripts/service.sh",
"test-mode": "ts-node scripts/loadTest.ts && node index",
"doc-code": "typedoc --mode 'file' --module 'commonjs' --target 'ES6' --ignoreCompilerErrors --exclude '**/*.spec.ts' --out 'doc/code' 'src'"
},
"nyc": {
"include": [
"src/**/*.ts"
],
"extension": [
".ts"
],
"require": [
"ts-node/register"
],
"reporter": [
"text-summary",
"text",
"lcov"
],
"sourceMap": true,
"instrument": true
},
"repository": {
"type": "git",
"url": "git@gitlab.c3sl.ufpr.br:c3sl/blendb.git"
......@@ -20,30 +39,37 @@
"author": "Centro de Computação Científica e Software Livre (C3SL)",
"license": "GPL-3.0",
"dependencies": {
"@types/async": "^2.0.40",
"@types/chai": "^3.4.33",
"@types/express": "^4.0.33",
"@types/js-yaml": "^3.5.29",
"@types/pg": "^6.1.45",
"async": "=2.4.1",
"express": "^4.0.33",
"js-yaml": "^3.8.2",
"@types/async": "^3.0.1",
"@types/chai": "^4.2.0",
"@types/express": "^4.17.1",
"@types/js-yaml": "^3.12.1",
"@types/pg": "^7.11.0",
"async": "^3.1.0",
"express": "^4.17.1",
"js-yaml": "^3.13.1",
"json-2-csv": "^3.5.6",
"log4js": "^5.1.0",
"monetdb": "^1.1.4",
"osprey": "^0.3.2",
"pg": "^6.1.5",
"ts-node": "^3.1.0",
"typescript": "^2.4.1"
"pg": "^7.12.1",
"raml-parser": "^0.8.18",
"ts-node": "^8.3.0",
"typescript": "^3.5.3"
},
"devDependencies": {
"@types/mocha": "^2.2.32",
"@types/supertest": "^2.0.0",
"chai": "^3.4.33",
"istanbul": "1.1.0-alpha.1",
"mocha": "^3.1.0",
"raml2html": "^3.0.1",
"supertest": "^3.0.0",
"tslint": "^3.15.1",
"tslint-stylish": "^2.1.0-beta",
"typedoc": "^0.11.1"
"@types/mocha": "^5.2.7",
"@types/supertest": "^2.0.8",
"chai": "^4.2.0",
"mocha": "^6.2.0",
"nyc": "^14.1.1",
"raml2html": "^7.4.0",
"supertest": "^4.0.2",
"tslint": "^5.19.0",
"tslint-stylish": "^2.1.0",
"typedoc": "^0.15.0"
},
"engines": {
"node": "^10.16.3"
}
}
#!/usr/bin/env node
/*
* Copyright (C) 2018 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 { Fixture as FixPostgres } from "../test/postgres/fixture";
import { ConfigParser } from "../src/util/configParser";
let config: any;
let fixture;
let configPath;
if(process.env.BLENDB_SCHEMA_FILE){
configPath = process.env.BLENDB_SCHEMA_FILE;
}
else{
throw new Error("BLENDB_SCHEMA_FILE wasn't informed");
}
config = ConfigParser.parse(configPath);
fixture = new FixPostgres(config.connections[0]);
fixture.load(config.loadViews, (err) => {
if (err) {
throw err;
}
})
......@@ -23,6 +23,7 @@
import { Engine } from "../src/core/engine";
import { PostgresAdapter } from "../src/adapter/postgres";
import { ConfigParser } from "../src/util/configParser";
import { QueryOpts, Query } from "../src/common/query";
import * as path from "path";
import * as fs from "fs";
......@@ -37,13 +38,11 @@ const configFile = process.argv[2];
const schemaFile = process.argv[3];
const config = ConfigParser.parse(configFile);
const referencePath = path.dirname(configFile);
const engine = new Engine();
const adapter = new PostgresAdapter(config.connection);
let schema = "";
const engine = new Engine(config);
const adapter = new PostgresAdapter(config.connections[0]);
config.metrics.forEach ((met) => engine.addMetric(met));
config.dimensions.forEach ((dim) => engine.addDimension(dim));
let schema = "";
for (let i = 0; i < config.buildViews.length; ++i) {
const view = config.buildViews[i].view;
......@@ -53,13 +52,13 @@ for (let i = 0; i < config.buildViews.length; ++i) {
// Cria uma tabela
let output = "-- View: " + alias + "\n";
if (process.env.BLENDB_ADAPTER === "postgres") {
output += "DROP VIEW IF EXISTS view_" + view.id + " CASCADE;\n";
output += "CREATE OR REPLACE VIEW view_" + view.id + " AS\n";
output += "DROP VIEW IF EXISTS " + view.name + " CASCADE;\n";
output += "CREATE OR REPLACE VIEW " + view.name + " AS\n";
}
else if (process.env.BLENDB_ADAPTER === "monet") {
output += "DROP VIEW view_" + view.id + " CASCADE;\n";
output += "CREATE VIEW view_" + view.id + " AS\n";
output += "DROP VIEW " + view.name + " CASCADE;\n";
output += "CREATE VIEW " + view.name + " AS\n";
}
else {
......@@ -77,11 +76,9 @@ for (let i = 0; i < config.buildViews.length; ++i) {
const view = config.buildViews[i].view;
const alias = config.buildViews[i].alias;
if (!view.origin) {
const materializedView = engine.query({
metrics: view.metrics,
dimensions: view.dimensions,
clauses: view.clauses
});
const qOpt: QueryOpts = { metrics: view.metrics,dimensions: view.dimensions,
clauses: view.clauses };
const materializedView = engine.query(new Query(qOpt));
const table = adapter.getQueryFromView(materializedView);
let query = "-- View: " + alias + "\n";
......
......@@ -61,6 +61,9 @@ echo "To set different user and port use npm run service -- <port> [<user>]"
echo "Run this commands, as root (or sudo) to finish the process and start blendb"
SYSTEMD_PATH=/etc/systemd/system/blendb.service
mkdir -p /var/log/
touch /var/log/blendb.log
chown root:$REAL_USER /var/log/blendb.log
echo -n "rm -f $SYSTEMD_PATH && "
echo -n "ln -s $WORKSPACE/service/blendb.service $SYSTEMD_PATH && "
echo "systemctl daemon-reload && systemctl restart blendb.service"
......
......@@ -271,6 +271,27 @@ traits:
description: |
Fields to be returned.
type: string
- formatable:
queryParameters:
format:
description: |
Response format. Defines if the response objects will be a
json or a csv-like file. The default value is json.
The csv-like formats are: csv, ssv and tsv which the
separator is comma, semi-colon and tab respectively.
example: "ssv+"
required: false
pattern: "^json$|^csv$|^ssv$|^tsv$"
type: string
- taggable:
queryParameters:
tags:
description: |
Tags that restrict the elements returned for your request.
Similar to a filter, but used in Blendb elements, not in
query results.
required: false
type: string
/metrics:
description: |
......@@ -279,13 +300,15 @@ traits:
system and their descriptions.
securedBy: [ null, oauth_2_0 ]
get:
is: [ formatable, taggable ]
/sources:
description: |
A Source represents a type of object that can be inserted in the database.
This collection allows the user to list all the sources available in the
system and their descriptions
securedBy: [ null, oauth_2_0 ]
securedBy: [ null, oauth_2_0 ]
get:
is: [ formatable ]
/dimensions:
description: |
......@@ -294,13 +317,23 @@ traits:
the system and their descriptions.
securedBy: [ null, oauth_2_0 ]
get:
is: [ formatable, taggable ]
/enumtypes:
description: |
A EnumType is short for enumerable type. This is a special data type that only accepts a few possible values. This
collection allows the user to list all the enumerable types available in the system, their descriptions and possible
values.
get:
securedBy: [ null, oauth_2_0 ]
get:
is: [ formatable ]
securedBy: [ null, oauth_2_0 ]
/tags:
description: |
A Tag can be placed in a metric or dimension to add some extra meaning
to it. Tags can be used to filter the amount of elements returned by a
route. Tags are like filters, but instead of filtering query results,
filter blendb elements.
get:
is: [ formatable ]
/data:
description: |
This is the main part of the API. You may query it for report
......@@ -309,7 +342,7 @@ traits:
start/end dates to refine your query.
type: base
get:
is: [ filtered ]
is: [ filtered, formatable ]
queryParameters:
metrics:
description: |
......
......@@ -142,17 +142,10 @@ export class MonetAdapter extends SQLAdapter {
pool.close();
}
/**
* Materialize a given view.
* @param view - View to be materialized.
*/
public materializeView(view: View): boolean {
return false;
}
/**
* Asynchronously insert one register into a given Source.
* @param source - Insertion "location".
* @param data - Data to be inserted.
* @param cb - Callback function which contains the query result.
* @param cb.error - Error information when the method fails.
* @param cb.result - Query result.
......
This diff is collapsed.
......@@ -77,6 +77,7 @@ export class PostgresAdapter extends SQLAdapter {
/**
* Asynchronously insert one register into a given Source.
* @param source - Insertion "location".
* @param data - Data to be inserted.
* @param cb - Callback function which contains the query result.
* @param cb.error - Error information when the method fails.
* @param cb.result - Query result.
......@@ -86,14 +87,6 @@ export class PostgresAdapter extends SQLAdapter {
this.executeQuery(query, cb);
}
/**
* Materialize a given view.
* @param view - View to be materialized.
*/
public materializeView(view: View): boolean {
return false;
}
/**
* Cast BlenDB data types to be used in PostgreSQL queries.
* @param quotedValue - SQL query attribute wrapped by quotes.
......
......@@ -27,6 +27,7 @@ import { Filter, FilterOperator } from "../core/filter";
import { AggregationType, RelationType, DataType } from "../common/types";
import { Operation, Opcode } from "../common/expression";
import { View } from "../core/view";
import { Tsort } from "../util/tsort";
/**
* Information required to make a join clause.
......@@ -62,6 +63,11 @@ interface QueryAndName {
name: string;
}
/** Dictonary indexed by view name, that returns the QueryAndName object. */
interface QNMap {
[key: string]: QueryAndName;
}
/**
* Two Dictionaries, both indexed with a dimension name.
* Used to get the views where a dimension is.
......@@ -90,7 +96,11 @@ export abstract class SQLAdapter extends Adapter {
* @param view - View to be translated.
*/
public getQueryFromView(view: View): string {
const partials = this.buildPartials(view).filter((i) => {
const map = this.buildPartials(view);
const topSort = Tsort.view(view);
const partials = topSort.map((i) => {
return (map[i]) ? map[i] : {query : "", name: i};
}).filter((i) => {
return i.query !== "";
}).map((i) => {
return i.name + " AS (" + i.query + ")";
......@@ -111,7 +121,30 @@ export abstract class SQLAdapter extends Adapter {
sort = " ORDER BY " + order;
}
return withClause + "SELECT * FROM " + this.viewName(view) + sort + ";";
const dimensions = view.dimensions.map((item) => {
return "\"" + item.name + "\"";
}).join(",");
const metrics = view.metrics.map((item) => {
return "\"" + item.name + "\"";
}).join(",");
let attributes = "";
if (dimensions.length > 0) {
if (metrics.length > 0) {
attributes = dimensions + "," + metrics;
}
else {
attributes = dimensions;
}
}
else {
attributes = metrics;
}
return withClause + "SELECT " + attributes + " FROM " + view.name + sort + ";";