Browse Source

Content directory mappings - BigInt fields, empty assets and unset license fixes

Leszek Wiesner 3 years ago
parent
commit
8a0e6559ac

+ 17 - 0
query-node/kill.sh

@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+set -e
+
+SCRIPT_PATH="$(dirname "${BASH_SOURCE[0]}")"
+cd $SCRIPT_PATH
+
+set -a
+. ../.env
+set +a
+
+# Only remove query-node related services
+docker-compose rm -vsf processor-mnt
+docker-compose rm -vsf graphql-server-mnt
+docker-compose rm -vsf indexer
+docker-compose rm -vsf hydra-indexer-gateway
+docker-compose rm -vsf redis
+docker-compose rm -vsf db

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

@@ -14,6 +14,7 @@ import { ContentParameters as Custom_ContentParameters } from '@joystream/types/
 import { registry } from '@joystream/types'
 import { metaToObject } from '@joystream/metadata-protobuf/utils'
 import { AnyMetadataClass, DecodedMetadataObject } from '@joystream/metadata-protobuf/types'
+import BN from 'bn.js'
 
 export const CURRENT_NETWORK = Network.OLYMPIA
 /*
@@ -93,7 +94,7 @@ export async function createDataObject(
     updatedAt: new Date(event.blockTimestamp),
     createdInBlock: event.blockNumber,
     typeId: typeId.toNumber(),
-    size: sizeInBytes.toNumber(),
+    size: new BN(sizeInBytes.toString()),
     liaisonJudgement: LiaisonJudgement.PENDING, // judgement is pending at start; liaison id is set when content is accepted/rejected
     ipfsContentId: ipfsContentId.toUtf8(),
     joystreamContentId: dataObjectId,

+ 4 - 3
query-node/mappings/content/channel.ts

@@ -7,7 +7,7 @@ import { AccountId } from '@polkadot/types/interfaces'
 import { Option } from '@polkadot/types/codec'
 import { Content } from '../generated/types'
 import { convertContentActorToChannelOwner, processChannelMetadata } from './utils'
-import { Channel, ChannelCategory, DataObject } from 'query-node/dist/model'
+import { AssetNone, Channel, ChannelCategory, DataObject } from 'query-node/dist/model'
 import { deserializeMetadata, inconsistentState, logger } from '../common'
 import { ChannelCategoryMetadata, ChannelMetadata } from '@joystream/metadata-protobuf'
 import { integrateMeta } from '@joystream/metadata-protobuf/utils'
@@ -24,11 +24,12 @@ export async function content_ChannelCreated(ctx: EventContext & StoreContext):
     isCensored: false,
     videos: [],
     createdInBlock: event.blockNumber,
-
+    // assets
+    coverPhoto: new AssetNone(),
+    avatarPhoto: new AssetNone(),
     // fill in auto-generated fields
     createdAt: new Date(event.blockTimestamp),
     updatedAt: new Date(event.blockTimestamp),
-
     // prepare channel owner (handles fields `ownerMember` and `ownerCuratorGroup`)
     ...(await convertContentActorToChannelOwner(store, contentActor)),
   })

+ 36 - 28
query-node/mappings/content/utils.ts

@@ -43,6 +43,7 @@ import { ContentParameters, NewAsset, ContentActor } from '@joystream/types/augm
 import { ContentParameters as Custom_ContentParameters } from '@joystream/types/storage'
 import { registry } from '@joystream/types'
 import { DecodedMetadataObject } from '@joystream/metadata-protobuf/types'
+import BN from 'bn.js'
 
 export async function processChannelMetadata(
   ctx: EventContext & StoreContext,
@@ -114,7 +115,7 @@ export async function processVideoMetadata(
 
   // prepare license if needed
   if (isSet(meta.license)) {
-    video.license = await processLicense(ctx, video.license, meta.license)
+    await updateVideoLicense(ctx, video, meta.license)
   }
 
   // prepare thumbnail photo asset if needed
@@ -200,7 +201,7 @@ async function processVideoMediaMetadata(
 
   // integrate media-related data
   const mediaMetadata = {
-    size: videoSize,
+    size: isSet(videoSize) ? new BN(videoSize.toString()) : undefined,
     pixelWidth: metadata.mediaPixelWidth,
     pixelHeight: metadata.mediaPixelHeight,
   }
@@ -381,39 +382,46 @@ async function processLanguage(
   return newLanguage
 }
 
-async function processLicense(
+async function updateVideoLicense(
   ctx: StoreContext & EventContext,
-  existingLicense: License | undefined,
-  metadata: ILicense | null | undefined
-): Promise<License | undefined> {
+  video: Video,
+  licenseMetadata: ILicense | null | undefined
+): Promise<void> {
   const { store, event } = ctx
 
-  if (!isSet(metadata)) {
-    return existingLicense
+  if (!isSet(licenseMetadata)) {
+    return
   }
 
-  if (isLicenseEmpty(metadata)) {
-    // license is meant to be deleted
-    if (existingLicense) {
-      await store.remove<License>(existingLicense)
-    }
-    return undefined
+  const previousLicense = video.license
+  let license: License | null = null
+
+  if (!isLicenseEmpty(licenseMetadata)) {
+    // license is meant to be created/updated
+    license =
+      previousLicense ||
+      new License({
+        createdAt: new Date(event.blockTimestamp),
+        createdById: '1',
+        updatedById: '1',
+      })
+    license.updatedAt = new Date(event.blockTimestamp)
+    integrateMeta(license, licenseMetadata, ['attribution', 'code', 'customText'])
+    await store.save<License>(license)
   }
 
-  // license is meant to be created/updated
-  const license =
-    existingLicense ||
-    new License({
-      createdAt: new Date(event.blockTimestamp),
-      createdById: '1',
-      updatedById: '1',
-    })
-  license.updatedAt = new Date(event.blockTimestamp)
-  integrateMeta(license, metadata, ['attribution', 'code', 'customText'])
-
-  await store.save<License>(license)
-
-  return license
+  // Update license (and potentially remove foreign key reference)
+  // FIXME: Note that we MUST to provide "null" here in order to unset a relation,
+  // even though the model typings itself are not aware that "null" is a valid value.
+  // See: https://github.com/typeorm/typeorm/issues/2934
+  video.license = license as License | undefined
+  video.updatedAt = new Date(ctx.event.blockTimestamp)
+  await store.save<Video>(video)
+
+  // Safely remove previous license if needed
+  if (previousLicense && !license) {
+    await store.remove<License>(previousLicense)
+  }
 }
 
 /*

+ 3 - 1
query-node/mappings/content/video.ts

@@ -6,7 +6,7 @@ import { In } from 'typeorm'
 import { Content } from '../generated/types'
 import { deserializeMetadata, inconsistentState, logger } from '../common'
 import { processVideoMetadata } from './utils'
-import { Channel, Video, VideoCategory } from 'query-node/dist/model'
+import { AssetNone, Channel, Video, VideoCategory } from 'query-node/dist/model'
 import { VideoMetadata, VideoCategoryMetadata } from '@joystream/metadata-protobuf'
 import { integrateMeta } from '@joystream/metadata-protobuf/utils'
 
@@ -106,6 +106,8 @@ export async function content_VideoCreated(ctx: EventContext & StoreContext): Pr
     isCensored: false,
     isFeatured: false,
     createdInBlock: event.blockNumber,
+    thumbnailPhoto: new AssetNone(),
+    media: new AssetNone(),
     createdAt: new Date(event.blockTimestamp),
     updatedAt: new Date(event.blockTimestamp),
   })

+ 7 - 2
query-node/schemas/content.graphql

@@ -9,7 +9,12 @@ type AssetJoystreamStorage @variant {
   dataObject: DataObject!
 }
 
-union Asset = AssetExternal | AssetJoystreamStorage
+# FIXME: https://github.com/Joystream/hydra/issues/434
+type AssetNone @variant {
+  _phantom: Int
+}
+
+union Asset = AssetExternal | AssetJoystreamStorage | AssetNone
 
 "Category of media channel"
 type ChannelCategory @entity {
@@ -174,7 +179,7 @@ type VideoMediaMetadata @entity {
   pixelHeight: Int
 
   "Video media size in bytes"
-  size: Int
+  size: BigInt
 
   video: Video @derivedFrom(field: "mediaMetadata")
 

+ 1 - 1
query-node/schemas/storage.graphql

@@ -19,7 +19,7 @@ type DataObject @entity {
   typeId: Int!
 
   "Content size in bytes"
-  size: Int!
+  size: BigInt!
 
   "Storage provider id of the liaison"
   liaison: Worker # liaison is unset until storage provider accepts or rejects the content