modules/Repository/ServerRepository.js

/**
 * Repository for server-side data retrieve.
 * Implement {@link ServerRepository#select} method able to return initialized {@link TubDataStore}
 *
 * Usually created using {@link UB#Repository UB.Repository} function.
 *
 * @example
 *
 *      var store = UB.Repository('my_entity').attrs('id')
 *       .where('code', 'in', ['1', '2', '3'])  // code in ('1', '2', '3')
 *       .where('name', 'contains', 'Homer'). // name like '%homer%'
 *       .where('birtday', 'geq', new Date()).where('birtday', 'leq', new Date() + 10) //(birtday >= '2012-01-01') AND (birtday <= '2012-01-02')
 *       .where('[age] -10', '>=', {age: 15}, 'byAge') // (age + 10 >= 15)
 *       .where('', 'match', 'myvalue'). // perform full text search for entity (fts mixin must be configured for entity)
 *       .logic('(byStrfType OR bySrfKindID)AND(dasdsa)')
 *       .select();
 *
 * @module ServerRepository
 * @extends CustomRepository
 * @author pavel.mash
 */

var CustomRepository = require('./CustomRepository.js'),
    LocalDataStore = require('LocalDataStore');

/**
 * Create a new server side repository. Operate in two mode:
 *
 *  - if connection is not passed, we consider this is server thread (i.e. operate with the same server code run in),
 *    and result of {ServerRepository#select} method is {TubDataStore}
 *  - if connection is passed, we consider this is remote server connection and result of {ServerRepository#select} is
 *
 * @constructor
 * @param {UBConnection|null} connection remote server connection
 * @param {String} entityName name of Entity we create for
 */
function ServerRepository(connection, entityName){
     //noinspection JSUnresolvedFunction
    CustomRepository.call(this, entityName);
    /**
     * @type {UBConnection|null}
     */
    this.connection = connection;
}
ServerRepository.prototype = Object.create(CustomRepository.prototype);
ServerRepository.prototype.constructor = ServerRepository;

/**
 * @param {Boolean} [resultInPlainText=false] If true - result is {String}
 * @return {Array.<Object>|String}
 */
ServerRepository.prototype.selectAsObject = function(resultInPlainText){
    var
        inst, conn, res;

    if (process.isServer){ // inside server thread
        inst = new TubDataStore(this.entityName);
        inst.run('select', this.ubRequest());
        res = resultInPlainText ? inst.asJSONObject : JSON.parse(inst.asJSONObject);
        inst.freeNative(); //release memory ASAP
        return res;
    } else {
        conn = this.connection;
        if (resultInPlainText){
            throw new Error('plainTextResult parameter not applicable in this context');
        }
        return LocalDataStore.selectResultToArrayOfObjects(conn.run(this.ubRequest()));
    }
};                                           

/**
 * @param {Boolean} [resultInPlainText=false] If true - result is {String}
 * @return {TubCachedData|String} // todo this is TubCachedData structure!!!
 */
ServerRepository.prototype.selectAsArray = function(resultInPlainText){
    var
        inst, res;

    if (process.isServer) { // inside server thread
        inst = new TubDataStore(this.entityName);
        inst.run('select', this.ubRequest());
        res = resultInPlainText ? inst.asJSONArray : {resultData: JSON.parse(inst.asJSONArray)};
        if ((!resultInPlainText) && (this.options && this.options.totalRequired)){
            inst.currentDataName = '__totalRecCount';
            res.__totalRecCount = inst.get(0);
        }
        inst.freeNative(); //release memory ASAP
        return res;
    } else {
        if (resultInPlainText){
            throw new Error('plainTextResult parameter not applicable in this context');
        }
        return this.connection.query(this.ubRequest());
    }
};

/**
 * Create new, or use passed as parameter {@link TubDataStore} and run {@link TubDataStore#select} method passing result of {@link CustomRepository#getRunListItem} as config.
 * Do not work for remote connection.
 *
 * @param {TubDataStore} [instance] Optional instance for in-thread execution context. If passed - run select for it (not create new instance) and return instance as a result.
 *   Be careful - method do not check instance is created for entity you pass to Repository constructor.
 * @return {TubDataStore|Array.<Object>}
 */
ServerRepository.prototype.selectAsStore = function(instance){
    var inst;

    if (this.connection){
        if (instance) { throw new Error('parameter instance applicable only for in-server execution context'); }
        inst = this.selectAsObject();
    } else {
        inst = instance || new TubDataStore(this.entityName);
        inst.run('select', this.ubRequest());
    }
    return inst;
};

/**
 * @param {TubDataStore} [instance] Optional instance for in-thread execution context. If passed - run select for it (not create new instance) and return instance as a result.
 * @return {TubDataStore}
 */
ServerRepository.prototype.select = function(instance){
   return this.selectAsStore(instance);
};

module.exports = ServerRepository;