models/UB/virtualStores/mdb.js

/**
 *  @classdesc
 *  Virtual store implementation for storing content inside models `public` folders.
 *  Key conceptions:
 *
 *    - relative path created in format modelName|relativePathFromModelDir to hide real file place from client
 *    - OS user temp folder used for store temporary content
 *    - delete operation is forbidden since models must be under version control
 *
 *  Used in:
 *
 *    - ubm_form for store form def & js inside /public/forms
 *    - ubm_diagrams for store diagram inside /public/erdiagrams
 *    - e.t.c.
 *    
 * @class
 * @extends UB.virtualStores.Custom
 * @singleton
 */
UB.virtualStores.mdb = Object.create(UB.virtualStores.Custom);
/**
 * @private
 */
UB.virtualStores.mdb.fileTempInfoExt = '.fti';
/**
 * @private
 * @param {TubDocumentHandlerCustom} handler
 */
UB.virtualStores.mdb.getPermanentFileName = function(handler){
     var
        pathPart, filePath,
        content = handler.content;
    if (content.isDirty){
        filePath = this.getTempFileName(handler);
    }else{
        pathPart =  content.relPath.split('|');
        filePath = (pathPart.length === 2) ? App.domain.config.models.byName(pathPart[0]).path + pathPart[1] + content.fName : '';
    }
    return filePath;
};
/**
 * @inheritdoc
 */
UB.virtualStores.mdb.fillResponse = function(handler){
    var
        filePath,
        content = handler.content;

    filePath = content.isDirty ? this.getTempFileName(handler) : this.getPermanentFileName(handler);
    if (filePath){
        return {
            httpResultCode: 200,
            body: filePath,
            header: 'Content-Type: application/def', //TODO - fix me - content type must be calculated from extension. Find and use some existing node module?? //'application/json'
            isFromFile: true
        };
    }else{
        return {
            httpResultCode: 404
        };
    }
};
/**
 * @inheritdoc
*/
UB.virtualStores.mdb.saveContentToTempStore = function (handler){
    var
        content = handler.content,
        request = handler.request,
        fn;
    console.debug('--========saveContentToTempStore=====------');

    if (!request.getIsBodyLoaded()){
        request.setBodyAsUnicodeString('{}');
    }
    fn = this.getTempFileName(handler);
    console.debug('temp file is writen to ', fn);
    if (!request.saveBodyToFile(fn)){
        throw new Error('invalid temp path');
    }
    if (!writeFile(fn + this.fileTempInfoExt, content)){
        throw new Error('invalid temp path');
    }
    return true;
};
/**
 *  Must return true in case no exception
 *  load content and body from temporary file in the this.tempFolder'
 *
 * See {@link UB.virtualStores.Custom#loadContentFromTempStore}
 */
UB.virtualStores.mdb.loadContentFromTempStore = function (handler, aWithBody){
    var
        content = handler.content,
        request = handler.request,
        strCtnt, objCtnt, fn;
    console.debug('--========loadContentFromTempStore=====------ for ', handler.attribute.name);
    //toLog('handler = %', handler);

    fn = this.getTempFileName(handler);
    strCtnt = loadFile(fn + this.fileTempInfoExt);
    if (!strCtnt){
        return; // TODO - make difference between insert (do nothing) and update - raise
        //throw new Error('temporary content information not found for ' + handler.attribute.name);
    }
    objCtnt = JSON.parse(strCtnt);
    // move all property from file to handler.content
    _.forEach(objCtnt, function(key, value){
        content[key] = value;
    });
    if(aWithBody === TubLoadContentBody.Yes ){
        request.loadBodyFromFile(fn);
    }
    return true;
};
/**
 * @inheritdoc
 */
UB.virtualStores.mdb.loadBodyFromEntity = function(handler){
    var
        request = handler.request,
        content = handler.content,
        filePath = content.isDirty ? this.getTempFileName(handler) : this.getPermanentFileName(handler);

    console.debug('--===== loadBodyFromEntity ===--- try to load body from', filePath);
    return filePath ? request.loadBodyFromFile(filePath) : false;
};
/**
 * Do nothing here - just delete content. Content itself must be under external version control system (SVN, fossil)
 */
UB.virtualStores.mdb.moveToArchive = function (handler){
    return true; //this.deleteContent(handler);
};
/**
 * Do nothing here - content must be under external version control system (SVN, GIT, fossil)
 */
UB.virtualStores.mdb.deleteContent = function (){
    // nothing to do here
    return true;
};
/**
 * @inheritDoc
 */
UB.virtualStores.mdb.moveToPermanentStore = function (handler, aPrevRelPath){
    var
        content = handler.content,
        pathPart, oldFilePath, newFilePath,
        fs = require('fs');

    console.debug('--========moveToPermanentStore=====------');
    oldFilePath = this.getTempFileName(handler);

    pathPart =  content.relPath.split('|');
    if (pathPart.length !== 2){
        throw new Error('MDB store expect relPath in form modelName|pathRelativeToModelPublicFolder but got: ' + content.relPath);
    }else{
        newFilePath = App.domain.config.models.byName(pathPart[0]).path + pathPart[1];
        if (!fs.isDir(newFilePath)){
            fs.mkdirSync(newFilePath);
        }
        newFilePath = newFilePath + content.fName;
    }
    console.debug('move from ' + oldFilePath + ' to '+ newFilePath);
    if (!moveFile(oldFilePath, newFilePath)){
        throw new Error('Can\'t move file to permanent store');
    }
    deleteFile(oldFilePath + this.fileTempInfoExt);
    handler.content.isDirty = false;
    return true;
};