gridfs.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. const logger = require('@alias/logger')('growi:service:fileUploaderGridfs');
  2. const mongoose = require('mongoose');
  3. const util = require('util');
  4. module.exports = function(crowi) {
  5. 'use strict';
  6. const lib = {};
  7. // instantiate mongoose-gridfs
  8. const gridfs = require('mongoose-gridfs')({
  9. collection: 'attachmentFiles',
  10. model: 'AttachmentFile',
  11. mongooseConnection: mongoose.connection
  12. });
  13. // obtain a model
  14. const AttachmentFile = gridfs.model;
  15. const Chunks = mongoose.model('Chunks', gridfs.schema, 'attachmentFiles.chunks');
  16. // create promisified method
  17. AttachmentFile.promisifiedWrite = util.promisify(AttachmentFile.write).bind(AttachmentFile);
  18. lib.deleteFile = async function(attachment) {
  19. const attachmentFile = await AttachmentFile.findOne({ filename: attachment.fileName });
  20. AttachmentFile.unlinkById(attachmentFile._id, function(error, unlinkedFile) {
  21. if (error) {
  22. throw new Error(error);
  23. }
  24. });
  25. };
  26. /**
  27. * get size of data uploaded files using (Promise wrapper)
  28. */
  29. const getCollectionSize = () => {
  30. return new Promise((resolve, reject) => {
  31. Chunks.collection.stats((err, data) => {
  32. if (err) {
  33. reject(err);
  34. }
  35. resolve(data.size);
  36. });
  37. });
  38. };
  39. /**
  40. * chech storage for fileUpload reaches MONGO_GRIDFS_TOTAL_LIMIT (for gridfs)
  41. */
  42. lib.checkCapacity = async(uploadFileSize) => {
  43. // skip checking if env var is undefined
  44. if (process.env.MONGO_GRIDFS_TOTAL_LIMIT == null) {
  45. return true;
  46. }
  47. const usingFilesSize = await getCollectionSize();
  48. return (+process.env.MONGO_GRIDFS_TOTAL_LIMIT > usingFilesSize + +uploadFileSize);
  49. };
  50. lib.uploadFile = async function(fileStream, attachment) {
  51. logger.debug(`File uploading: fileName=${attachment.fileName}`);
  52. return AttachmentFile.promisifiedWrite(
  53. {
  54. filename: attachment.fileName,
  55. contentType: attachment.fileFormat
  56. },
  57. fileStream);
  58. };
  59. /**
  60. * Find data substance
  61. *
  62. * @param {Attachment} attachment
  63. * @return {stream.Readable} readable stream
  64. */
  65. lib.findDeliveryFile = async function(attachment) {
  66. const attachmentFile = await AttachmentFile.findOne({ filename: attachment.fileName });
  67. if (attachmentFile == null) {
  68. throw new Error(`Any AttachmentFile that relate to the Attachment (${attachment._id.toString()}) does not exist in GridFS`);
  69. }
  70. // return stream.Readable
  71. return AttachmentFile.readById(attachmentFile._id);
  72. };
  73. return lib;
  74. };