songs.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. 'use strict';
  2. const coreClass = require("../core");
  3. const async = require('async');
  4. const mongoose = require('mongoose');
  5. module.exports = class extends coreClass {
  6. constructor(name, moduleManager) {
  7. super(name, moduleManager);
  8. this.dependsOn = ["utils", "cache", "db"];
  9. }
  10. initialize() {
  11. return new Promise((resolve, reject) => {
  12. this.cache = this.moduleManager.modules["cache"];
  13. this.db = this.moduleManager.modules["db"];
  14. this.io = this.moduleManager.modules["io"];
  15. this.utils = this.moduleManager.modules["utils"];
  16. async.waterfall([
  17. (next) => {
  18. this.cache.hgetall('songs', next);
  19. },
  20. (songs, next) => {
  21. if (!songs) return next();
  22. let songIds = Object.keys(songs);
  23. async.each(songIds, (songId, next) => {
  24. this.db.models.song.findOne({songId}, (err, song) => {
  25. if (err) next(err);
  26. else if (!song) this.cache.hdel('songs', songId, next);
  27. else next();
  28. });
  29. }, next);
  30. },
  31. (next) => {
  32. this.db.models.song.find({}, next);
  33. },
  34. (songs, next) => {
  35. async.each(songs, (song, next) => {
  36. this.cache.hset('songs', song.songId, this.cache.schemas.song(song), next);
  37. }, next);
  38. }
  39. ], async (err) => {
  40. if (err) {
  41. err = await this.utils.getError(err);
  42. reject(err);
  43. } else {
  44. resolve();
  45. }
  46. });
  47. });
  48. }
  49. /**
  50. * Gets a song by id from the cache or Mongo, and if it isn't in the cache yet, adds it the cache
  51. *
  52. * @param {String} id - the id of the song we are trying to get
  53. * @param {Function} cb - gets called once we're done initializing
  54. */
  55. async getSong(id, cb) {
  56. try { await this._validateHook(); } catch { return; }
  57. async.waterfall([
  58. (next) => {
  59. if (!mongoose.Types.ObjectId.isValid(id)) return next('Id is not a valid ObjectId.');
  60. this.cache.hget('songs', id, next);
  61. },
  62. (song, next) => {
  63. if (song) return next(true, song);
  64. this.db.models.song.findOne({_id: id}, next);
  65. },
  66. (song, next) => {
  67. if (song) {
  68. this.cache.hset('songs', id, song, next);
  69. } else next('Song not found.');
  70. },
  71. ], (err, song) => {
  72. if (err && err !== true) return cb(err);
  73. cb(null, song);
  74. });
  75. }
  76. /**
  77. * Gets a song by song id from the cache or Mongo, and if it isn't in the cache yet, adds it the cache
  78. *
  79. * @param {String} songId - the mongo id of the song we are trying to get
  80. * @param {Function} cb - gets called once we're done initializing
  81. */
  82. async getSongFromId(songId, cb) {
  83. try { await this._validateHook(); } catch { return; }
  84. async.waterfall([
  85. (next) => {
  86. this.db.models.song.findOne({ songId }, next);
  87. }
  88. ], (err, song) => {
  89. if (err && err !== true) return cb(err);
  90. else return cb(null, song);
  91. });
  92. }
  93. /**
  94. * Gets a song from id from Mongo and updates the cache with it
  95. *
  96. * @param {String} songId - the id of the song we are trying to update
  97. * @param {Function} cb - gets called when an error occurred or when the operation was successful
  98. */
  99. async updateSong(songId, cb) {
  100. try { await this._validateHook(); } catch { return; }
  101. async.waterfall([
  102. (next) => {
  103. this.db.models.song.findOne({_id: songId}, next);
  104. },
  105. (song, next) => {
  106. if (!song) {
  107. this.cache.hdel('songs', songId);
  108. return next('Song not found.');
  109. }
  110. this.cache.hset('songs', songId, song, next);
  111. }
  112. ], (err, song) => {
  113. if (err && err !== true) return cb(err);
  114. cb(null, song);
  115. });
  116. }
  117. /**
  118. * Deletes song from id from Mongo and cache
  119. *
  120. * @param {String} songId - the id of the song we are trying to delete
  121. * @param {Function} cb - gets called when an error occurred or when the operation was successful
  122. */
  123. async deleteSong(songId, cb) {
  124. try { await this._validateHook(); } catch { return; }
  125. async.waterfall([
  126. (next) => {
  127. this.db.models.song.deleteOne({ songId }, next);
  128. },
  129. (next) => {
  130. this.cache.hdel('songs', songId, next);
  131. }
  132. ], (err) => {
  133. if (err && err !== true) cb(err);
  134. cb(null);
  135. });
  136. }
  137. }