Browse Source

query node - mappings implementation III

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

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

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

+ 16 - 10
query-node/mappings/mappingsContent.ts

@@ -5,6 +5,7 @@
 
 import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
+import ISO6391 from 'iso-639-1';
 
 // protobuf definitions
 import {
@@ -161,7 +162,7 @@ async function readProtobuf(
 async function convertAsset(rawAsset: NewAsset, db: DatabaseManager, event: SubstrateEvent): Promise<typeof Asset> {
   if (rawAsset.isUrls) {
     const assetUrl = new AssetUrl()
-    assetUrl.url = rawAsset.asUrls.toArray()[0].toString() // TODO: find out why asUrl() returns array
+    assetUrl.urls = rawAsset.asUrls.toArray().map(item => item.toString())
 
     return assetUrl
   }
@@ -187,18 +188,17 @@ async function extractAsset(
   }
 
   if (assetIndex > assets.length) {
-    throw 'Inconsistent state' // TODO: more sophisticated inconsistency handling; unify handling with other critical errors
+    return inconsistentState()
   }
 
   return convertAsset(assets[assetIndex], db, event)
 }
 
 async function prepareLanguage(languageIso: string, db: DatabaseManager): Promise<Language> {
-  // TODO: ensure language is ISO name
-  const isValidIso = true;
+  const isValidIso = ISO6391.validate(languageIso);
 
   if (!isValidIso) {
-    throw 'Inconsistent state' // TODO: create a proper way of handling inconsistent state
+    return inconsistentState()
   }
 
   const language = await db.get(Language, { where: { iso: languageIso }})
@@ -215,8 +215,6 @@ async function prepareLanguage(languageIso: string, db: DatabaseManager): Promis
 }
 
 async function prepareLicense(licenseProtobuf: LicenseMetadata.AsObject): Promise<License> {
-  // TODO: add old license removal (when existing) or rework the whole function
-
   const license = new License(licenseProtobuf)
 
   return license
@@ -239,7 +237,7 @@ async function prepareVideoCategory(categoryId: number, db: DatabaseManager): Pr
   const category = await db.get(VideoCategory, { where: { id: categoryId }})
 
   if (!category) {
-    throw 'Inconsistent state' // TODO: create a proper way of handling inconsistent state
+    return inconsistentState()
   }
 
   return category
@@ -603,10 +601,18 @@ export async function content_VideoUpdated(
       event,
     )
 
+    // remember original license
+    const originalLicense = video.license
+
     // update all fields read from protobuf
     for (let [key, value] of Object(protobufContent).entries()) {
       video[key] = value
     }
+
+    // license has changed - delete old license
+    if (originalLicense && video.license != originalLicense) {
+      await db.remove<License>(originalLicense)
+    }
   }
 
   // TODO: handle situation when only assets changed
@@ -759,7 +765,7 @@ export async function content_CuratorGroupStatusSet(
   event: SubstrateEvent
 ) {
   // read event data
-  const {curatorGroupId, isActive} = new Content.CuratorGroupStatusSetEvent(event).data
+  const {curatorGroupId, bool: isActive} = new Content.CuratorGroupStatusSetEvent(event).data
 
   // load curator group
   const curatorGroup = await db.get(CuratorGroup, { where: { id: curatorGroupId }})
@@ -770,7 +776,7 @@ export async function content_CuratorGroupStatusSet(
   }
 
   // update curator group
-  curatorGroup.isActive = isActive
+  curatorGroup.isActive = isActive.isTrue
 
   // save curator group
   await db.save<CuratorGroup>(curatorGroup)

+ 48 - 2
query-node/mappings/membership.ts

@@ -4,26 +4,42 @@ import { MemberId } from '@joystream/types/members'
 import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 
-import { prepareBlock } from './common'
+import {
+  inconsistentState,
+  prepareBlock,
+} from './common'
 import { Members } from '../generated/types'
 import { MembershipEntryMethod, Membership } from 'query-node/src/modules/membership/membership.model'
 import { Block } from 'query-node/src/modules/block/block.model'
 
+/*
+  Retrive membership from the database
+*/
 async function getMemberById(db: DatabaseManager, id: MemberId): Promise<Membership> {
+  // load member
   const member = await db.get(Membership, { where: { id: id.toString() } })
-  if (!member) throw Error(`Member(${id}) not found`)
+
+  // ensure member exists
+  if (!member) {
+    return inconsistentState(`Member(${id}) not found`)
+  }
   return member
 }
 
+/*
+  Helper for converting Bytes type to string
+*/
 function convertBytesToString(b: Bytes): string {
   return Buffer.from(b.toU8a(true)).toString()
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function members_MemberRegistered(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
+  // read event data
   const { accountId, memberId } = new Members.MemberRegisteredEvent(event_).data
   const { avatarUri, about, handle } = new Members.BuyMembershipCall(event_).args
 
+  // create new membership
   const member = new Membership({
     id: memberId.toString(),
     rootAccount: accountId.toString(),
@@ -37,50 +53,80 @@ export async function members_MemberRegistered(db: DatabaseManager, event_: Subs
     entry: MembershipEntryMethod.PAID,
   })
 
+  // save membership
   await db.save<Membership>(member)
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function members_MemberUpdatedAboutText(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
+  // read event data
   const { text, memberId } = new Members.ChangeMemberAboutTextCall(event_).args
 
+  // load member
   const member = await getMemberById(db, memberId)
+
+  // update member
   member.about = convertBytesToString(text)
+
+  // save member
   await db.save<Membership>(member)
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function members_MemberUpdatedAvatar(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
+  // read event data
   const { uri, memberId } = new Members.ChangeMemberAvatarCall(event_).args
 
+  // load member
   const member = await getMemberById(db, memberId)
+
+  // update member
   member.avatarUri = convertBytesToString(uri)
+
+  // save member
   await db.save<Membership>(member)
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function members_MemberUpdatedHandle(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
+  // read event data
   const { handle, memberId } = new Members.ChangeMemberHandleCall(event_).args
 
+  // load member
   const member = await getMemberById(db, memberId)
+
+  // update member
   member.handle = convertBytesToString(handle)
+
+  // save member
   await db.save<Membership>(member)
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function members_MemberSetRootAccount(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
+  // read event data
   const { newRootAccount, memberId } = new Members.SetRootAccountCall(event_).args
 
   const member = await getMemberById(db, memberId)
+
+  // update member
   member.rootAccount = newRootAccount.toString()
+
+  // save member
   await db.save<Membership>(member)
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function members_MemberSetControllerAccount(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
+  // read event data
   const { newControllerAccount, memberId } = new Members.SetControllerAccountCall(event_).args
 
+  // load member
   const member = await getMemberById(db, memberId)
+
+  // update member
   member.controllerAccount = newControllerAccount.toString()
+
+  // save member
   await db.save<Membership>(member)
 }

+ 2 - 2
query-node/mappings/package.json

@@ -10,8 +10,8 @@
     "clean": "rm -rf lib"
   },
   "dependencies": {
-    "@dzlzv/hydra-common": "2.0.1-beta.15",
-    "@dzlzv/hydra-db-utils": "2.0.1-beta.15",
+    "@dzlzv/hydra-common": "2.0.1-beta.16",
+    "@dzlzv/hydra-db-utils": "2.0.1-beta.16",
     "@joystream/content-metadata-protobuf": "^1.0.0",
     "@joystream/types": "^0.16.0",
     "iso-639-1": "^2.1.8",

+ 3 - 3
query-node/package.json

@@ -38,11 +38,11 @@
     "@types/bn.js": "^4.11.6",
     "bn.js": "^5.1.2",
     "@polkadot/metadata": "^4.1.1",
-    "@dzlzv/hydra-cli": "2.0.1-beta.15",
-    "@dzlzv/hydra-processor": "2.0.1-beta.15"
+    "@dzlzv/hydra-cli": "2.0.1-beta.16",
+    "@dzlzv/hydra-processor": "2.0.1-beta.16"
   },
   "devDependencies": {
-    "@dzlzv/hydra-typegen": "2.0.1-beta.15"
+    "@dzlzv/hydra-typegen": "2.0.1-beta.16"
   },
   "volta": {
 		"extends": "../package.json"

+ 5 - 5
query-node/schema.graphql

@@ -71,7 +71,7 @@ type AssetUrl @variant {
   id: ID!
 
   "The http url pointing to the media"
-  url: String!
+  urls: [String!]
 }
 
 "Asset was never fully uploaded."
@@ -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