entity.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. createCategory,
  7. createChannel,
  8. createVideoMedia,
  9. createVideo,
  10. createUserDefinedLicense,
  11. createKnownLicense,
  12. createHttpMediaLocation,
  13. createJoystreamMediaLocation,
  14. removeCategory,
  15. removeChannel,
  16. removeVideoMedia,
  17. removeVideo,
  18. removeUserDefinedLicense,
  19. removeKnownLicense,
  20. removeHttpMediaLocation,
  21. removeJoystreamMediaLocation,
  22. removeLanguage,
  23. removeVideoMediaEncoding,
  24. createLanguage,
  25. createVideoMediaEncoding,
  26. updateCategoryEntityPropertyValues,
  27. updateChannelEntityPropertyValues,
  28. updateVideoMediaEntityPropertyValues,
  29. updateVideoEntityPropertyValues,
  30. updateUserDefinedLicenseEntityPropertyValues,
  31. updateHttpMediaLocationEntityPropertyValues,
  32. updateJoystreamMediaLocationEntityPropertyValues,
  33. updateKnownLicenseEntityPropertyValues,
  34. updateLanguageEntityPropertyValues,
  35. updateVideoMediaEncodingEntityPropertyValues,
  36. createBlockOrGetFromDatabase,
  37. } from './entity-helper'
  38. import {
  39. CategoryPropertyNamesWithId,
  40. channelPropertyNamesWithId,
  41. httpMediaLocationPropertyNamesWithId,
  42. joystreamMediaLocationPropertyNamesWithId,
  43. knownLicensePropertyNamesWIthId,
  44. languagePropertyNamesWIthId,
  45. userDefinedLicensePropertyNamesWithId,
  46. videoMediaEncodingPropertyNamesWithId,
  47. videoPropertyNamesWithId,
  48. contentDirectoryClassNamesWithId,
  49. ContentDirectoryKnownClasses,
  50. } from './content-dir-consts'
  51. import {
  52. IChannel,
  53. ICategory,
  54. IKnownLicense,
  55. IUserDefinedLicense,
  56. IJoystreamMediaLocation,
  57. IHttpMediaLocation,
  58. IVideoMedia,
  59. IVideo,
  60. ILanguage,
  61. IVideoMediaEncoding,
  62. IDBBlockId,
  63. IWhereCond,
  64. } from '../types'
  65. const debug = Debug('mappings:content-directory')
  66. // eslint-disable-next-line @typescript-eslint/naming-convention
  67. async function contentDirectory_EntitySchemaSupportAdded(db: DB, event: SubstrateEvent): Promise<void> {
  68. if (event.extrinsic && event.extrinsic.method === 'transaction') return
  69. debug(`EntitySchemaSupportAdded event: ${JSON.stringify(event)}`)
  70. const { blockNumber: block } = event
  71. const entityId = decode.stringIfyEntityId(event)
  72. const classEntity = await db.get(ClassEntity, { where: { id: entityId } })
  73. if (classEntity === undefined) {
  74. console.log(`Class not found for the EntityId: ${entityId}`)
  75. return
  76. }
  77. const cls = contentDirectoryClassNamesWithId.find((c) => c.classId === classEntity.classId)
  78. if (cls === undefined) {
  79. console.log('Not recognized class')
  80. return
  81. }
  82. const arg: IDBBlockId = { db, block, id: entityId }
  83. switch (cls.name) {
  84. case ContentDirectoryKnownClasses.CHANNEL:
  85. await createChannel(arg, decode.setProperties<IChannel>(event, channelPropertyNamesWithId))
  86. break
  87. case ContentDirectoryKnownClasses.CATEGORY:
  88. await createCategory(arg, decode.setProperties<ICategory>(event, CategoryPropertyNamesWithId))
  89. break
  90. case ContentDirectoryKnownClasses.KNOWNLICENSE:
  91. await createKnownLicense(arg, decode.setProperties<IKnownLicense>(event, knownLicensePropertyNamesWIthId))
  92. break
  93. case ContentDirectoryKnownClasses.USERDEFINEDLICENSE:
  94. await createUserDefinedLicense(
  95. arg,
  96. decode.setProperties<IUserDefinedLicense>(event, userDefinedLicensePropertyNamesWithId)
  97. )
  98. break
  99. case ContentDirectoryKnownClasses.JOYSTREAMMEDIALOCATION:
  100. await createJoystreamMediaLocation(
  101. arg,
  102. decode.setProperties<IJoystreamMediaLocation>(event, joystreamMediaLocationPropertyNamesWithId)
  103. )
  104. break
  105. case ContentDirectoryKnownClasses.HTTPMEDIALOCATION:
  106. await createHttpMediaLocation(
  107. arg,
  108. decode.setProperties<IHttpMediaLocation>(event, httpMediaLocationPropertyNamesWithId)
  109. )
  110. break
  111. case ContentDirectoryKnownClasses.VIDEOMEDIA:
  112. await createVideoMedia(arg, decode.setProperties<IVideoMedia>(event, videoPropertyNamesWithId))
  113. break
  114. case ContentDirectoryKnownClasses.VIDEO:
  115. await createVideo(arg, decode.setProperties<IVideo>(event, videoPropertyNamesWithId))
  116. break
  117. case ContentDirectoryKnownClasses.LANGUAGE:
  118. await createLanguage(arg, decode.setProperties<ILanguage>(event, languagePropertyNamesWIthId))
  119. break
  120. case ContentDirectoryKnownClasses.VIDEOMEDIAENCODING:
  121. await createVideoMediaEncoding(
  122. arg,
  123. decode.setProperties<IVideoMediaEncoding>(event, videoMediaEncodingPropertyNamesWithId)
  124. )
  125. break
  126. default:
  127. throw new Error(`Unknown class name: ${cls.name}`)
  128. }
  129. }
  130. // eslint-disable-next-line @typescript-eslint/naming-convention
  131. async function contentDirectory_EntityRemoved(db: DB, event: SubstrateEvent): Promise<void> {
  132. debug(`EntityRemoved event: ${JSON.stringify(event)}`)
  133. const entityId = decode.stringIfyEntityId(event)
  134. const where: IWhereCond = { where: { id: entityId } }
  135. const classEntity = await db.get(ClassEntity, where)
  136. if (classEntity === undefined) {
  137. console.log(`Class not found for the EntityId: ${entityId}`)
  138. return
  139. }
  140. const cls = contentDirectoryClassNamesWithId.find((c) => c.classId === classEntity.classId)
  141. if (cls === undefined) {
  142. console.log('Undefined class')
  143. return
  144. }
  145. switch (cls.name) {
  146. case ContentDirectoryKnownClasses.CHANNEL:
  147. await removeChannel(db, where)
  148. break
  149. case ContentDirectoryKnownClasses.CATEGORY:
  150. await removeCategory(db, where)
  151. break
  152. case ContentDirectoryKnownClasses.KNOWNLICENSE:
  153. await removeKnownLicense(db, where)
  154. break
  155. case ContentDirectoryKnownClasses.USERDEFINEDLICENSE:
  156. await removeUserDefinedLicense(db, where)
  157. break
  158. case ContentDirectoryKnownClasses.JOYSTREAMMEDIALOCATION:
  159. await removeJoystreamMediaLocation(db, where)
  160. break
  161. case ContentDirectoryKnownClasses.HTTPMEDIALOCATION:
  162. await removeHttpMediaLocation(db, where)
  163. break
  164. case ContentDirectoryKnownClasses.VIDEOMEDIA:
  165. await removeVideoMedia(db, where)
  166. break
  167. case ContentDirectoryKnownClasses.VIDEO:
  168. await removeVideo(db, where)
  169. break
  170. case ContentDirectoryKnownClasses.LANGUAGE:
  171. await removeLanguage(db, where)
  172. break
  173. case ContentDirectoryKnownClasses.VIDEOMEDIAENCODING:
  174. await removeVideoMediaEncoding(db, where)
  175. break
  176. default:
  177. throw new Error(`Unknown class name: ${cls.name}`)
  178. }
  179. }
  180. // eslint-disable-next-line @typescript-eslint/naming-convention
  181. async function contentDirectory_EntityCreated(db: DB, event: SubstrateEvent): Promise<void> {
  182. if (event.extrinsic && event.extrinsic.method === 'transaction') return
  183. debug(`EntityCreated event: ${JSON.stringify(event)}`)
  184. const c = decode.getClassEntity(event)
  185. const classEntity = new ClassEntity()
  186. classEntity.classId = c.classId
  187. classEntity.id = c.entityId.toString()
  188. classEntity.version = event.blockNumber
  189. classEntity.happenedIn = await createBlockOrGetFromDatabase(db, event.blockNumber)
  190. await db.save<ClassEntity>(classEntity)
  191. }
  192. // eslint-disable-next-line @typescript-eslint/naming-convention
  193. async function contentDirectory_EntityPropertyValuesUpdated(db: DB, event: SubstrateEvent): Promise<void> {
  194. debug(`EntityPropertyValuesUpdated event: ${JSON.stringify(event)}`)
  195. const { extrinsic } = event
  196. if (extrinsic && extrinsic.method === 'transaction') return
  197. if (extrinsic === undefined) throw Error(`Extrinsic data not found for event: ${event.id}`)
  198. const { 2: newPropertyValues } = extrinsic.args
  199. const entityId = decode.stringIfyEntityId(event)
  200. const ce = await db.get(ClassEntity, { where: { id: entityId } })
  201. if (ce === undefined) throw Error(`Class not found for the entity id: ${entityId}`)
  202. const cls = contentDirectoryClassNamesWithId.find((c) => c.classId === ce.classId)
  203. if (cls === undefined) throw Error(`Not known class id: ${ce.classId}`)
  204. const where: IWhereCond = { where: { id: entityId } }
  205. // TODO: change setProperties method signature to accecpt SubstrateExtrinsic, then remove the following
  206. // line. The reason we push the same arg is beacuse of the setProperties method check the 3rd indices
  207. // to get properties values
  208. extrinsic.args.push(newPropertyValues)
  209. switch (cls.name) {
  210. case ContentDirectoryKnownClasses.CHANNEL:
  211. updateChannelEntityPropertyValues(db, where, decode.setProperties<IChannel>(event, channelPropertyNamesWithId))
  212. break
  213. case ContentDirectoryKnownClasses.CATEGORY:
  214. await updateCategoryEntityPropertyValues(
  215. db,
  216. where,
  217. decode.setProperties<ICategory>(event, CategoryPropertyNamesWithId)
  218. )
  219. break
  220. case ContentDirectoryKnownClasses.KNOWNLICENSE:
  221. await updateKnownLicenseEntityPropertyValues(
  222. db,
  223. where,
  224. decode.setProperties<IKnownLicense>(event, knownLicensePropertyNamesWIthId)
  225. )
  226. break
  227. case ContentDirectoryKnownClasses.USERDEFINEDLICENSE:
  228. await updateUserDefinedLicenseEntityPropertyValues(
  229. db,
  230. where,
  231. decode.setProperties<IUserDefinedLicense>(event, userDefinedLicensePropertyNamesWithId)
  232. )
  233. break
  234. case ContentDirectoryKnownClasses.JOYSTREAMMEDIALOCATION:
  235. await updateJoystreamMediaLocationEntityPropertyValues(
  236. db,
  237. where,
  238. decode.setProperties<IJoystreamMediaLocation>(event, joystreamMediaLocationPropertyNamesWithId)
  239. )
  240. break
  241. case ContentDirectoryKnownClasses.HTTPMEDIALOCATION:
  242. await updateHttpMediaLocationEntityPropertyValues(
  243. db,
  244. where,
  245. decode.setProperties<IHttpMediaLocation>(event, httpMediaLocationPropertyNamesWithId)
  246. )
  247. break
  248. case ContentDirectoryKnownClasses.VIDEOMEDIA:
  249. await updateVideoMediaEntityPropertyValues(
  250. db,
  251. where,
  252. decode.setProperties<IVideoMedia>(event, videoPropertyNamesWithId)
  253. )
  254. break
  255. case ContentDirectoryKnownClasses.VIDEO:
  256. await updateVideoEntityPropertyValues(db, where, decode.setProperties<IVideo>(event, videoPropertyNamesWithId))
  257. break
  258. case ContentDirectoryKnownClasses.LANGUAGE:
  259. await updateLanguageEntityPropertyValues(
  260. db,
  261. where,
  262. decode.setProperties<ILanguage>(event, languagePropertyNamesWIthId)
  263. )
  264. break
  265. case ContentDirectoryKnownClasses.VIDEOMEDIAENCODING:
  266. await updateVideoMediaEncodingEntityPropertyValues(
  267. db,
  268. where,
  269. decode.setProperties<IVideoMediaEncoding>(event, videoMediaEncodingPropertyNamesWithId)
  270. )
  271. break
  272. default:
  273. throw new Error(`Unknown class name: ${cls.name}`)
  274. }
  275. }
  276. export {
  277. contentDirectory_EntityCreated,
  278. contentDirectory_EntityRemoved,
  279. contentDirectory_EntitySchemaSupportAdded,
  280. contentDirectory_EntityPropertyValuesUpdated,
  281. }