entity-helper.ts 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. import { DB } from '../../generated/indexer'
  2. import { Channel } from '../../generated/graphql-server/src/modules/channel/channel.model'
  3. import { Category } from '../../generated/graphql-server/src/modules/category/category.model'
  4. import { KnownLicense } from '../../generated/graphql-server/src/modules/known-license/known-license.model'
  5. import { UserDefinedLicense } from '../../generated/graphql-server/src/modules/user-defined-license/user-defined-license.model'
  6. import { JoystreamMediaLocation } from '../../generated/graphql-server/src/modules/joystream-media-location/joystream-media-location.model'
  7. import { HttpMediaLocation } from '../../generated/graphql-server/src/modules/http-media-location/http-media-location.model'
  8. import { VideoMedia } from '../../generated/graphql-server/src/modules/video-media/video-media.model'
  9. import { Video } from '../../generated/graphql-server/src/modules/video/video.model'
  10. import { Block, Network } from '../../generated/graphql-server/src/modules/block/block.model'
  11. import { Language } from '../../generated/graphql-server/src/modules/language/language.model'
  12. import { VideoMediaEncoding } from '../../generated/graphql-server/src/modules/video-media-encoding/video-media-encoding.model'
  13. import { ClassEntity } from '../../generated/graphql-server/src/modules/class-entity/class-entity.model'
  14. import { License } from '../../generated/graphql-server/src/modules/license/license.model'
  15. import { MediaLocation } from '../../generated/graphql-server/src/modules/media-location/media-location.model'
  16. import { contentDirectoryClassNamesWithId } from './content-dir-consts'
  17. import {
  18. ClassEntityMap,
  19. ICategory,
  20. IChannel,
  21. ICreateEntityOperation,
  22. IDBBlockId,
  23. IEntity,
  24. IHttpMediaLocation,
  25. IJoystreamMediaLocation,
  26. IKnownLicense,
  27. ILanguage,
  28. ILicense,
  29. IMediaLocation,
  30. IUserDefinedLicense,
  31. IVideo,
  32. IVideoMedia,
  33. IVideoMediaEncoding,
  34. IWhereCond,
  35. } from '../types'
  36. import { getOrCreate } from './get-or-create'
  37. import BN from 'bn.js'
  38. async function createBlockOrGetFromDatabase(db: DB, blockNumber: number): Promise<Block> {
  39. let b = await db.get(Block, { where: { block: blockNumber } })
  40. if (b === undefined) {
  41. // TODO: get timestamp from the event or extrinsic
  42. b = new Block({ block: blockNumber, network: Network.BABYLON, timestamp: new BN(Date.now()) })
  43. await db.save<Block>(b)
  44. }
  45. return b
  46. }
  47. async function createChannel(
  48. { db, block, id }: IDBBlockId,
  49. classEntityMap: ClassEntityMap,
  50. p: IChannel
  51. ): Promise<Channel> {
  52. const record = await db.get(Channel, { where: { id } })
  53. if (record) return record
  54. const channel = new Channel()
  55. channel.version = block
  56. channel.id = id
  57. channel.title = p.title
  58. channel.description = p.description
  59. channel.isCurated = p.isCurated || false
  60. channel.isPublic = p.isPublic
  61. channel.coverPhotoUrl = p.coverPhotoURL
  62. channel.avatarPhotoUrl = p.avatarPhotoURL
  63. const { language } = p
  64. if (language !== undefined) {
  65. if (language.existing) {
  66. const r = await db.get(Language, { where: { id: language.entityId.toString() } })
  67. if (!r) throw Error(`Language entity not found`)
  68. channel.language = r
  69. } else {
  70. // Language entity id is based on the index so we increase the entityid to make it correct
  71. channel.language = await getOrCreate.language({ db, block, id }, classEntityMap, language.entityId)
  72. }
  73. }
  74. channel.happenedIn = await createBlockOrGetFromDatabase(db, block)
  75. await db.save(channel)
  76. return channel
  77. }
  78. async function createCategory({ db, block, id }: IDBBlockId, p: ICategory): Promise<Category> {
  79. const record = await db.get(Category, { where: { id } })
  80. if (record) return record
  81. const category = new Category()
  82. category.id = id
  83. category.name = p.name
  84. category.description = p.description
  85. category.version = block
  86. category.happenedIn = await createBlockOrGetFromDatabase(db, block)
  87. await db.save(category)
  88. return category
  89. }
  90. async function createKnownLicense({ db, block, id }: IDBBlockId, p: IKnownLicense): Promise<KnownLicense> {
  91. const record = await db.get(KnownLicense, { where: { id } })
  92. if (record) return record
  93. const knownLicence = new KnownLicense()
  94. knownLicence.id = id
  95. knownLicence.code = p.code
  96. knownLicence.name = p.name
  97. knownLicence.description = p.description
  98. knownLicence.url = p.url
  99. knownLicence.version = block
  100. knownLicence.happenedIn = await createBlockOrGetFromDatabase(db, block)
  101. await db.save(knownLicence)
  102. return knownLicence
  103. }
  104. async function createUserDefinedLicense(
  105. { db, block, id }: IDBBlockId,
  106. p: IUserDefinedLicense
  107. ): Promise<UserDefinedLicense> {
  108. const record = await db.get(UserDefinedLicense, { where: { id } })
  109. if (record) return record
  110. const userDefinedLicense = new UserDefinedLicense()
  111. userDefinedLicense.id = id
  112. userDefinedLicense.content = p.content
  113. userDefinedLicense.version = block
  114. userDefinedLicense.happenedIn = await createBlockOrGetFromDatabase(db, block)
  115. await db.save<UserDefinedLicense>(userDefinedLicense)
  116. return userDefinedLicense
  117. }
  118. async function createJoystreamMediaLocation(
  119. { db, block, id }: IDBBlockId,
  120. p: IJoystreamMediaLocation
  121. ): Promise<JoystreamMediaLocation> {
  122. const record = await db.get(JoystreamMediaLocation, { where: { id } })
  123. if (record) return record
  124. const joyMediaLoc = new JoystreamMediaLocation()
  125. joyMediaLoc.id = id
  126. joyMediaLoc.dataObjectId = p.dataObjectId
  127. joyMediaLoc.version = block
  128. joyMediaLoc.happenedIn = await createBlockOrGetFromDatabase(db, block)
  129. await db.save(joyMediaLoc)
  130. return joyMediaLoc
  131. }
  132. async function createHttpMediaLocation(
  133. { db, block, id }: IDBBlockId,
  134. p: IHttpMediaLocation
  135. ): Promise<HttpMediaLocation> {
  136. const record = await db.get(HttpMediaLocation, { where: { id } })
  137. if (record) return record
  138. const httpMediaLoc = new HttpMediaLocation()
  139. httpMediaLoc.id = id
  140. httpMediaLoc.url = p.url
  141. httpMediaLoc.port = p.port
  142. httpMediaLoc.version = block
  143. httpMediaLoc.happenedIn = await createBlockOrGetFromDatabase(db, block)
  144. await db.save(httpMediaLoc)
  145. return httpMediaLoc
  146. }
  147. async function createVideoMedia(
  148. { db, block, id }: IDBBlockId,
  149. classEntityMap: ClassEntityMap,
  150. p: IVideoMedia
  151. ): Promise<VideoMedia> {
  152. const videoMedia = new VideoMedia()
  153. videoMedia.id = id
  154. videoMedia.pixelHeight = p.pixelHeight
  155. videoMedia.pixelWidth = p.pixelWidth
  156. videoMedia.size = p.size
  157. videoMedia.version = block
  158. const { encoding, location } = p
  159. if (encoding !== undefined) {
  160. if (encoding.existing) {
  161. const e = await db.get(VideoMediaEncoding, { where: { id: encoding.entityId.toString() } })
  162. if (!e) throw Error(`VideoMediaEncoding not found: ${encoding.entityId}`)
  163. videoMedia.encoding = e
  164. } else {
  165. videoMedia.encoding = await getOrCreate.videoMediaEncoding({ db, block, id }, classEntityMap, encoding.entityId)
  166. }
  167. }
  168. if (location !== undefined) {
  169. if (location.existing) {
  170. const l = await db.get(MediaLocation, { where: { id: location.entityId.toString() } })
  171. if (!l) throw Error(`MediaLocation not found: ${location.entityId}`)
  172. videoMedia.location = l
  173. } else {
  174. videoMedia.location = await getOrCreate.mediaLocation({ db, block, id }, classEntityMap, location.entityId)
  175. }
  176. }
  177. videoMedia.happenedIn = await createBlockOrGetFromDatabase(db, block)
  178. await db.save(videoMedia)
  179. return videoMedia
  180. }
  181. async function createVideo({ db, block, id }: IDBBlockId, classEntityMap: ClassEntityMap, p: IVideo): Promise<Video> {
  182. const record = await db.get(Video, { where: { id } })
  183. if (record) return record
  184. const video = new Video()
  185. video.id = id
  186. video.title = p.title
  187. video.description = p.description
  188. video.duration = p.duration
  189. video.hasMarketing = p.hasMarketing
  190. // TODO: needs to be handled correctly, from runtime CurationStatus is coming
  191. video.isCurated = p.isCurated || true
  192. video.isExplicit = p.isExplicit
  193. video.isPublic = p.isPublic
  194. video.publishedBeforeJoystream = p.publishedBeforeJoystream
  195. video.skippableIntroDuration = p.skippableIntroDuration
  196. video.thumbnailUrl = p.thumbnailURL
  197. video.version = block
  198. const { language, license, category, channel, media } = p
  199. if (language !== undefined) {
  200. if (language.existing) {
  201. const l = await db.get(Language, { where: { id: language.entityId.toString() } })
  202. if (!l) throw Error(`Language entity not found`)
  203. video.language = l
  204. } else {
  205. video.language = await getOrCreate.language({ db, block, id }, classEntityMap, language.entityId)
  206. }
  207. }
  208. if (license !== undefined) {
  209. if (license.existing) {
  210. const lic = await db.get(License, { where: { id: license.entityId.toString() } })
  211. if (!lic) throw Error(`License entity not found`)
  212. video.license = lic
  213. } else {
  214. video.license = await getOrCreate.license({ db, block, id }, classEntityMap, license.entityId)
  215. }
  216. }
  217. if (category !== undefined) {
  218. if (category.existing) {
  219. const ca = await db.get(Category, { where: { id: category.entityId.toString() } })
  220. if (!ca) throw Error(`Category not found`)
  221. video.category = ca
  222. } else {
  223. video.category = await getOrCreate.category({ db, block, id }, classEntityMap, category.entityId)
  224. }
  225. }
  226. if (channel !== undefined) {
  227. if (channel.existing) {
  228. const c = await db.get(Channel, { where: { id: channel.entityId.toString() } })
  229. if (!c) throw Error(`Channel not found: ${channel.entityId}`)
  230. video.channel = c
  231. } else {
  232. video.channel = await getOrCreate.channel({ db, block, id }, classEntityMap, channel.entityId)
  233. }
  234. }
  235. if (media !== undefined) {
  236. if (media.existing) {
  237. const m = await db.get(VideoMedia, { where: { id: media.entityId.toString() } })
  238. if (!m) throw Error(`VideoMedia not found: ${media.entityId}`)
  239. video.media = m
  240. } else {
  241. video.media = await getOrCreate.videoMedia({ db, block, id }, classEntityMap, media.entityId)
  242. }
  243. }
  244. video.happenedIn = await createBlockOrGetFromDatabase(db, block)
  245. await db.save<Video>(video)
  246. return video
  247. }
  248. async function createLanguage({ db, block, id }: IDBBlockId, p: ILanguage): Promise<Language> {
  249. const record = await db.get(Language, { where: { id } })
  250. if (record) return record
  251. const language = new Language()
  252. language.id = id
  253. language.name = p.name
  254. language.code = p.code
  255. language.version = block
  256. language.happenedIn = await createBlockOrGetFromDatabase(db, block)
  257. await db.save<Language>(language)
  258. return language
  259. }
  260. async function createVideoMediaEncoding(
  261. { db, block, id }: IDBBlockId,
  262. p: IVideoMediaEncoding
  263. ): Promise<VideoMediaEncoding> {
  264. const record = await db.get(VideoMediaEncoding, { where: { id } })
  265. if (record) return record
  266. const encoding = new VideoMediaEncoding()
  267. encoding.id = id
  268. encoding.name = p.name
  269. encoding.version = block
  270. encoding.happenedIn = await createBlockOrGetFromDatabase(db, block)
  271. await db.save<VideoMediaEncoding>(encoding)
  272. return encoding
  273. }
  274. async function createLicense(
  275. { db, block, id }: IDBBlockId,
  276. classEntityMap: ClassEntityMap,
  277. p: ILicense
  278. ): Promise<License> {
  279. const record = await db.get(License, { where: { id } })
  280. if (record) return record
  281. const { knownLicense, userDefinedLicense } = p
  282. const license = new License()
  283. license.id = id
  284. if (knownLicense !== undefined) {
  285. if (knownLicense.existing) {
  286. const kl = await db.get(KnownLicense, { where: { id: knownLicense.entityId.toString() } })
  287. if (!kl) throw Error(`KnownLicense not found: ${knownLicense.entityId}`)
  288. license.knownLicense = kl
  289. } else {
  290. license.knownLicense = await getOrCreate.knownLicense({ db, block, id }, classEntityMap, knownLicense.entityId)
  291. }
  292. }
  293. if (userDefinedLicense !== undefined) {
  294. if (userDefinedLicense.existing) {
  295. const udl = await db.get(UserDefinedLicense, { where: { id: userDefinedLicense.entityId.toString() } })
  296. if (!udl) throw Error(`UserDefinedLicense not found: ${userDefinedLicense.entityId}`)
  297. license.userdefinedLicense = udl
  298. } else {
  299. license.userdefinedLicense = await getOrCreate.userDefinedLicense(
  300. { db, block, id },
  301. classEntityMap,
  302. userDefinedLicense.entityId
  303. )
  304. }
  305. }
  306. license.happenedIn = await createBlockOrGetFromDatabase(db, block)
  307. await db.save<License>(license)
  308. return license
  309. }
  310. async function createMediaLocation(
  311. { db, block, id }: IDBBlockId,
  312. classEntityMap: ClassEntityMap,
  313. p: IMediaLocation
  314. ): Promise<MediaLocation> {
  315. const { httpMediaLocation, joystreamMediaLocation } = p
  316. const location = new MediaLocation()
  317. location.id = id
  318. console.log(p)
  319. if (httpMediaLocation !== undefined) {
  320. const { existing, entityId } = httpMediaLocation
  321. if (existing) {
  322. const hml = await db.get(HttpMediaLocation, { where: { id: entityId.toString() } })
  323. if (!hml) throw Error(`HttpMediaLocation not found: ${entityId}`)
  324. } else {
  325. location.httpMediaLocation = await getOrCreate.httpMediaLocation({ db, block, id }, classEntityMap, entityId)
  326. }
  327. }
  328. if (joystreamMediaLocation !== undefined) {
  329. const { entityId, existing } = joystreamMediaLocation
  330. if (existing) {
  331. const jml = await db.get(JoystreamMediaLocation, { where: { id: entityId.toString() } })
  332. if (!jml) throw Error(`JoystreamMediaLocation not found: ${entityId}`)
  333. location.joystreamMediaLocation = jml
  334. } else {
  335. location.joystreamMediaLocation = await getOrCreate.joystreamMediaLocation(
  336. { db, block, id },
  337. classEntityMap,
  338. entityId
  339. )
  340. }
  341. }
  342. location.happenedIn = await createBlockOrGetFromDatabase(db, block)
  343. await db.save<License>(location)
  344. return location
  345. }
  346. async function batchCreateClassEntities(db: DB, block: number, operations: ICreateEntityOperation[]): Promise<void> {
  347. let entityId = 1 // Entity id starts at 1
  348. // Create entities before adding schema support
  349. operations.map(async ({ classId }) => {
  350. const c = new ClassEntity()
  351. c.id = entityId.toString()
  352. c.classId = classId
  353. c.version = block
  354. c.happenedIn = await createBlockOrGetFromDatabase(db, block)
  355. await db.save<ClassEntity>(c)
  356. entityId++
  357. })
  358. }
  359. async function getClassName(
  360. db: DB,
  361. entity: IEntity,
  362. createEntityOperations: ICreateEntityOperation[]
  363. ): Promise<string | undefined> {
  364. const { entityId, indexOf } = entity
  365. if (entityId === undefined && indexOf === undefined) {
  366. throw Error(`Can not determine class of the entity`)
  367. }
  368. let classId: number | undefined
  369. // Is newly created entity in the same transaction
  370. if (indexOf !== undefined) {
  371. classId = createEntityOperations[indexOf].classId
  372. } else {
  373. const ce = await db.get(ClassEntity, { where: { id: entityId } })
  374. if (ce === undefined) console.log(`Class not found for the entity: ${entityId}`)
  375. classId = ce ? ce.classId : undefined
  376. }
  377. const c = contentDirectoryClassNamesWithId.find((c) => c.classId === classId)
  378. // TODO: stop execution, class should be created before entity creation
  379. if (c === undefined) console.log(`Not recognized class id: ${classId}`)
  380. return c ? c.name : undefined
  381. }
  382. async function removeChannel(db: DB, where: IWhereCond): Promise<void> {
  383. const record = await db.get(Channel, where)
  384. if (record === undefined) throw Error(`Channel not found`)
  385. if (record.videos) record.videos.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
  386. await db.remove<Channel>(record)
  387. }
  388. async function removeCategory(db: DB, where: IWhereCond): Promise<void> {
  389. const record = await db.get(Category, where)
  390. if (record === undefined) throw Error(`Category not found`)
  391. if (record.videos) record.videos.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
  392. await db.remove<Category>(record)
  393. }
  394. async function removeVideoMedia(db: DB, where: IWhereCond): Promise<void> {
  395. const record = await db.get(VideoMedia, where)
  396. if (record === undefined) throw Error(`VideoMedia not found`)
  397. if (record.video) await db.remove<Video>(record.video)
  398. await db.remove<VideoMedia>(record)
  399. }
  400. async function removeVideo(db: DB, where: IWhereCond): Promise<void> {
  401. const record = await db.get(Video, where)
  402. if (record === undefined) throw Error(`Video not found`)
  403. await db.remove<Video>(record)
  404. }
  405. async function removeLicense(db: DB, where: IWhereCond): Promise<void> {
  406. const record = await db.get(License, where)
  407. if (record === undefined) throw Error(`License not found`)
  408. // Remove all the videos under this license
  409. if (record.videolicense) record.videolicense.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
  410. await db.remove<License>(record)
  411. }
  412. async function removeUserDefinedLicense(db: DB, where: IWhereCond): Promise<void> {
  413. const record = await db.get(UserDefinedLicense, where)
  414. if (record === undefined) throw Error(`UserDefinedLicense not found`)
  415. if (record.licenseuserdefinedLicense)
  416. record.licenseuserdefinedLicense.map(async (l) => await removeLicense(db, { where: { id: l.id } }))
  417. await db.remove<UserDefinedLicense>(record)
  418. }
  419. async function removeKnownLicense(db: DB, where: IWhereCond): Promise<void> {
  420. const record = await db.get(KnownLicense, where)
  421. if (record === undefined) throw Error(`KnownLicense not found`)
  422. if (record.licenseknownLicense)
  423. record.licenseknownLicense.map(async (k) => await removeLicense(db, { where: { id: k.id } }))
  424. await db.remove<KnownLicense>(record)
  425. }
  426. async function removeMediaLocation(db: DB, where: IWhereCond): Promise<void> {
  427. const record = await db.get(MediaLocation, where)
  428. if (record === undefined) throw Error(`MediaLocation not found`)
  429. if (record.videoMedia) await removeVideo(db, { where: { id: record.videoMedia.id } })
  430. await db.remove<MediaLocation>(record)
  431. }
  432. async function removeHttpMediaLocation(db: DB, where: IWhereCond): Promise<void> {
  433. const record = await db.get(HttpMediaLocation, where)
  434. if (record === undefined) throw Error(`HttpMediaLocation not found`)
  435. if (record.medialocationhttpMediaLocation)
  436. record.medialocationhttpMediaLocation.map(async (v) => await removeMediaLocation(db, { where: { id: v.id } }))
  437. await db.remove<HttpMediaLocation>(record)
  438. }
  439. async function removeJoystreamMediaLocation(db: DB, where: IWhereCond): Promise<void> {
  440. const record = await db.get(JoystreamMediaLocation, where)
  441. if (record === undefined) throw Error(`JoystreamMediaLocation not found`)
  442. if (record.medialocationjoystreamMediaLocation)
  443. record.medialocationjoystreamMediaLocation.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
  444. await db.remove<JoystreamMediaLocation>(record)
  445. }
  446. async function removeLanguage(db: DB, where: IWhereCond): Promise<void> {
  447. const record = await db.get(Language, where)
  448. if (record === undefined) throw Error(`Language not found`)
  449. if (record.channellanguage) record.channellanguage.map(async (c) => await removeChannel(db, { where: { id: c.id } }))
  450. if (record.videolanguage) record.videolanguage.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
  451. await db.remove<Language>(record)
  452. }
  453. async function removeVideoMediaEncoding(db: DB, where: IWhereCond): Promise<void> {
  454. const record = await db.get(VideoMediaEncoding, where)
  455. if (record === undefined) throw Error(`Language not found`)
  456. await db.remove<VideoMediaEncoding>(record)
  457. }
  458. // ========Entity property value updates========
  459. async function updateMediaLocationEntityPropertyValues(
  460. db: DB,
  461. where: IWhereCond,
  462. props: IMediaLocation
  463. ): Promise<void> {
  464. const { httpMediaLocation, joystreamMediaLocation } = props
  465. const record = await db.get(MediaLocation, where)
  466. if (record === undefined) throw Error(`MediaLocation entity not found: ${where.where.id}`)
  467. if (httpMediaLocation) {
  468. record.httpMediaLocation = await db.get(HttpMediaLocation, { where: { id: httpMediaLocation.toString() } })
  469. }
  470. if (joystreamMediaLocation) {
  471. record.joystreamMediaLocation = await db.get(JoystreamMediaLocation, {
  472. where: { id: joystreamMediaLocation.toString() },
  473. })
  474. }
  475. await db.save<MediaLocation>(record)
  476. }
  477. async function updateLicenseEntityPropertyValues(db: DB, where: IWhereCond, props: ILicense): Promise<void> {
  478. const { knownLicense, userDefinedLicense } = props
  479. const record = await db.get(License, where)
  480. if (record === undefined) throw Error(`License entity not found: ${where.where.id}`)
  481. if (knownLicense) {
  482. record.knownLicense = await db.get(KnownLicense, { where: { id: knownLicense.toString() } })
  483. }
  484. if (userDefinedLicense) {
  485. record.userdefinedLicense = await db.get(UserDefinedLicense, {
  486. where: { id: userDefinedLicense.toString() },
  487. })
  488. }
  489. await db.save<License>(record)
  490. }
  491. async function updateCategoryEntityPropertyValues(db: DB, where: IWhereCond, props: ICategory): Promise<void> {
  492. const record = await db.get(Category, where)
  493. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  494. Object.assign(record, props)
  495. await db.save<Category>(record)
  496. }
  497. async function updateChannelEntityPropertyValues(db: DB, where: IWhereCond, props: IChannel): Promise<void> {
  498. const record = await db.get(Channel, where)
  499. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  500. if (props.language) {
  501. const l = await db.get(Language, { where: { id: props.language.toString() } })
  502. if (l === undefined) throw Error(`Language entity not found: ${props.language}`)
  503. record.language = l
  504. props.language = undefined
  505. }
  506. Object.assign(record, props)
  507. await db.save<Channel>(record)
  508. }
  509. async function updateVideoMediaEntityPropertyValues(db: DB, where: IWhereCond, props: IVideoMedia): Promise<void> {
  510. const record = await db.get(VideoMedia, where)
  511. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  512. const { encoding, location } = props
  513. if (encoding) {
  514. const e = await db.get(VideoMediaEncoding, { where: { id: encoding.toString() } })
  515. if (e === undefined) throw Error(`VideoMediaEncoding entity not found: ${encoding}`)
  516. record.encoding = e
  517. props.encoding = undefined
  518. }
  519. if (location) {
  520. const mediaLoc = await db.get(MediaLocation, { where: { id: location.toString() } })
  521. if (!mediaLoc) throw Error(`MediaLocation entity not found: ${location}`)
  522. record.location = mediaLoc
  523. props.location = undefined
  524. }
  525. Object.assign(record, props)
  526. await db.save<VideoMedia>(record)
  527. }
  528. async function updateVideoEntityPropertyValues(db: DB, where: IWhereCond, props: IVideo): Promise<void> {
  529. const record = await db.get<Video>(Video, where)
  530. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  531. const { channel, category, language, media, license } = props
  532. if (channel) {
  533. const c = await db.get(Channel, { where: { id: channel.toString() } })
  534. if (c === undefined) throw Error(`Channel entity not found: ${channel}`)
  535. record.channel = c
  536. props.channel = undefined
  537. }
  538. if (category) {
  539. const c = await db.get(Category, { where: { id: category.toString() } })
  540. if (c === undefined) throw Error(`Category entity not found: ${category}`)
  541. record.category = c
  542. props.category = undefined
  543. }
  544. if (media) {
  545. const m = await db.get(VideoMedia, { where: { id: media.toString() } })
  546. if (m === undefined) throw Error(`VideoMedia entity not found: ${channel}`)
  547. record.media = m
  548. props.media = undefined
  549. }
  550. if (license) {
  551. const l = await db.get(License, { where: { id: license.toString() } })
  552. if (!l) throw Error(`License entity not found: ${license}`)
  553. record.license = l
  554. props.license = undefined
  555. }
  556. if (language) {
  557. const l = await db.get(Language, { where: { id: language.toString() } })
  558. if (l === undefined) throw Error(`Language entity not found: ${language}`)
  559. record.language = l
  560. props.language = undefined
  561. }
  562. Object.assign(record, props)
  563. await db.save<Video>(record)
  564. }
  565. async function updateUserDefinedLicenseEntityPropertyValues(
  566. db: DB,
  567. where: IWhereCond,
  568. props: IUserDefinedLicense
  569. ): Promise<void> {
  570. const record = await db.get(UserDefinedLicense, where)
  571. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  572. Object.assign(record, props)
  573. await db.save<UserDefinedLicense>(record)
  574. }
  575. async function updateKnownLicenseEntityPropertyValues(db: DB, where: IWhereCond, props: IKnownLicense): Promise<void> {
  576. const record = await db.get(KnownLicense, where)
  577. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  578. Object.assign(record, props)
  579. await db.save<KnownLicense>(record)
  580. }
  581. async function updateHttpMediaLocationEntityPropertyValues(
  582. db: DB,
  583. where: IWhereCond,
  584. props: IHttpMediaLocation
  585. ): Promise<void> {
  586. const record = await db.get(HttpMediaLocation, where)
  587. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  588. Object.assign(record, props)
  589. await db.save<HttpMediaLocation>(record)
  590. }
  591. async function updateJoystreamMediaLocationEntityPropertyValues(
  592. db: DB,
  593. where: IWhereCond,
  594. props: IJoystreamMediaLocation
  595. ): Promise<void> {
  596. const record = await db.get(JoystreamMediaLocation, where)
  597. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  598. Object.assign(record, props)
  599. await db.save<JoystreamMediaLocation>(record)
  600. }
  601. async function updateLanguageEntityPropertyValues(db: DB, where: IWhereCond, props: ILanguage): Promise<void> {
  602. const record = await db.get(Language, where)
  603. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  604. Object.assign(record, props)
  605. await db.save<Language>(record)
  606. }
  607. async function updateVideoMediaEncodingEntityPropertyValues(
  608. db: DB,
  609. where: IWhereCond,
  610. props: IVideoMediaEncoding
  611. ): Promise<void> {
  612. const record = await db.get(VideoMediaEncoding, where)
  613. if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
  614. Object.assign(record, props)
  615. await db.save<VideoMediaEncoding>(record)
  616. }
  617. export {
  618. createCategory,
  619. createChannel,
  620. createVideoMedia,
  621. createVideo,
  622. createUserDefinedLicense,
  623. createKnownLicense,
  624. createHttpMediaLocation,
  625. createJoystreamMediaLocation,
  626. createLanguage,
  627. createVideoMediaEncoding,
  628. createLicense,
  629. createMediaLocation,
  630. removeCategory,
  631. removeChannel,
  632. removeVideoMedia,
  633. removeVideo,
  634. removeUserDefinedLicense,
  635. removeKnownLicense,
  636. removeHttpMediaLocation,
  637. removeJoystreamMediaLocation,
  638. removeLanguage,
  639. removeVideoMediaEncoding,
  640. removeMediaLocation,
  641. removeLicense,
  642. createBlockOrGetFromDatabase,
  643. batchCreateClassEntities,
  644. getClassName,
  645. updateCategoryEntityPropertyValues,
  646. updateChannelEntityPropertyValues,
  647. updateVideoMediaEntityPropertyValues,
  648. updateVideoEntityPropertyValues,
  649. updateUserDefinedLicenseEntityPropertyValues,
  650. updateHttpMediaLocationEntityPropertyValues,
  651. updateJoystreamMediaLocationEntityPropertyValues,
  652. updateKnownLicenseEntityPropertyValues,
  653. updateLanguageEntityPropertyValues,
  654. updateVideoMediaEncodingEntityPropertyValues,
  655. updateLicenseEntityPropertyValues,
  656. updateMediaLocationEntityPropertyValues,
  657. }