songs.js 4.0 KB

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