Sfoglia il codice sorgente

query node - mappings metadata handling fix II

ondratra 3 anni fa
parent
commit
e41433e7f8
1 ha cambiato i file con 76 aggiunte e 23 eliminazioni
  1. 76 23
      query-node/mappings/src/content/utils.ts

+ 76 - 23
query-node/mappings/src/content/utils.ts

@@ -12,6 +12,7 @@ import { Bytes } from '@polkadot/types'
 import ISO6391 from 'iso-639-1';
 import ISO6391 from 'iso-639-1';
 import { u64 } from '@polkadot/types/primitive';
 import { u64 } from '@polkadot/types/primitive';
 import { FindConditions } from 'typeorm'
 import { FindConditions } from 'typeorm'
+import * as jspb from "google-protobuf";
 
 
 // protobuf definitions
 // protobuf definitions
 import {
 import {
@@ -107,12 +108,18 @@ export async function readProtobuf<T extends ChannelCategory | VideoCategory>(
 
 
   // process channel category
   // process channel category
   if (type instanceof ChannelCategory) {
   if (type instanceof ChannelCategory) {
-    return ChannelCategoryMetadata.deserializeBinary(metaU8a).toObject() as Partial<T>
+    const meta = ChannelCategoryMetadata.deserializeBinary(metaU8a)
+    const result = convertMetadataToObject<ChannelCategoryMetadata.AsObject>(meta) as Partial<T>
+
+    return result
   }
   }
 
 
   // process video category
   // process video category
   if (type instanceof VideoCategory) {
   if (type instanceof VideoCategory) {
-    return VideoCategoryMetadata.deserializeBinary(metaU8a).toObject() as Partial<T>
+    const meta = VideoCategoryMetadata.deserializeBinary(metaU8a)
+    const result = convertMetadataToObject<VideoCategoryMetadata.AsObject>(meta) as Partial<T>
+
+    return result
   }
   }
 
 
   // this should never happen
   // this should never happen
@@ -125,12 +132,6 @@ export async function readProtobuf<T extends ChannelCategory | VideoCategory>(
   In addition it handles any assets associated with the metadata.
   In addition it handles any assets associated with the metadata.
 */
 */
 
 
-/*
-export async function readProtobufWithAssets(
-  type: Channel | Video,
-  parameters: IReadProtobufArgumentsWithAssets,
-): Promise<Partial<typeof type>> {
-*/
 export async function readProtobufWithAssets<T extends Channel | Video>(
 export async function readProtobufWithAssets<T extends Channel | Video>(
   type: T,
   type: T,
   parameters: IReadProtobufArgumentsWithAssets,
   parameters: IReadProtobufArgumentsWithAssets,
@@ -141,12 +142,13 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
   // process channel
   // process channel
   if (type instanceof Channel) {
   if (type instanceof Channel) {
     const meta = ChannelMetadata.deserializeBinary(metaU8a)
     const meta = ChannelMetadata.deserializeBinary(metaU8a)
-    const metaAsObject = meta.toObject()
+    const metaAsObject = convertMetadataToObject<ChannelMetadata.AsObject>(meta)
     const result = metaAsObject as any as Partial<Channel>
     const result = metaAsObject as any as Partial<Channel>
 
 
     // prepare cover photo asset if needed
     // prepare cover photo asset if needed
-    if (metaAsObject.coverPhoto !== undefined) {
+    if ('coverPhoto' in metaAsObject) {
       const asset = await extractAsset({
       const asset = await extractAsset({
+        //assetIndex: metaAsObject.coverPhoto,
         assetIndex: metaAsObject.coverPhoto,
         assetIndex: metaAsObject.coverPhoto,
         assets: parameters.assets,
         assets: parameters.assets,
         db: parameters.db,
         db: parameters.db,
@@ -158,7 +160,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
     }
     }
 
 
     // prepare avatar photo asset if needed
     // prepare avatar photo asset if needed
-    if (metaAsObject.avatarPhoto !== undefined) {
+    if ('avatarPhoto' in metaAsObject) {
       const asset = await extractAsset({
       const asset = await extractAsset({
         assetIndex: metaAsObject.avatarPhoto,
         assetIndex: metaAsObject.avatarPhoto,
         assets: parameters.assets,
         assets: parameters.assets,
@@ -171,7 +173,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
     }
     }
 
 
     // prepare language if needed
     // prepare language if needed
-    if (metaAsObject.language) {
+    if ('language' in metaAsObject) {
       result.language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.blockNumber)
       result.language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.blockNumber)
     }
     }
 
 
@@ -181,16 +183,16 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
   // process video
   // process video
   if (type instanceof Video) {
   if (type instanceof Video) {
     const meta = VideoMetadata.deserializeBinary(metaU8a)
     const meta = VideoMetadata.deserializeBinary(metaU8a)
-    const metaAsObject = meta.toObject()
+    const metaAsObject = convertMetadataToObject<VideoMetadata.AsObject>(meta)
     const result = metaAsObject as any as Partial<Video>
     const result = metaAsObject as any as Partial<Video>
 
 
     // prepare video category if needed
     // prepare video category if needed
-    if (metaAsObject.category !== undefined) {
+    if ('category' in metaAsObject) {
       result.category = await prepareVideoCategory(metaAsObject.category, parameters.db)
       result.category = await prepareVideoCategory(metaAsObject.category, parameters.db)
     }
     }
 
 
     // prepare media meta information if needed
     // prepare media meta information if needed
-    if (metaAsObject.mediaType) {
+    if ('mediaType' in metaAsObject) {
       // prepare video file size if poosible
       // prepare video file size if poosible
       const videoSize = await extractVideoSize(parameters.assets, metaAsObject.video)
       const videoSize = await extractVideoSize(parameters.assets, metaAsObject.video)
 
 
@@ -199,12 +201,12 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
     }
     }
 
 
     // prepare license if needed
     // prepare license if needed
-    if (metaAsObject.license) {
+    if ('license' in metaAsObject) {
       result.license = await prepareLicense(metaAsObject.license)
       result.license = await prepareLicense(metaAsObject.license)
     }
     }
 
 
     // prepare thumbnail photo asset if needed
     // prepare thumbnail photo asset if needed
-    if (metaAsObject.thumbnailPhoto !== undefined) {
+    if ('thumbnailPhoto' in metaAsObject) {
       const asset = await extractAsset({
       const asset = await extractAsset({
         assetIndex: metaAsObject.thumbnailPhoto,
         assetIndex: metaAsObject.thumbnailPhoto,
         assets: parameters.assets,
         assets: parameters.assets,
@@ -217,7 +219,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
     }
     }
 
 
     // prepare video asset if needed
     // prepare video asset if needed
-    if (metaAsObject.video !== undefined) {
+    if ('video' in metaAsObject) {
       const asset = await extractAsset({
       const asset = await extractAsset({
         assetIndex: metaAsObject.video,
         assetIndex: metaAsObject.video,
         assets: parameters.assets,
         assets: parameters.assets,
@@ -230,7 +232,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
     }
     }
 
 
     // prepare language if needed
     // prepare language if needed
-    if (metaAsObject.language) {
+    if ('language' in metaAsObject) {
       result.language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.blockNumber)
       result.language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.blockNumber)
     }
     }
 
 
@@ -366,7 +368,7 @@ async function convertAsset(parameters: IConvertAssetParameters): Promise<AssetS
 }
 }
 
 
 interface IExtractAssetParameters {
 interface IExtractAssetParameters {
-  assetIndex: number
+  assetIndex: number | undefined
   assets: NewAsset[]
   assets: NewAsset[]
   db: DatabaseManager
   db: DatabaseManager
   blockNumber: number
   blockNumber: number
@@ -377,6 +379,11 @@ interface IExtractAssetParameters {
   Selects asset from provided set of assets and prepares asset data fit to be saved to db.
   Selects asset from provided set of assets and prepares asset data fit to be saved to db.
 */
 */
 async function extractAsset(parameters: IExtractAssetParameters): Promise<AssetStorageOrUrls | undefined> {
 async function extractAsset(parameters: IExtractAssetParameters): Promise<AssetStorageOrUrls | undefined> {
+  // is asset being unset?
+  if (parameters.assetIndex === undefined) {
+    return undefined
+  }
+
   // ensure asset index is valid
   // ensure asset index is valid
   if (parameters.assetIndex >= parameters.assets.length) {
   if (parameters.assetIndex >= parameters.assets.length) {
     inconsistentState(`Non-existing asset extraction requested`, {
     inconsistentState(`Non-existing asset extraction requested`, {
@@ -467,7 +474,12 @@ async function extractVideoSize(assets: NewAsset[], assetIndex: number | undefin
   return videoSize
   return videoSize
 }
 }
 
 
-async function prepareLanguage(languageIso: string, db: DatabaseManager, blockNumber: number): Promise<Language | undefined> {
+async function prepareLanguage(languageIso: string | undefined, db: DatabaseManager, blockNumber: number): Promise<Language | undefined> {
+  // is language being unset?
+  if (languageIso === undefined) {
+    return undefined
+  }
+
   // validate language string
   // validate language string
   const isValidIso = ISO6391.validate(languageIso);
   const isValidIso = ISO6391.validate(languageIso);
 
 
@@ -501,10 +513,15 @@ async function prepareLanguage(languageIso: string, db: DatabaseManager, blockNu
   return newLanguage
   return newLanguage
 }
 }
 
 
-async function prepareLicense(licenseProtobuf: LicenseMetadata.AsObject): Promise<License> {
+async function prepareLicense(licenseProtobuf: LicenseMetadata.AsObject | undefined): Promise<License | undefined> {
   // NOTE: Deletion of any previous license should take place in appropriate event handling function
   // NOTE: Deletion of any previous license should take place in appropriate event handling function
   //       and not here even it might appear so.
   //       and not here even it might appear so.
 
 
+  // is license being unset?
+  if (licenseProtobuf === undefined) {
+    return undefined
+  }
+
   // crete new license
   // crete new license
   const license = new License({
   const license = new License({
     ...licenseProtobuf,
     ...licenseProtobuf,
@@ -544,7 +561,12 @@ async function prepareVideoMetadata(videoProtobuf: VideoMetadata.AsObject, video
   return videoMeta
   return videoMeta
 }
 }
 
 
-async function prepareVideoCategory(categoryId: number, db: DatabaseManager): Promise<VideoCategory | undefined> {
+async function prepareVideoCategory(categoryId: number | undefined, db: DatabaseManager): Promise<VideoCategory | undefined> {
+  // is category being unset?
+  if (categoryId === undefined) {
+    return undefined
+  }
+
   // load video category
   // load video category
   const category = await db.get(VideoCategory, { where: { id: categoryId.toString() } as FindConditions<VideoCategory> })
   const category = await db.get(VideoCategory, { where: { id: categoryId.toString() } as FindConditions<VideoCategory> })
 
 
@@ -556,3 +578,34 @@ async function prepareVideoCategory(categoryId: number, db: DatabaseManager): Pr
 
 
   return category
   return category
 }
 }
+
+function convertMetadataToObject<T extends Object>(metadata: jspb.Message): T {
+  const metaAsObject = metadata.toObject()
+  const result = {} as T
+
+  for (const key in metaAsObject) {
+    const funcNameBase = key.charAt(0).toUpperCase() + key.slice(1)
+    const hasFuncName = 'has' + funcNameBase
+    const isSet = funcNameBase == 'PersonsList' // there is no `VideoMetadata.hasPersonsList` method from unkown reason -> create exception
+      ? true
+      : metadata[hasFuncName]()
+
+    if (!isSet) {
+      continue
+    }
+
+
+    const getFuncName = 'get' + funcNameBase
+    const value = metadata[getFuncName]()
+
+    // TODO: check that recursion trully works
+    if (value instanceof jspb.Message) {
+      result[key] = convertMetadataToObject(value)
+      continue
+    }
+
+    result[key] = metaAsObject[key]
+  }
+
+  return result
+}