Skip to content
Snippets Groups Projects
Select Git revision
  • develop default protected
  • simmc-based
  • drill-experiment
  • tg-felipe
  • issue/97
  • issue/63
  • icde-2019-experiments
  • issue/85
  • master protected
  • issue/20
  • refactor/engine
  • issue/6
  • feature/diagrams
  • wip-transformers
14 results

collect.ts

Blame
  • collect.ts 6.64 KiB
    /*
     * 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 * as express from "express";
    import { Request } from "../types";
    import { Source, Field } from "../../core/source";
    import { EnumType } from "../../core/enumType";
    import { DataType } from "../../common/types";
    import { EnumHandler } from "../../util/enumHandler";
    
    /**
     * Dictionary indexed by a type name which return a
     * validation function that returns true if the
     * objetct is a valid object of that type
     * or false otherwise.
     */
    interface Valid{
        [key: string]: (value: any) => boolean;
    }
    
    /**
     * Constroller responsable for collect part from the API. In other
     * words, controller responsable for inserting data in BlenDB.
     */
    export class CollectCtrl {
        /**
         * Route that validates and insert data.
         * @param req - Object with request information
         * @param res - Object used to create and send the response
         * @param next - Call next middleware or controller. Not used but required
         * by typescript definition of route.
         */
        public static write(req: Request, res: express.Response, next: express.NextFunction) {
    
            const validador: Valid = {
                "integer": function(value: any) {
                    let test = parseInt(value, 10);
                    if (test === undefined || isNaN(value) ) {
                        return false;
                    }
    
                    else {
                        return true;
                    }
                },
                "float": function(value: any) {
                    let test = parseFloat(value);
                    if (test === undefined || isNaN(value) ) {
                        return false;
                    }
    
                    else {
                        return true;
                    }
                },
                "string": function(value: any) {
                    let test = typeof(value);
                    if (test === "string") {
                        return true;
                    }
    
                    else{
                        return false;
                    }
                },
                "date": function(value: any) {
    
                    let test: string[] = [];
                    let date = new Date(value);
                    try {
                        test = date.toISOString().split("T");
                    }
                    catch (e) {
                        return false;
                    }
                    if (test[0] === value){
                        return true;
                    }
                    else{
                        return false;
                    }
    
                },
                "boolean": function(value: any) {
                    let test = typeof(value);
                    if(test === "boolean"){
                        return true;
                    }else{
                        let test: string = value;
                        test = test.toLocaleLowerCase();
                        if (test === "true" || test === "false"){
                            return true;
                        }else{
                            return false;
                        }
                    }                    
                }
            };
    
            let fields: Field[] = [];
            let data: string[] = [];
            let types: string[] = [];
            let source: Source;
            let enumType: EnumType;
    
            const id: string = req.params.class;
            try {
                source = req.engine.getSourceByName(id);
                // If source does not exist them return error
    
                fields = source.fields;
    
                for (let i = 0; i < fields.length; i++){
                    data[i] = req.body[fields[i].name];
                    // check if the data is empty, however since data may be
                    // true/false, it must guarantee that it isn't a boolean
                    // then it'll test if it's empty
                    if (!(typeof(data[i]) === "boolean") && !data[i]){
                        throw new Error(
                            "The '" + fields[i].name + "' wasn't informed on json");
                    }
                }
    
                for (let i = 0; i < fields.length; i++){
                    // check if it's a valid enumtype
                    if (fields[i].dataType === DataType.ENUMTYPE){
                        enumType = req.engine.getEnumTypeByName(fields[i].enumType);
                        types = enumType.values;
                        let found: boolean = false;
                        for (let j = 0; j < types.length; j++){
                            if (data[i] === types[j]){
                            found = true;
                            break;
                            }
                        }
                        if (!found) {
                            throw new Error(
                                "The value '" +  data[i] + "' from '" + fields[i].name +
                                "' isn't listed on " + fields[i].enumType);
                        }
                    }
    
                    else if (fields[i].dataType !== DataType.NONE){
                    // check if it's a valid datatype from query
                        if (!validador[EnumHandler.stringfyDataType(fields[i].dataType)](data[i]) === true){
                            throw new Error(
                                "The value '" +  data[i] + "' from '" + fields[i].name +
                                "' isn't a type " + [EnumHandler.stringfyDataType(fields[i].dataType)]);
                        }
                    }                
                }
            }
    
            catch (e) {
                res.status(500).json({
                    message: "Query execution failed: " +
                    "Could not construct query with the given parameters.",
                    error: e.message
                 });
                return;
            }
    
            req.adapter.insertIntoSource(source, req.body, (err: Error, result: any[]) => {
                if (err) {
                    res.status(500).json({
                        message: "Insertion has failed",
                        error: err
                    });
                    return;
                }
                else{
                    res.status(200).json({message: "Data has been successfully received and stored by the server"});
                    return;
                }
    
            });
    
        }
    }