view app/query.service.ts @ 9:402c7229dc7c

more query generation.
author casties
date Wed, 20 Jan 2016 11:32:31 +0100
parents fa646ee46c19
children 66dce99cef4e
line wrap: on
line source

import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';

import 'rxjs/Rx'; // import all RxJS operators

import {QueryMode} from './query-mode';
import {QueryState} from './query-state';
import {QueryStep} from './query-step';

@Injectable()
export class QueryService {
        
    public neo4jBaseUrl = 'http://localhost:7474/db/data';
    public state: QueryState;
    public ismiObjectTypes: any;
    
    public QUERY_MODES: QueryMode[] = [
        {id: 'type_is', label:'Object type is'},
        {id: 'att_contains', label: 'Attribute contains'}];
        
    constructor(private _http: Http) {
        this.state = {
            'steps': [],
            'cypherQuery': '',
            'cypherParams': {}, 
            'results': [],
            'resultTypes': '',
            'numResults': 0
        };
    }
    
    setup() {
        this.setupIsmiObjectTypes();
    }
    
    getState() {
        return this.state;
    }
    
    getQueryModes(): QueryMode[] {
        return this.QUERY_MODES;
    }
    
    getQueryOptions(queryMode: QueryMode) {
        var options = ['a1', 'b1', 'c1'];
        if (queryMode.id === 'att_contains') {
            if (this.state.attributeCypherQuery) {
                var res = this.fetchCypherResult(this.state.attributeCypherQuery);
                res.subscribe(
                    data => {
                        console.debug("neo4j data=", data);
                        var atts = data.results[0].data.map(elem => elem.row[0]).filter(elem => elem[0] != "_");
                        console.debug("ismi attributes=", atts);
                    },
                    err => console.error("neo4j error=", err),
                    () => console.debug('neo4j query Complete')
                );
            }
            options = ['d', 'e', 'f'];
        } else if (queryMode.id === 'type_is') {
            options = this.ismiObjectTypes;
        }
        console.debug("getQueryOptions returns: ", options);
        return options;
    }
    
    setupIsmiObjectTypes() {
        var query = `MATCH (n) WITH DISTINCT labels(n) AS labels
                UNWIND labels AS label 
                RETURN DISTINCT label ORDER BY label`;

        var res = this.fetchCypherResult(query);
        res.subscribe(
            data => {
                console.debug("neo4j data=", data);
                this.ismiObjectTypes = data.results[0].data.map(elem => elem.row[0]).filter(elem => elem[0] != "_");
                console.debug("ismi types=", this.ismiObjectTypes);
                },
            err => console.error("neo4j error=", err),
            () => console.debug('neo4j query Complete')
        );
    }
    
    setQueryStep(index: number, step: QueryStep) {
        this.state.steps[index] = step;
        this.createCypherQuery();
    }
    
    createCypherQuery() {
        var resultCypher = '';
        var attCypher = '';
        var returnType = '';
        this.state.steps.forEach((step) => {
            if (step.mode.id === 'type_is') {
                resultCypher = `MATCH (e:${step.objectType}) return e`;
                returnType = 'node';
                attCypher = `MATCH (e:${step.objectType}) WITH DISTINCT keys(e) AS atts
                    UNWIND atts AS att 
                    RETURN DISTINCT att ORDER BY att`;
            }
        });
        this.state.resultCypherQuery = resultCypher;
        this.state.attributeCypherQuery = attCypher;
        this.state.resultTypes = returnType;
    }
    
    updateQuery() {
        this.createCypherQuery();
        var query = this.state.resultCypherQuery;
        var params = this.state.cypherParams;
        var res = this.fetchCypherResult(query, params);
        res.subscribe(
            data => {
                console.debug("neo4j data=", data);
                this.state.results = data.results[0].data.map(elem => elem.row[0]);
                this.state.numResults = this.state.results.length;
            },
            err => console.error("neo4j error=", err),
            () => console.debug('neo4j query Complete')
        );
    }
    
    fetchCypherResult(query: string, params = {}) {
        var headers = new Headers();
        headers.append('Authorization', 'Basic ' + btoa('neo4j' + ':' + 'neo5j'));
        headers.append('Content-Type', 'application/json');
        headers.append('Accept', 'application/json');
        // put headers in options
        var opts = {'headers': headers};
        // create POST data from query
        var data = JSON.stringify({'statements': [
            {'statement': query, 'parameters': params}
            ]});
        // make post request asynchronously
        var resp = this._http.post(this.neo4jBaseUrl+'/transaction/commit', data, opts)
        // filter result as JSON
        .map(res => res.json());
        // return Observable
        return resp;
    }
}