Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

StageR can store binary files in a file storage independant from the database storage which is used to store JSON documents. The file handler is a pluggable module that provides StageR with the logic to store and read files from an external file storage application. The internal implementation of the file handler and the supporting file storage application used is up to the users needs. The module needs to provide a way to read and write file streams to the underlying file storage application.


StageR provides a simple file handler which uses a local file system folder its file storage application.

Use the sample code (of the local file handler) below as a template to create new file handlers.

Code Block
languagetext
themeRDark
'use strict'

 


var crypto = require('crypto')


var async = require('async')


var util = require('util')


var zlib = require('zlib')


var constants = require('../constants/general.server.constants')


var fs = require('fs-extra')


var path = require('path')

 


function localFileHandler (options) {

  

  options = options || {}

  

  var hashKey = options.hashkey || function (value)
{
    return
 {
    return crypto.createHash('md5').update(value).digest('hex')

  }
  if

  }
  if (!options.encryption)
{
    throw new
 {
    throw new Error('options.encryption is required')

  }
  var encryption =

  }
  var encryption = options.encryption

  

  if (!options.destination)
{
    throw new
 {
    throw new Error('options.destination is required')

  }
  var destination = options.destination
 
  return {
    getFolderDestination: function (storageUnit, scope, key, callback) {
      var filePrefix = hashKey(key)
      var firstLevel =

  }
  var destination = options.destination

  return {
    getFolderDestination: function (storageUnit, scope, key, callback) {
      var filePrefix = hashKey(key)
      var firstLevel = filePrefix.substring(0, 3)

      var secondLevel =

      var secondLevel = filePrefix.substring(3, 6)

      var storeFileLocation =

      var storeFileLocation = path.join(destination, storageUnit, scope, firstLevel, secondLevel)

      try {
        

      try {
        fs.existsSync(storeFileLocation) || fs.mkdirsSync(storeFileLocation)

      } catch

      } catch (err)
{
        return
 {
        return callback(err)

      }
      return

      }
      return callback(null, storeFileLocation)

    

    },

    

    saveStream: function (storageUnit, scope, key, filename, mimetype, stream, encrypt, compress, callback)
{
      
 {
      this.getFolderDestination(storageUnit, scope, key, function (err, destinationFolder)
{
        if
 {
        if (err)
{
          return
 {
          return callback(err)

        }
 
        var encodedFilename =

        }

        var encodedFilename = hashKey(key) + '-' +
filename
        var finalPath =
 filename
        var finalPath = path.join(destinationFolder, encodedFilename)

        var outStream =

        var outStream = fs.createWriteStream(finalPath)

 
        


        async.waterfall([

          function

          function (wfNext)
{
            if (encrypt
 {
            if (encrypt === true)
{
              var encKey =
 {
              var encKey = encryption.generateKeyId()

              var encIv =

              var encIv = encryption.generateiv()

              

              encryption.getCipher(storageUnit, encKey, encIv, function (err, cipher)
{
                
 {
                wfNext(err, cipher, encKey, encIv)

              })
            } else {
              

              })
            } else {
              wfNext(null, null, null, null)

            }
          },
          function (cipher, encKey, encIv, wfNext) {
            if (compress === true) {
              stream =

            }
          },
          function (cipher, encKey, encIv, wfNext) {
            if (compress === true) {
              stream = stream.pipe(zlib.createDeflate())

            }
            if (encrypt

            }
            if (encrypt === true)
{
              stream =
 {
              stream = stream.pipe(cipher)

            }
            

            }
            stream.pipe(outStream)

            

            outStream.on('error', wfNext)

            

            outStream.on('finish', function ()
{
              
 {
              wfNext(null, destinationFolder, finalPath, outStream.bytesWritten, encKey, encIv, (compress === true))

            })
          }
        ], callback)
      })
    },
    getStream: function (storageUnit, scope, key, srFileId, encKey, encIv, isCompressed, callback) {
      var self = this
      async.waterfall([
        function (wfNext) {
          

            })
          }
        ], callback)
      })
    },
    getStream: function (storageUnit, scope, key, srFileId, encKey, encIv, isCompressed, callback) {
      var self = this
      async.waterfall([
        function (wfNext) {
          self.getFolderDestination(storageUnit, scope, key, function (err, destinationFolder)
{
            if
 {
            if (err)
{
              return
 {
              return wfNext(err)

            }
            var encodedFilename =

            }
            var encodedFilename = hashKey(key) + '-' +
srFileId
            var fileLocation =
 srFileId
            var fileLocation = path.join(destinationFolder, encodedFilename)

            var fileStream =

            var fileStream = fs.createReadStream(fileLocation)

            

            wfNext(null, fileStream)

          })
        },
        function (fileStream, wfNext) {
          if

          })
        },
        function (fileStream, wfNext) {
          if (!util.isNullOrUndefined(encKey))
{
            
 {
            encryption.getDecipher(storageUnit, encKey, encIv, function (err, decipher)
{
              
 {
              wfNext(err, fileStream.pipe(decipher))

            })
          } else {
            

            })
          } else {
            wfNext(null, fileStream)

          }
        }, function

          }
        }, function (fileStream, wfNext)
{
          if
 {
          if (isCompressed === true)
{
            
 {
            wfNext(null, fileStream.pipe(zlib.createInflate()))

          } else {
            

          } else {
            wfNext(null, fileStream)

          }
        

          }
        }], callback)

    

    },

    

    deletePath: function (path, callback)
{
      if
 {
      if (callback)
{
        return
 {
        return fs.remove(path, callback)

      }
      return

      }
      return fs.removeSync(path)

    

    },

    

    deleteFileById: function (storageUnit, scope, key, srFileId, callback)
{
      var self = this
      
 {
      var self = this
      self.getFolderDestination(storageUnit, scope, key, function (err, destination)
{
        if
 {
        if (err)
{
          return
 {
          return callback(err)

        }
        var hashedKey =

        }
        var hashedKey = hashKey(key)

        var filePath =

        var filePath = path.join(destination, hashedKey + '-' + srFileId)

        

        self.deletePath(filePath, callback)

      })
    },
    deleteFilesByKey: function

      })
    },
    deleteFilesByKey: function (storageUnit, scope, key, callback)
{
      var self = this
      var hashedKey =
 {
      var self = this
      var hashedKey = hashKey(key)

      if

      if (scope === constants.recordScope)
{
        var filePath =
 {
        var filePath = path.join(destination, storageUnit, '*', '*', '*', hashedKey + '-*')

        

        self.deletePath(filePath, callback)

      } else {
        

      } else {
        self.getFolderDestination(storageUnit, scope, key, function (err, destination)
{
          if
 {
          if (err)
{
            return
 {
            return callback(err)

          }
          var filePath =

          }
          var filePath = path.join(destination, hashedKey + '-*')

          

          self.deletePath(filePath, callback)

        })
      }
    },
    deleteFilesByScope: function (storageUnit, scope, callback) {
      var scopeLocation =

        })
      }
    },
    deleteFilesByScope: function (storageUnit, scope, callback) {
      var scopeLocation = path.join(destination, storageUnit, scope)

      

      this.deletePath(scopeLocation, callback)

    

    },

    

    deleteFilesByStorageUnit: function (storageUnit, callback)
{
      var storageUnitLocation =
 {
      var storageUnitLocation = path.join(destination, storageUnit)

      

      this.deletePath(storageUnitLocation, callback)

    

    },

    

    changeFileNameToId: function (storageUnit, scope, key, filename, srFileId, callback)
{
      
 {
      this.getFolderDestination(storageUnit, scope, key, function (err, destination)
{
        if
 {
        if (err)
{
          return
 {
          return callback(err)

        }
        var hashedKey =

        }
        var hashedKey = hashKey(key)

        var inFilePath =

        var inFilePath = path.join(destination, hashedKey + '-' + filename)

        var outFilePath =

        var outFilePath = path.join(destination, hashedKey + '-' + srFileId)

        

        fs.rename(inFilePath, outFilePath, function (err)
{
          
 {
          callback(err, outFilePath)

        })
      })
    },
    fileExists: function (path, callback) {
      if (callback) {
        return

        })
      })
    },
    fileExists: function (path, callback) {
      if (callback) {
        return fs.exists(path, callback)

      }
      return

      }
      return fs.existsSync(path)

    }
  }
}
 

    }
  }
}

module.exports = localFileHandler