<commit_before>/**
 * 
 * ©2016 EdgeVerve Systems Limited (a fully owned Infosys subsidiary),
 * Bangalore, India. All Rights Reserved.
 * 
 */
var loopback = require('loopback');
var _ = require('lodash');
var utils = require('../common/utils');

module.exports = function(RED) {

    function SyncObserverNode(config) {
        RED.nodes.createNode(this, config);
        var node = this;

        var modelName = config.modelname;
        var method = config.method;

        var Model = loopback.findModel(modelName, node.callContext);

        if (Model !== undefined) {

            utils.removeOldObservers(Model, node.id);

            Model.observe(method, new observer(node, modelName, method).observe);
        }

        node.on('close', function() {
            if (Model != undefined) {
                utils.removeOldObservers(Model, node.id);
            }
        });
    }
    RED.nodes.registerType("sync-observer", SyncObserverNode);
}

var observer = function(node, modelName, methodName) {
    var _node = node;
    var _modelName = modelName;
    var _methodName = methodName;
  
    this.observe = function(ctx, next) {        
        var id = _node.id;

        // sort of an hack to return a function in case this method is called by
        // node itself.
        if (ctx === null && next == null) {
            var getNRId = function() {
                return id;
            };

            return getNRId;
        }

        if (!utils.compareContext(_node, ctx)) {
            return next();
        }

        var msg = {};

        if (ctx.Model !== undefined) {
            // Ajith: Added following line to add Model to the msg
            msg.Model = ctx.Model;
            msg.payload = ctx.Model.definition.name + '.' + _methodName + ' triggered';
        } else {
            msg.payload = _modelName + '.' + _methodName + ' triggered';
        }
        msg.callContext = _node.callContext;
        // msg.next = next;
        msg.ctx = JSON.parse(JSON.stringify(ctx));

        msg.next = function(msg) {

            var err = {};
            if (_methodName === 'after save' || _methodName === 'after delete') {
                 if (typeof msg.payload === 'string' && msg.payload.startsWith('Error')) {
                    err = new Error(msg.payload);
                    err.retriable = true;
                    return next(err);
                 } else if (typeof msg.error === 'string') {
                     err = new Error(msg.error);
                     err.retriable = true;
                     return next(err);
                 } else if (msg.payload.error || msg.error) {
                    err = new Error(msg.payload.error || msg.error.message);
                    err.retriable = true;
                    return next(err);
                 }      
            } 

            if (msg.payload || msg.payload.error || msg.error) {
                //reporting errors in flow execution back to loopback
                return next(msg.payload.error || msg.error);
            }
            // var updatedCtx = msg.ctx;
            var updatedCtx = JSON.parse(JSON.stringify(msg.ctx));
            // console.log('callback function called. returning to loopback.
            // updatedCtx =', updatedCtx);

            if (updatedCtx.query !== undefined) {
                // ctx.query = updatedCtx.query;
                _.assign(ctx.query, updatedCtx.query);
            }

            if (updatedCtx.instance !== undefined) {

                _.assign(ctx.instance, updatedCtx.instance);
                // console.log('new instance = ', ctx.instance);
            }

            if (updatedCtx.data !== undefined) {
                _.assign(ctx.data, updatedCtx.data);
            }
            next();

        }

        _node.send(msg);
    }

    this.observe.getId = function() {
            return _node.id;
    }

}<commit_msg>it should be possible to change the instance on which observer was written<commit_after>/**
 * 
 * ©2016 EdgeVerve Systems Limited (a fully owned Infosys subsidiary),
 * Bangalore, India. All Rights Reserved.
 * 
 */
var loopback = require('loopback');
var _ = require('lodash');
var utils = require('../common/utils');

module.exports = function (RED) {

    function SyncObserverNode(config) {
        RED.nodes.createNode(this, config);
        var node = this;

        var modelName = config.modelname;
        var method = config.method;

        var Model = loopback.findModel(modelName, node.callContext);

        if (Model !== undefined) {

            utils.removeOldObservers(Model, node.id);

            Model.observe(method, new observer(node, modelName, method).observe);
        }

        node.on('close', function () {
            if (Model != undefined) {
                utils.removeOldObservers(Model, node.id);
            }
        });
    }
    RED.nodes.registerType("sync-observer", SyncObserverNode);
}

var observer = function (node, modelName, methodName) {
    var _node = node;
    var _modelName = modelName;
    var _methodName = methodName;

    this.observe = function (ctx, next) {
        var id = _node.id;

        // sort of an hack to return a function in case this method is called by
        // node itself.
        if (ctx === null && next == null) {
            var getNRId = function () {
                return id;
            };

            return getNRId;
        }

        if (!utils.compareContext(_node, ctx)) {
            return next();
        }

        var msg = {};

        if (ctx.Model) {
            // Ajith: Added following line to add Model to the msg
            msg.Model = ctx.Model;
            msg.payload = ctx.Model.definition.name + '.' + _methodName + ' triggered';
        } else {
            msg.payload = _modelName + '.' + _methodName + ' triggered';
        }
        var callContext = ctx.options || _node.callContext;
        ctx.callContext = JSON.parse(JSON.stringify(callContext));
        msg.ctx = ctx;

        msg.next = function (msg1) {
            ctx.options = callContext;
            var err = msg1.error || (msg1.payload && msg1.payload.error);
            if (err) {
                if (typeof err === 'string') {
                    err = new Error(err);
                    err.retriable = true;
                }
                return next(err);
            }
            if (msg1.ctx.instance) {
                _.assign(ctx.instance, msg1.ctx.instance);
            }
            next();
        }


        _node.send(msg);
    }

    this.observe.getId = function () {
        return _node.id;
    }

}
{'fraction_non_alphanumeric': 0.12102874432677761, 'fraction_numerical': 0.002118003025718608, 'mean_word_length': 1.6048069345941687, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3733631', 'n_tokens_mistral': 1848, 'n_tokens_neox': 1771, 'n_words': 445}