Browse Source

query node - mappings record update improvements + commentaries

ondratra 4 years ago
parent
commit
11889fcf59

+ 1 - 1
query-node/mappings/src/content/channel.ts

@@ -281,5 +281,5 @@ function handleChannelRewardAccountChange(
 
   // reward account removed
 
-  delete channel.rewardAccount
+  channel.rewardAccount = undefined // plan deletion (will have effect when saved to db)
 }

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

@@ -28,7 +28,6 @@ import {
   prepareDataObject,
 } from '../common'
 
-
 // primary entities
 import { CuratorGroup } from 'query-node/src/modules/curator-group/curator-group.model'
 import { Channel } from 'query-node/src/modules/channel/channel.model'
@@ -55,8 +54,14 @@ import {
   NewAsset,
 } from '@joystream/types/augment'
 
+/*
+  Asset either stored in storage or describing list of URLs.
+*/
 type AssetStorageOrUrls = DataObject | string[]
 
+/*
+  Type guard differentiating asset stored in storage from asset describing a list of URLs.
+*/
 function isAssetInStorage(dataObject: AssetStorageOrUrls): dataObject is DataObject {
   if (Array.isArray(dataObject)) {
     return false
@@ -65,10 +70,13 @@ function isAssetInStorage(dataObject: AssetStorageOrUrls): dataObject is DataObj
   return true
 }
 
+/*
+  Reads information from the event and protobuf metadata and constructs changeset that's fit to be used when saving to db.
+*/
 export async function readProtobuf(
   type: Channel | ChannelCategory | Video | VideoCategory,
   metadata: Uint8Array,
-  assets: NewAsset[],
+  assets: NewAsset[], // assets provided in event
   db: DatabaseManager,
   event: SubstrateEvent,
 ): Promise<Partial<typeof type>> {
@@ -174,39 +182,55 @@ function handlePublishedBeforeJoystream(video: Video, publishedAtString?: string
   }
 
   // unset publish info
-  delete video.publishedBeforeJoystream
+  video.publishedBeforeJoystream = undefined // plan deletion (will have effect when saved to db)
 }
 
+/*
+  Converts event asset into data object or list of URLs fit to be saved to db.
+*/
 async function convertAsset(rawAsset: NewAsset, db: DatabaseManager, event: SubstrateEvent): Promise<AssetStorageOrUrls> {
+  // is asset describing list of URLs?
   if (rawAsset.isUrls) {
     const urls = rawAsset.asUrls.toArray().map(item => item.toString())
 
     return urls
   }
 
-  // !rawAsset.isUrls && rawAsset.isUpload
+  // !rawAsset.isUrls && rawAsset.isUpload // asset is in storage
 
+  // prepare data object
   const contentParameters: ContentParameters = rawAsset.asUpload
   const dataObject = await prepareDataObject(contentParameters, event.blockNumber)
 
   return dataObject
 }
 
+/*
+  Selects asset from provided set of assets and prepares asset data fit to be saved to db.
+*/
 async function extractAsset(
   assetIndex: number,
   assets: NewAsset[],
   db: DatabaseManager,
   event: SubstrateEvent,
 ): Promise<AssetStorageOrUrls> {
+  // ensure asset index is valid
   if (assetIndex > assets.length) {
     return inconsistentState(`Non-existing asset extraction requested`, {assetsProvided: assets.length, assetIndex})
   }
 
+  // convert asset to data object record
   return convertAsset(assets[assetIndex], db, event)
 }
 
-// changes `result` inline!
-function integrateAsset<T>(propertyName: string, result: T, asset: AssetStorageOrUrls): T {
+/*
+  As a temporary messure to overcome yet-to-be-implemented features in Hydra, we are using redudant information
+  to describe asset state. This function introduces all redudant data needed to be saved to db.
+
+  Changes `result` argument!
+*/
+function integrateAsset<T>(propertyName: string, result: Object, asset: AssetStorageOrUrls) {
+  // helpers - property names
   const nameUrl = propertyName + 'Urls'
   const nameDataObject = propertyName + 'DataObject'
   const nameAvailability = propertyName + 'Availability'
@@ -216,7 +240,7 @@ function integrateAsset<T>(propertyName: string, result: T, asset: AssetStorageO
     // (un)set asset's properties
     result[nameUrl] = asset
     result[nameAvailability] = AssetAvailability.ACCEPTED
-    delete result[nameDataObject]
+    result[nameDataObject] = undefined // plan deletion (will have effect when saved to db)
 
     return result
   }
@@ -229,50 +253,57 @@ function integrateAsset<T>(propertyName: string, result: T, asset: AssetStorageO
   }
 
   // (un)set asset's properties
-  delete result[nameUrl]
+  result[nameUrl] = undefined // plan deletion (will have effect when saved to db)
   result[nameAvailability] = conversionTable[asset.liaisonJudgement]
   result[nameDataObject] = asset
-
-  return result
 }
 
 async function extractVideoSize(assets: NewAsset[], assetIndex: number | undefined): Promise<BN | undefined> {
+  // escape if no asset is required
   if (assetIndex === undefined) {
     return undefined
   }
 
+  // ensure asset index is valid
   if (assetIndex > assets.length) {
     return inconsistentState(`Non-existing asset video size extraction requested`, {assetsProvided: assets.length, assetIndex})
   }
 
   const rawAsset = assets[assetIndex]
 
+  // escape if asset is describing URLs (can't get size)
   if (rawAsset.isUrls) {
     return undefined
   }
 
-  // !rawAsset.isUrls && rawAsset.isUpload
+  // !rawAsset.isUrls && rawAsset.isUpload // asset is in storage
 
+  // extract video size
   const contentParameters: ContentParameters = rawAsset.asUpload
-  // `size` is masked by `size` special name in struct so there needs to be `.get('size') as u64`
+  // `size` is masked by `size` special name in struct that's why there needs to be `.get('size') as u64`
   const videoSize = (contentParameters.get('size') as unknown as u64).toBn()
 
   return videoSize
 }
 
 async function prepareLanguage(languageIso: string, db: DatabaseManager): Promise<Language> {
+  // validate language string
   const isValidIso = ISO6391.validate(languageIso);
 
+  // ensure language string is valid
   if (!isValidIso) {
     return inconsistentState(`Invalid language ISO-639-1 provided`, languageIso)
   }
 
+  // load language
   const language = await db.get(Language, { where: { iso: languageIso }})
 
+  // return existing language if any
   if (language) {
     return language;
   }
 
+  // create new language
   const newLanguage = new Language({
     iso: languageIso
   })
@@ -281,20 +312,27 @@ async function prepareLanguage(languageIso: string, db: DatabaseManager): Promis
 }
 
 async function prepareLicense(licenseProtobuf: LicenseMetadata.AsObject): Promise<License> {
+  // NOTE: Deletion of any previous license should take place in appropriate even handling function
+  //       and not here even it might appear so.
+
+  // crete new license
   const license = new License(licenseProtobuf)
 
   return license
 }
 
 async function prepareVideoMetadata(videoProtobuf: VideoMetadata.AsObject, videoSize: BN | undefined): Promise<VideoMediaMetadata> {
+  // create new encoding info
   const encoding = new VideoMediaEncoding(videoProtobuf.mediaType)
 
+  // create new video metadata
   const videoMeta = new VideoMediaMetadata({
     encoding,
     pixelWidth: videoProtobuf.mediaPixelWidth,
     pixelHeight: videoProtobuf.mediaPixelHeight,
   })
 
+  // fill in video size if provided
   if (videoSize !== undefined) {
     videoMeta.size = videoSize
   }
@@ -303,8 +341,10 @@ async function prepareVideoMetadata(videoProtobuf: VideoMetadata.AsObject, video
 }
 
 async function prepareVideoCategory(categoryId: number, db: DatabaseManager): Promise<VideoCategory> {
+  // load video category
   const category = await db.get(VideoCategory, { where: { id: categoryId }})
 
+  // ensure video category exists
   if (!category) {
     return inconsistentState('Non-existing video category association with video requested', categoryId)
   }

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

@@ -1,5 +1,3 @@
-// TODO: validate storage types are generated as expected
-
 import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'