songs.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. import async from "async";
  2. import mongoose from "mongoose";
  3. import CoreClass from "../core";
  4. let SongsModule;
  5. let CacheModule;
  6. let DBModule;
  7. let UtilsModule;
  8. class _SongsModule extends CoreClass {
  9. // eslint-disable-next-line require-jsdoc
  10. constructor() {
  11. super("songs");
  12. SongsModule = this;
  13. }
  14. /**
  15. * Initialises the songs module
  16. *
  17. * @returns {Promise} - returns promise (reject, resolve)
  18. */
  19. async initialize() {
  20. this.setStage(1);
  21. CacheModule = this.moduleManager.modules.cache;
  22. DBModule = this.moduleManager.modules.db;
  23. UtilsModule = this.moduleManager.modules.utils;
  24. const songModel = await DBModule.runJob("GET_MODEL", { modelName: "song" });
  25. const songSchema = await CacheModule.runJob("GET_SCHEMA", { schemaName: "song" });
  26. this.setStage(2);
  27. return new Promise((resolve, reject) =>
  28. async.waterfall(
  29. [
  30. next => {
  31. this.setStage(2);
  32. CacheModule.runJob("HGETALL", { table: "songs" })
  33. .then(songs => {
  34. next(null, songs);
  35. })
  36. .catch(next);
  37. },
  38. (songs, next) => {
  39. this.setStage(3);
  40. if (!songs) return next();
  41. const songIds = Object.keys(songs);
  42. return async.each(
  43. songIds,
  44. (songId, next) => {
  45. songModel.findOne({ songId }, (err, song) => {
  46. if (err) next(err);
  47. else if (!song)
  48. CacheModule.runJob("HDEL", {
  49. table: "songs",
  50. key: songId
  51. })
  52. .then(() => next())
  53. .catch(next);
  54. else next();
  55. });
  56. },
  57. next
  58. );
  59. },
  60. next => {
  61. this.setStage(4);
  62. songModel.find({}, next);
  63. },
  64. (songs, next) => {
  65. this.setStage(5);
  66. async.each(
  67. songs,
  68. (song, next) => {
  69. CacheModule.runJob("HSET", {
  70. table: "songs",
  71. key: song.songId,
  72. value: songSchema(song)
  73. })
  74. .then(() => next())
  75. .catch(next);
  76. },
  77. next
  78. );
  79. }
  80. ],
  81. async err => {
  82. if (err) {
  83. err = await UtilsModule.runJob("GET_ERROR", { error: err });
  84. reject(new Error(err));
  85. } else resolve();
  86. }
  87. )
  88. );
  89. }
  90. /**
  91. * Gets a song by id from the cache or Mongo, and if it isn't in the cache yet, adds it the cache
  92. *
  93. * @param {object} payload - object containing the payload
  94. * @param {string} payload.id - the id of the song we are trying to get
  95. * @returns {Promise} - returns a promise (resolve, reject)
  96. */
  97. GET_SONG(payload) {
  98. return new Promise((resolve, reject) => {
  99. let songModel;
  100. SongsModule.log("ERROR", "HOW DOES THIS WORK!?!?!??!?!?!?!??!?!??!?!?!?!");
  101. DBModule.runJob("GET_MODEL", { modelName: "song" }, this)
  102. .then(model => {
  103. songModel = model;
  104. })
  105. .catch(console.error);
  106. return async.waterfall(
  107. [
  108. next => {
  109. if (!mongoose.Types.ObjectId.isValid(payload.id)) return next("Id is not a valid ObjectId.");
  110. return CacheModule.runJob("HGET", { table: "songs", key: payload.id }, this)
  111. .then(song => {
  112. next(null, song);
  113. })
  114. .catch(next);
  115. },
  116. (song, next) => {
  117. if (song) return next(true, song);
  118. return songModel.findOne({ _id: payload.id }, next);
  119. },
  120. (song, next) => {
  121. if (song) {
  122. CacheModule.runJob(
  123. "HSET",
  124. {
  125. table: "songs",
  126. key: payload.id,
  127. value: song
  128. },
  129. this
  130. ).then(song => next(null, song));
  131. } else next("Song not found.");
  132. }
  133. ],
  134. (err, song) => {
  135. if (err && err !== true) return reject(new Error(err));
  136. return resolve({ song });
  137. }
  138. );
  139. });
  140. }
  141. /**
  142. * Gets a song by song id from the cache or Mongo, and if it isn't in the cache yet, adds it the cache
  143. *
  144. * @param {object} payload - an object containing the payload
  145. * @param {string} payload.songId - the mongo id of the song we are trying to get
  146. * @returns {Promise} - returns a promise (resolve, reject)
  147. */
  148. GET_SONG_FROM_ID(payload) {
  149. return new Promise((resolve, reject) => {
  150. let songModel;
  151. SongsModule.log("ERROR", "HOW DOES THIS WORK!?!?!??!?!?!?!??!?!??!?!?!?!");
  152. DBModule.runJob("GET_MODEL", { modelName: "song" }, this)
  153. .then(model => {
  154. songModel = model;
  155. })
  156. .catch(console.error);
  157. return async.waterfall(
  158. [
  159. next => {
  160. songModel.findOne({ songId: payload.songId }, next);
  161. }
  162. ],
  163. (err, song) => {
  164. if (err && err !== true) return reject(new Error(err));
  165. return resolve({ song });
  166. }
  167. );
  168. });
  169. }
  170. /**
  171. * Gets a song from id from Mongo and updates the cache with it
  172. *
  173. * @param {object} payload - an object containing the payload
  174. * @param {string} payload.songId - the id of the song we are trying to update
  175. * @returns {Promise} - returns a promise (resolve, reject)
  176. */
  177. UPDATE_SONG(payload) {
  178. // songId, cb
  179. return new Promise((resolve, reject) => {
  180. let songModel;
  181. SongsModule.log("ERROR", "HOW DOES THIS WORK!?!?!??!?!?!?!??!?!??!?!?!?!");
  182. DBModule.runJob("GET_MODEL", { modelName: "song" }, this)
  183. .then(model => {
  184. songModel = model;
  185. })
  186. .catch(console.error);
  187. return async.waterfall(
  188. [
  189. next => {
  190. songModel.findOne({ _id: payload.songId }, next);
  191. },
  192. (song, next) => {
  193. if (!song) {
  194. CacheModule.runJob("HDEL", {
  195. table: "songs",
  196. key: payload.songId
  197. });
  198. return next("Song not found.");
  199. }
  200. return CacheModule.runJob(
  201. "HSET",
  202. {
  203. table: "songs",
  204. key: payload.songId,
  205. value: song
  206. },
  207. this
  208. )
  209. .then(song => {
  210. next(null, song);
  211. })
  212. .catch(next);
  213. }
  214. ],
  215. (err, song) => {
  216. if (err && err !== true) return reject(new Error(err));
  217. return resolve(song);
  218. }
  219. );
  220. });
  221. }
  222. /**
  223. * Deletes song from id from Mongo and cache
  224. *
  225. * @param {object} payload - returns an object containing the payload
  226. * @param {string} payload.songId - the id of the song we are trying to delete
  227. * @returns {Promise} - returns a promise (resolve, reject)
  228. */
  229. DELETE_SONG(payload) {
  230. // songId, cb
  231. return new Promise((resolve, reject) => {
  232. let songModel;
  233. SongsModule.log("ERROR", "HOW DOES THIS WORK!?!?!??!?!?!?!??!?!??!?!?!?!");
  234. DBModule.runJob("GET_MODEL", { modelName: "song" })
  235. .then(model => {
  236. songModel = model;
  237. })
  238. .catch(console.error);
  239. return async.waterfall(
  240. [
  241. next => {
  242. songModel.deleteOne({ songId: payload.songId }, next);
  243. },
  244. next => {
  245. CacheModule.runJob(
  246. "HDEL",
  247. {
  248. table: "songs",
  249. key: payload.songId
  250. },
  251. this
  252. )
  253. .then(() => next())
  254. .catch(next);
  255. }
  256. ],
  257. err => {
  258. if (err && err !== true) return reject(new Error(err));
  259. return resolve();
  260. }
  261. );
  262. });
  263. }
  264. }
  265. export default new _SongsModule();