index.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. import Debug from 'debug'
  2. import { DB, SubstrateEvent } from '../../../generated/indexer'
  3. import { ClassEntity } from '../../../generated/graphql-server/src/modules/class-entity/class-entity.model'
  4. import { decode } from '../decode'
  5. import {
  6. updateCategoryEntityPropertyValues,
  7. updateChannelEntityPropertyValues,
  8. updateVideoMediaEntityPropertyValues,
  9. updateVideoEntityPropertyValues,
  10. updateUserDefinedLicenseEntityPropertyValues,
  11. updateHttpMediaLocationEntityPropertyValues,
  12. updateJoystreamMediaLocationEntityPropertyValues,
  13. updateKnownLicenseEntityPropertyValues,
  14. updateLanguageEntityPropertyValues,
  15. updateVideoMediaEncodingEntityPropertyValues,
  16. updateLicenseEntityPropertyValues,
  17. updateMediaLocationEntityPropertyValues,
  18. updateFeaturedVideoEntityPropertyValues,
  19. } from './update'
  20. import {
  21. removeCategory,
  22. removeChannel,
  23. removeVideoMedia,
  24. removeVideo,
  25. removeUserDefinedLicense,
  26. removeKnownLicense,
  27. removeHttpMediaLocation,
  28. removeJoystreamMediaLocation,
  29. removeLanguage,
  30. removeVideoMediaEncoding,
  31. removeLicense,
  32. removeMediaLocation,
  33. removeFeaturedVideo,
  34. } from './remove'
  35. import {
  36. createCategory,
  37. createChannel,
  38. createVideoMedia,
  39. createVideo,
  40. createUserDefinedLicense,
  41. createKnownLicense,
  42. createHttpMediaLocation,
  43. createJoystreamMediaLocation,
  44. createLanguage,
  45. createVideoMediaEncoding,
  46. createBlockOrGetFromDatabase,
  47. createFeaturedVideo,
  48. } from './create'
  49. import {
  50. categoryPropertyNamesWithId,
  51. channelPropertyNamesWithId,
  52. httpMediaLocationPropertyNamesWithId,
  53. joystreamMediaLocationPropertyNamesWithId,
  54. knownLicensePropertyNamesWIthId,
  55. languagePropertyNamesWIthId,
  56. userDefinedLicensePropertyNamesWithId,
  57. videoMediaEncodingPropertyNamesWithId,
  58. videoPropertyNamesWithId,
  59. ContentDirectoryKnownClasses,
  60. featuredVideoPropertyNamesWithId,
  61. } from '../content-dir-consts'
  62. import {
  63. IChannel,
  64. ICategory,
  65. IKnownLicense,
  66. IUserDefinedLicense,
  67. IJoystreamMediaLocation,
  68. IHttpMediaLocation,
  69. IVideoMedia,
  70. IVideo,
  71. ILanguage,
  72. IVideoMediaEncoding,
  73. IDBBlockId,
  74. IWhereCond,
  75. IEntity,
  76. ILicense,
  77. IMediaLocation,
  78. IFeaturedVideo,
  79. } from '../../types'
  80. import { getOrCreate, getKnownClass } from '../get-or-create'
  81. const debug = Debug('mappings:content-directory')
  82. // eslint-disable-next-line @typescript-eslint/naming-convention
  83. async function contentDirectory_EntitySchemaSupportAdded(db: DB, event: SubstrateEvent): Promise<void> {
  84. if (event.extrinsic && event.extrinsic.method === 'transaction') return
  85. debug(`EntitySchemaSupportAdded event: ${JSON.stringify(event)}`)
  86. const { blockNumber: block } = event
  87. const entityId = decode.stringIfyEntityId(event)
  88. const knownClass = await getKnownClass(db, { where: { id: entityId } })
  89. if (!knownClass) return
  90. const arg: IDBBlockId = { db, block, id: entityId }
  91. switch (knownClass.name) {
  92. case ContentDirectoryKnownClasses.CHANNEL:
  93. await createChannel(
  94. arg,
  95. new Map<string, IEntity[]>(),
  96. decode.setProperties<IChannel>(event, channelPropertyNamesWithId),
  97. 0 // ignored
  98. )
  99. break
  100. case ContentDirectoryKnownClasses.CATEGORY:
  101. await createCategory(arg, decode.setProperties<ICategory>(event, categoryPropertyNamesWithId))
  102. break
  103. case ContentDirectoryKnownClasses.KNOWNLICENSE:
  104. await createKnownLicense(arg, decode.setProperties<IKnownLicense>(event, knownLicensePropertyNamesWIthId))
  105. break
  106. case ContentDirectoryKnownClasses.USERDEFINEDLICENSE:
  107. await createUserDefinedLicense(
  108. arg,
  109. decode.setProperties<IUserDefinedLicense>(event, userDefinedLicensePropertyNamesWithId)
  110. )
  111. break
  112. case ContentDirectoryKnownClasses.JOYSTREAMMEDIALOCATION:
  113. await createJoystreamMediaLocation(
  114. arg,
  115. decode.setProperties<IJoystreamMediaLocation>(event, joystreamMediaLocationPropertyNamesWithId)
  116. )
  117. break
  118. case ContentDirectoryKnownClasses.HTTPMEDIALOCATION:
  119. await createHttpMediaLocation(
  120. arg,
  121. decode.setProperties<IHttpMediaLocation>(event, httpMediaLocationPropertyNamesWithId)
  122. )
  123. break
  124. case ContentDirectoryKnownClasses.VIDEOMEDIA:
  125. await createVideoMedia(
  126. arg,
  127. new Map<string, IEntity[]>(),
  128. decode.setProperties<IVideoMedia>(event, videoPropertyNamesWithId),
  129. 0 // ignored
  130. )
  131. break
  132. case ContentDirectoryKnownClasses.VIDEO:
  133. await createVideo(
  134. arg,
  135. new Map<string, IEntity[]>(),
  136. decode.setProperties<IVideo>(event, videoPropertyNamesWithId),
  137. 0 // ignored
  138. )
  139. break
  140. case ContentDirectoryKnownClasses.LANGUAGE:
  141. await createLanguage(arg, decode.setProperties<ILanguage>(event, languagePropertyNamesWIthId))
  142. break
  143. case ContentDirectoryKnownClasses.VIDEOMEDIAENCODING:
  144. await createVideoMediaEncoding(
  145. arg,
  146. decode.setProperties<IVideoMediaEncoding>(event, videoMediaEncodingPropertyNamesWithId)
  147. )
  148. break
  149. case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
  150. await createFeaturedVideo(
  151. arg,
  152. new Map<string, IEntity[]>(),
  153. decode.setProperties<IFeaturedVideo>(event, featuredVideoPropertyNamesWithId),
  154. 0
  155. )
  156. break
  157. default:
  158. throw new Error(`Unknown class name: ${knownClass.name}`)
  159. }
  160. }
  161. // eslint-disable-next-line @typescript-eslint/naming-convention
  162. async function contentDirectory_EntityRemoved(db: DB, event: SubstrateEvent): Promise<void> {
  163. debug(`EntityRemoved event: ${JSON.stringify(event)}`)
  164. const entityId = decode.stringIfyEntityId(event)
  165. const where: IWhereCond = { where: { id: entityId } }
  166. const knownClass = await getKnownClass(db, where)
  167. if (!knownClass) return
  168. switch (knownClass.name) {
  169. case ContentDirectoryKnownClasses.CHANNEL:
  170. await removeChannel(db, where)
  171. break
  172. case ContentDirectoryKnownClasses.CATEGORY:
  173. await removeCategory(db, where)
  174. break
  175. case ContentDirectoryKnownClasses.KNOWNLICENSE:
  176. await removeKnownLicense(db, where)
  177. break
  178. case ContentDirectoryKnownClasses.USERDEFINEDLICENSE:
  179. await removeUserDefinedLicense(db, where)
  180. break
  181. case ContentDirectoryKnownClasses.JOYSTREAMMEDIALOCATION:
  182. await removeJoystreamMediaLocation(db, where)
  183. break
  184. case ContentDirectoryKnownClasses.HTTPMEDIALOCATION:
  185. await removeHttpMediaLocation(db, where)
  186. break
  187. case ContentDirectoryKnownClasses.VIDEOMEDIA:
  188. await removeVideoMedia(db, where)
  189. break
  190. case ContentDirectoryKnownClasses.VIDEO:
  191. await removeVideo(db, where)
  192. break
  193. case ContentDirectoryKnownClasses.LANGUAGE:
  194. await removeLanguage(db, where)
  195. break
  196. case ContentDirectoryKnownClasses.VIDEOMEDIAENCODING:
  197. await removeVideoMediaEncoding(db, where)
  198. break
  199. case ContentDirectoryKnownClasses.LICENSE:
  200. await removeLicense(db, where)
  201. break
  202. case ContentDirectoryKnownClasses.MEDIALOCATION:
  203. await removeMediaLocation(db, where)
  204. break
  205. case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
  206. await removeFeaturedVideo(db, where)
  207. break
  208. default:
  209. throw new Error(`Unknown class name: ${knownClass.name}`)
  210. }
  211. const ce = await db.get(ClassEntity, where)
  212. if (ce) await db.remove<ClassEntity>(ce)
  213. }
  214. // eslint-disable-next-line @typescript-eslint/naming-convention
  215. async function contentDirectory_EntityCreated(db: DB, event: SubstrateEvent): Promise<void> {
  216. if (event.extrinsic && event.extrinsic.method === 'transaction') return
  217. debug(`EntityCreated event: ${JSON.stringify(event)}`)
  218. const c = decode.getClassEntity(event)
  219. const classEntity = new ClassEntity()
  220. classEntity.classId = c.classId
  221. classEntity.id = c.entityId.toString()
  222. classEntity.version = event.blockNumber
  223. classEntity.happenedIn = await createBlockOrGetFromDatabase(db, event.blockNumber)
  224. await db.save<ClassEntity>(classEntity)
  225. await getOrCreate.nextEntityId(db, c.entityId + 1)
  226. }
  227. // eslint-disable-next-line @typescript-eslint/naming-convention
  228. async function contentDirectory_EntityPropertyValuesUpdated(db: DB, event: SubstrateEvent): Promise<void> {
  229. const { extrinsic } = event
  230. if (extrinsic && extrinsic.method === 'transaction') return
  231. if (extrinsic === undefined) throw Error(`Extrinsic data not found for event: ${event.id}`)
  232. debug(`EntityPropertyValuesUpdated event: ${JSON.stringify(event)}`)
  233. const { 2: newPropertyValues } = extrinsic.args
  234. const entityId = decode.stringIfyEntityId(event)
  235. const where: IWhereCond = { where: { id: entityId } }
  236. const knownClass = await getKnownClass(db, where)
  237. if (!knownClass) return
  238. // TODO: change setProperties method signature to accecpt SubstrateExtrinsic, then remove the following
  239. // line. The reason we push the same arg is beacuse of the setProperties method check the 3rd indices
  240. // to get properties values
  241. extrinsic.args.push(newPropertyValues)
  242. switch (knownClass.name) {
  243. case ContentDirectoryKnownClasses.CHANNEL:
  244. updateChannelEntityPropertyValues(db, where, decode.setProperties<IChannel>(event, channelPropertyNamesWithId), 0)
  245. break
  246. case ContentDirectoryKnownClasses.CATEGORY:
  247. await updateCategoryEntityPropertyValues(
  248. db,
  249. where,
  250. decode.setProperties<ICategory>(event, categoryPropertyNamesWithId)
  251. )
  252. break
  253. case ContentDirectoryKnownClasses.KNOWNLICENSE:
  254. await updateKnownLicenseEntityPropertyValues(
  255. db,
  256. where,
  257. decode.setProperties<IKnownLicense>(event, knownLicensePropertyNamesWIthId)
  258. )
  259. break
  260. case ContentDirectoryKnownClasses.USERDEFINEDLICENSE:
  261. await updateUserDefinedLicenseEntityPropertyValues(
  262. db,
  263. where,
  264. decode.setProperties<IUserDefinedLicense>(event, userDefinedLicensePropertyNamesWithId)
  265. )
  266. break
  267. case ContentDirectoryKnownClasses.JOYSTREAMMEDIALOCATION:
  268. await updateJoystreamMediaLocationEntityPropertyValues(
  269. db,
  270. where,
  271. decode.setProperties<IJoystreamMediaLocation>(event, joystreamMediaLocationPropertyNamesWithId)
  272. )
  273. break
  274. case ContentDirectoryKnownClasses.HTTPMEDIALOCATION:
  275. await updateHttpMediaLocationEntityPropertyValues(
  276. db,
  277. where,
  278. decode.setProperties<IHttpMediaLocation>(event, httpMediaLocationPropertyNamesWithId)
  279. )
  280. break
  281. case ContentDirectoryKnownClasses.VIDEOMEDIA:
  282. await updateVideoMediaEntityPropertyValues(
  283. db,
  284. where,
  285. decode.setProperties<IVideoMedia>(event, videoPropertyNamesWithId),
  286. 0
  287. )
  288. break
  289. case ContentDirectoryKnownClasses.VIDEO:
  290. await updateVideoEntityPropertyValues(db, where, decode.setProperties<IVideo>(event, videoPropertyNamesWithId), 0)
  291. break
  292. case ContentDirectoryKnownClasses.LANGUAGE:
  293. await updateLanguageEntityPropertyValues(
  294. db,
  295. where,
  296. decode.setProperties<ILanguage>(event, languagePropertyNamesWIthId)
  297. )
  298. break
  299. case ContentDirectoryKnownClasses.VIDEOMEDIAENCODING:
  300. await updateVideoMediaEncodingEntityPropertyValues(
  301. db,
  302. where,
  303. decode.setProperties<IVideoMediaEncoding>(event, videoMediaEncodingPropertyNamesWithId)
  304. )
  305. break
  306. case ContentDirectoryKnownClasses.LICENSE:
  307. await updateLicenseEntityPropertyValues(
  308. db,
  309. where,
  310. decode.setProperties<ILicense>(event, videoMediaEncodingPropertyNamesWithId),
  311. 0
  312. )
  313. break
  314. case ContentDirectoryKnownClasses.MEDIALOCATION:
  315. await updateMediaLocationEntityPropertyValues(
  316. db,
  317. where,
  318. decode.setProperties<IMediaLocation>(event, videoMediaEncodingPropertyNamesWithId),
  319. 0
  320. )
  321. break
  322. case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
  323. await updateFeaturedVideoEntityPropertyValues(
  324. db,
  325. where,
  326. decode.setProperties<IFeaturedVideo>(event, featuredVideoPropertyNamesWithId),
  327. 0
  328. )
  329. break
  330. default:
  331. throw new Error(`Unknown class name: ${knownClass.name}`)
  332. }
  333. }
  334. export {
  335. contentDirectory_EntityCreated,
  336. contentDirectory_EntityRemoved,
  337. contentDirectory_EntitySchemaSupportAdded,
  338. contentDirectory_EntityPropertyValuesUpdated,
  339. }