Browse Source

query node - mappings implementation IV

ondratra 4 năm trước cách đây
mục cha
commit
4ce6c9bf9e

+ 1 - 1
query-node/mappings/src/common.ts

@@ -23,7 +23,7 @@ import {
 const currentNetwork = Network.BABYLON
 
 export function inconsistentState(extraInfo?: string): never {
-  throw 'Inconsistent state.' + extraInfo // TODO: create a proper way of handling inconsistent state
+  throw 'Inconsistent state: ' + extraInfo // TODO: create a proper way of handling inconsistent state
 }
 
 // prepare block record

+ 31 - 8
query-node/mappings/src/content/channel.ts

@@ -2,6 +2,8 @@ import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 import ISO6391 from 'iso-639-1';
 
+import { GenericAccountId } from '@polkadot/types/generic';
+import { Option } from '@polkadot/types/codec';
 import { Content } from '../../../generated/types'
 import { readProtobuf } from './utils'
 
@@ -75,13 +77,8 @@ export async function content_ChannelUpdated(
 
   // reward account change happened?
   if (channelUpdateParameters.reward_account.isSome) {
-    // TODO: separate to function
-    // new different reward account set
-    if (channelUpdateParameters.reward_account.unwrap().isSome) {
-      channel.rewardAccount = channelUpdateParameters.reward_account.unwrap().unwrap().toString()
-    } else { // reward account removed
-      delete channel.rewardAccount
-    }
+    // this will change the `channel`!
+    handleChannelRewardAccountChange(channel, channelUpdateParameters.reward_account.unwrap())
   }
 
   // save channel
@@ -92,7 +89,16 @@ export async function content_ChannelAssetsRemoved(
   db: DatabaseManager,
   event: SubstrateEvent
 ) {
-  // TODO - what should happen here?
+  // read event data
+  const {contentId: contentIds} = new Content.ChannelAssetsRemovedEvent(event).data
+
+  // load channel
+  const assets = await db.getMany(Asset, { where: { id: contentIds } })
+
+  // delete assets
+  for (const asset in assets) {
+    await db.remove<Asset>(asset)
+  }
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
@@ -225,3 +231,20 @@ export async function content_ChannelCategoryDeleted(
   // delete channel category
   await db.remove<ChannelCategory>(channelCategory)
 }
+
+/////////////////// Helpers ////////////////////////////////////////////////////
+
+function handleChannelRewardAccountChange(
+  channel: Channel, // will be modified inside of the function!
+  reward_account: Option<GenericAccountId>
+) {
+  // new different reward account set?
+  if (reward_account.isSome) {
+    channel.rewardAccount = reward_account.unwrap().toString()
+    return
+  }
+
+  // reward account removed
+
+  delete channel.rewardAccount
+}

+ 12 - 8
query-node/mappings/src/content/utils.ts

@@ -1,6 +1,4 @@
 // TODO: add logging of mapping events (entity found/not found, entity updated/deleted, etc.)
-// TODO: split file into multiple files
-// TODO: make sure assets are updated when VideoUpdateParameters have only `assets` parameter set (no `new_meta` set) - if this situation can even happend
 // TODO: check all `db.get()` and similar calls recieve a proper type argument (aka add `.toString()`, etc. to those calls)
 
 import { SubstrateEvent } from '@dzlzv/hydra-common'
@@ -137,12 +135,8 @@ export async function readProtobuf(
 
     // prepare information about media published somewhere else before Joystream if needed.
     if (metaAsObject.publishedBeforeJoystream) {
-      // TODO: is ok to just ignore `isPublished?: boolean` here?
-      if (metaAsObject.publishedBeforeJoystream.date) {
-        result.publishedBeforeJoystream = new Date(metaAsObject.publishedBeforeJoystream.date)
-      } else {
-        delete result.publishedBeforeJoystream
-      }
+      // this will change the `channel`!
+      handlePublishedBeforeJoystream(result, metaAsObject.publishedBeforeJoystream.date)
     }
 
     return result
@@ -157,6 +151,16 @@ export async function readProtobuf(
   throw `Not implemented type: ${type}`
 }
 
+function handlePublishedBeforeJoystream(video: Video, publishedAtString?: string) {
+  // published elsewhere before Joystream
+  if (publishedAtString) {
+    video.publishedBeforeJoystream = new Date(publishedAt)
+  }
+
+  // unset publish info
+  delete video.publishedBeforeJoystream
+}
+
 async function convertAsset(rawAsset: NewAsset, db: DatabaseManager, event: SubstrateEvent): Promise<typeof Asset> {
   if (rawAsset.isUrls) {
     const assetUrl = new AssetUrl()

+ 18 - 0
query-node/mappings/src/storage.ts

@@ -22,8 +22,10 @@ import { LiaisonJudgement } from 'query-node/src/modules/enums/enums'
 import { AssetDataObject } from 'query-node/src/modules/asset-data-object/asset-data-object.model'
 
 export async function ContentAdded(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+  // read event data
   const {channelId , contentParameters} = new StorageTypes.ContentAddedEvent(event).data
   // TODO: resolve handling of Vec<ContentParameters> - currently only the first item is handleu
+
   const block = await prepareBlock(db, event)
   const assetStorage = await prepareAssetDataObject(contentParameters[0], block)
 
@@ -31,36 +33,52 @@ export async function ContentAdded(db: DatabaseManager, event: SubstrateEvent):
 }
 
 export async function ContentRemoved(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+  // read event data
   const {contentId: contentIds} = new StorageTypes.ContentRemovedEvent(event).data
+
+  // load assets
   const assetDataObjects = await db.getMany(AssetDataObject, { where: { joystreamContentId: contentIds }})
 
+  // remove assets from database
   for (let item of assetDataObjects) {
       await db.remove<AssetDataObject>(item)
   }
 }
 
 export async function ContentAccepted(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+  // read event data
   const {contentId} = new StorageTypes.ContentAcceptedEvent(event).data
+
+  // load asset
   const assetDataObject = await db.get(AssetDataObject, { where: { joystreamContentId: contentId }})
 
+  // ensure object exists
   if (!assetDataObject) {
     return inconsistentState()
   }
 
+  // update object
   assetDataObject.liaisonJudgement = LiaisonJudgement.ACCEPTED
 
+  // save object
   await db.save<AssetDataObject>(assetDataObject)
 }
 
 export async function ContentRejected(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+  // read event data
   const {contentId} = new StorageTypes.ContentRejectedEvent(event).data
+
+  // load asset
   const assetDataObject = await db.get(AssetDataObject, { where: { joystreamContentId: contentId }})
 
+  // ensure object exists
   if (!assetDataObject) {
     return inconsistentState()
   }
 
+  // update object
   assetDataObject.liaisonJudgement = LiaisonJudgement.REJECTED
 
+  // save object
   await db.save<AssetDataObject>(assetDataObject)
 }

+ 4 - 4
query-node/schema.graphql

@@ -213,11 +213,11 @@ type Channel @entity {
   "The description of a Channel"
   description: String
 
-  #"Channel's cover (background) photo. Recommended ratio: 16:9."
-  #coverPhoto: Asset
+  "Channel's cover (background) photo. Recommended ratio: 16:9."
+  coverPhoto: Asset
 
-  #"Channel's avatar photo."
-  #avatarPhoto: Asset
+  "Channel's avatar photo."
+  avatarPhoto: Asset
 
   "Flag signaling whether a channel is public."
   isPublic: Boolean