Browse Source

query node - assets mappings I

ondratra 4 years ago
parent
commit
646170687c

+ 0 - 31
query-node/README.md

@@ -71,47 +71,16 @@ sed -i 's/"query-node": "^0.0.0",//' query-node/mappings/package.json
 
 # install dependencies
 yarn
-
-# add dummy values to input schema variants that needs it
-sed -i 's/type AssetOwnerChannel @variant {/type AssetOwnerChannel @variant {\n  dummy: Int/' query-node/schema.graphql
-sed -i 's/type AssetNeverProvided @variant {/type AssetNeverProvided @variant {\n  dummy: Int/' query-node/schema.graphql
-sed -i 's/type AssetDeleted @variant {/type AssetDeleted @variant {\n  dummy: Int/' query-node/schema.graphql
-sed -i 's/type AssetUploadStatus @variant {/type AssetUploadStatus @variant {\n  dummy: Int/' query-node/schema.graphql
-
 yarn workspace @joystream/content-metadata-protobuf build
 yarn workspace @joystream/types build
 yarn workspace query-node-root build # this will fail during mappings compilation
 
-# setup TS declarations for query node compilation
-sed -i 's/"compilerOptions": {/"compilerOptions": {\n    "declaration": true,/' query-node/generated/graphql-server/tsconfig.json
-
 # add back dependency
 sed -i 's/"dependencies": {/"dependencies": {\n    "query-node": "^0.0.0",/' query-node/mappings/package.json
 
 # install query node dependency to mappings
 yarn
 
-# yarn workspace query-node compile # probably not needed
-sed -i 's/BN/number/' query-node/generated/graphql-server/src/modules/variants/variants.model.ts # replace BigNumber by number
-
-# remove extra variant imports
-TMP_VARIANT_IMPORT="import { Asset } from '../variants/variants.model'"
-sed -i "s#$TMP_VARIANT_IMPORT##;" query-node/generated/graphql-server/src/modules/channel/channel.model.ts query-node/generated/graphql-server/src/modules/video/video.model.ts
-echo $TMP_VARIANT_IMPORT >> query-node/generated/graphql-server/src/modules/channel/channel.model.ts
-echo $TMP_VARIANT_IMPORT >> query-node/generated/graphql-server/src/modules/video/video.model.ts
-
-# fix relations cardinality (why is this code generated like this? is input schema wrong or Hydra has a bug?)
-sed -i 's/return result.channels/return [result.channels]/' query-node/generated/graphql-server/src/modules/channel-category/channel-category.resolver.ts
-sed -i 's/return result.category/return result.category[0]/' query-node/generated/graphql-server/src/modules/channel/channel.resolver.ts
-sed -i 's/return result.videos/return [result.videos]/' query-node/generated/graphql-server/src/modules/video-category/video-category.resolver.ts
-sed -i 's/return result.category/return result.category[0]/' query-node/generated/graphql-server/src/modules/video/video.resolver.ts
-
-# fix two functions having the same name (why this has to be changed manually?)
-sed -i '0,/videoMediaMetadata/s/videoMediaMetadata/videoMediaMetadata2/' query-node/generated/graphql-server/src/modules/video-media-metadata/video-media-metadata.resolver.ts
-
-# add missing dependency
-sed -i 's/"dependencies": {/"dependencies": {\n    "pg-listen": "^1.7.0",/' query-node/generated/graphql-server/package.json
-
 # install new dependencies
 yarn
 

+ 1 - 9
query-node/mappings/bootstrap/members.ts

@@ -1,5 +1,3 @@
-// TODO: add logger
-
 import BN from 'bn.js'
 import { ApiPromise } from '@polkadot/api'
 import { Option } from '@polkadot/types/codec'
@@ -8,12 +6,8 @@ import { Membership as Profile } from '@joystream/types/members'
 
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 import { prepareBlock } from '../common'
-//import { DB, getLogger } from '../../generated/hydra-processor'
-import { Block, Network } from '../../generated/graphql-server/src/modules/block/block.model'
 import { Membership } from '../../generated/graphql-server/src/modules/membership/membership.model'
 
-//const logger = getLogger()
-
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function members_bootMembers(api: ApiPromise, db: DatabaseManager): Promise<void> {
   const blkHeight = process.env.BLOCK_HEIGHT ? parseInt(process.env.BLOCK_HEIGHT) : 0
@@ -21,8 +15,6 @@ export async function members_bootMembers(api: ApiPromise, db: DatabaseManager):
   const ids = await api.query.members.membersCreated.at(blkHash)
   const num: number = parseInt(ids.toString())
 
-  let block = await prepareBlock(db, {blockNumber: blkHeight, blockTimestamp: new BN(Date.now())} as any)
-
   for (let i = 0; i < num; i++) {
     const profileOpt = (await api.query.members.memberProfile.at(blkHash, i)) as Option<Profile & Codec>
     const profile: Profile | null = profileOpt.unwrapOr(null)
@@ -39,7 +31,7 @@ export async function members_bootMembers(api: ApiPromise, db: DatabaseManager):
 
     member.rootAccount = profile.root_account.toString()
     member.controllerAccount = profile.controller_account.toString()
-    member.registeredAtBlock = block
+    member.registeredAtBlock = blkHeight
 
     //logger.trace(`Saving member: ${JSON.stringify(member, null, 2)}`)
     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.16",
-    "@dzlzv/hydra-db-utils": "2.0.1-beta.16",
+    "@dzlzv/hydra-common": "2.0.1-beta.17",
+    "@dzlzv/hydra-db-utils": "2.0.1-beta.17",
     "@joystream/content-metadata-protobuf": "^1.0.0",
     "@joystream/types": "^0.16.0",
     "iso-639-1": "^2.1.8",

+ 15 - 38
query-node/mappings/src/common.ts

@@ -3,20 +3,21 @@ import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 import { u64 } from '@polkadot/types/primitive';
 
-import { Block } from 'query-node/src/modules/block/block.model'
 import { Network } from 'query-node/src/modules/enums/enums'
 
 // Asset
 import {
-  Asset,
-  AssetUploadStatus,
-  AssetStorage,
-  AssetOwnerMember,
+  DataObjectOwner,
+  DataObjectOwnerMember,
+  DataObjectOwnerChannel,
+  DataObjectOwnerDao,
+  DataObjectOwnerCouncil,
+  DataObjectOwnerWorkingGroup,
 } from 'query-node/src/modules/variants/variants.model'
 import {
-  AssetDataObject,
+  DataObject,
   LiaisonJudgement,
-} from 'query-node/src/modules/asset-data-object/asset-data-object.model'
+} from 'query-node/src/modules/data-object/data-object.model'
 import {
   ContentParameters
 } from '@joystream/types/augment'
@@ -33,28 +34,13 @@ export function inconsistentState(extraInfo: string, data?: unknown): never {
   throw errorMessage
 }
 
-// prepare block record
-export async function prepareBlock(db: DatabaseManager, event: SubstrateEvent): Promise<Block> {
-  let block = await db.get(Block, { where: { block: event.blockNumber } })
+export async function prepareDataObject(contentParameters: ContentParameters, blockNumber: number): Promise<DataObject> {
+  const dataObjectOwner = new DataObjectOwnerMember() // TODO: proper owner
+  dataObjectOwner.memberId = new BN(0)
 
-  if (block) {
-      return block
-  }
-
-  return new Block({
-    block: event.blockNumber,
-    executedAt: new Date(event.blockTimestamp.toNumber()),
-    network: currentNetwork,
-  })
-}
-
-export async function prepareAssetDataObject(contentParameters: ContentParameters, block: Block): Promise<AssetStorage> {
-  const assetOwner = new AssetOwnerMember() // TODO: proper owner
-  assetOwner.memberId = new BN(0)
-
-  const assetDataObject = new AssetDataObject({
-    owner: assetOwner,
-    addedAt: block,
+  const dataObject = new DataObject({
+    owner: dataObjectOwner,
+    addedAt: blockNumber,
     typeId: contentParameters.type_id.toNumber(),
     // `size` is masked by `size` special name in struct so there needs to be `.get('size') as u64`
     size: (contentParameters.get('size') as unknown as u64).toBn(),
@@ -63,17 +49,8 @@ export async function prepareAssetDataObject(contentParameters: ContentParameter
     ipfsContentId: contentParameters.ipfs_content_id.toHex(),
     joystreamContentId: contentParameters.content_id.toHex(),
   })
-  // TODO: handle `AssetNeverProvided` and `AssetDeleted` states
-  const uploadingStatus = new AssetUploadStatus()
-  /* TODO: set the values (`dataObject` and `oldDataObject` absent in AssetUploadStatus)
-  uploadingStatus.dataObject = new AssetDataObject
-  uploadingStatus.oldDataObject: undefined // TODO: handle oldDataObject
-  */
-
-  const assetStorage = new AssetStorage()
-  assetStorage.uploadStatus = uploadingStatus
 
-  return assetStorage
+  return dataObject
 }
 
 /////////////////// Logger /////////////////////////////////////////////////////

+ 9 - 10
query-node/mappings/src/content/channel.ts

@@ -7,13 +7,12 @@ import { Option } from '@polkadot/types/codec';
 import { Content } from '../../../generated/types'
 import { readProtobuf } from './utils'
 
-
-// Asset
-import { AssetStorage } from 'query-node/src/modules/variants/variants.model'
+import {
+  DataObject,
+} from 'query-node/src/modules/data-object/data-object.model'
 import {
   inconsistentState,
   logger,
-  prepareBlock,
 } from '../common'
 
 // primary entities
@@ -39,7 +38,7 @@ export async function content_ChannelCreated(db: DatabaseManager, event: Substra
     id: channelId,
     isCensored: false,
     videos: [],
-    happenedIn: await prepareBlock(db, event),
+    happenedIn: event.blockNumber,
     ...Object(protobufContent)
   })
 
@@ -88,7 +87,7 @@ export async function content_ChannelUpdated(
   // reward account change happened?
   if (channelUpdateParameters.reward_account.isSome) {
     // this will change the `channel`!
-    handleChannelRewardAccountChange(channel, channelUpdateParameters.reward_account.unwrap())
+    handleChannelRewardAccountChange(channel, channelUpdateParameters.reward_account.unwrap()) // TODO: get rid of unwrap
   }
 
   // save channel
@@ -106,11 +105,11 @@ export async function content_ChannelAssetsRemoved(
   const {contentId: contentIds} = new Content.ChannelAssetsRemovedEvent(event).data
 
   // load channel
-  const assets = await db.getMany(AssetStorage, { where: { id: contentIds } })
+  const assets = await db.getMany(DataObject, { where: { id: contentIds } })
 
   // delete assets
-  for (const asset in assets) {
-    await db.remove<AssetStorage>(asset)
+  for (const asset of assets) {
+    await db.remove<DataObject>(asset)
   }
 
   // emit log event
@@ -192,7 +191,7 @@ export async function content_ChannelCategoryCreated(
   const channelCategory = new ChannelCategory({
     id: event.params[0].value.toString(), // ChannelCategoryId
     channels: [],
-    happenedIn: await prepareBlock(db, event),
+    happenedIn: event.blockNumber,
     ...Object(protobufContent)
   })
 

+ 50 - 31
query-node/mappings/src/content/utils.ts

@@ -1,5 +1,7 @@
 // TODO: add logging of mapping events (entity found/not found, entity updated/deleted, etc.)
 // TODO: check all `db.get()` and similar calls recieve a proper type argument (aka add `.toString()`, etc. to those calls)
+// TODO: can we rely on db having "foreign keys"? When item is deleted will automaticly be all relations to it unset?
+//       Similarly, will saving item also save all its related items no-yet-saved in db, or do they need to saved individually?
 
 import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
@@ -24,12 +26,11 @@ import {
 
 import {
   inconsistentState,
-  prepareBlock,
-  prepareAssetDataObject,
+  prepareDataObject,
 } from '../common'
 
+
 // primary entities
-import { Block } from 'query-node/src/modules/block/block.model'
 import { CuratorGroup } from 'query-node/src/modules/curator-group/curator-group.model'
 import { Channel } from 'query-node/src/modules/channel/channel.model'
 import { ChannelCategory } from 'query-node/src/modules/channel-category/channel-category.model'
@@ -43,18 +44,11 @@ import { VideoMediaEncoding } from 'query-node/src/modules/video-media-encoding/
 import { VideoMediaMetadata } from 'query-node/src/modules/video-media-metadata/video-media-metadata.model'
 
 // Asset
+import { AssetAvailability } from 'query-node/src/modules/enums/enums';
 import {
-  Asset,
-  AssetUrl,
-  AssetUploadStatus,
-  AssetStorage,
-  AssetOwner,
-  AssetOwnerMember,
-} from 'query-node/src/modules/variants/variants.model'
-import {
-  AssetDataObject,
+  DataObject,
   LiaisonJudgement
-} from 'query-node/src/modules/asset-data-object/asset-data-object.model'
+} from 'query-node/src/modules/data-object/data-object.model'
 
 // Joystream types
 import {
@@ -62,6 +56,8 @@ import {
   NewAsset,
 } from '@joystream/types/augment'
 
+type AssetStorageOrUrls = DataObject | string[]
+
 export async function readProtobuf(
   type: Channel | ChannelCategory | Video | VideoCategory,
   metadata: Uint8Array,
@@ -77,12 +73,16 @@ export async function readProtobuf(
 
     // prepare cover photo asset if needed
     if (metaAsObject.coverPhoto !== undefined) {
-      result.coverPhoto = await extractAsset(metaAsObject.coverPhoto, assets, db, event)
+      const asset = await extractAsset(metaAsObject.coverPhoto, assets, db, event)
+      integrateAsset('coverPhoto', result, asset) // changes `result` inline!
+      delete metaAsObject.coverPhoto
     }
 
     // prepare avatar photo asset if needed
     if (metaAsObject.avatarPhoto !== undefined) {
-      result.avatarPhoto = await extractAsset(metaAsObject.avatarPhoto, assets, db, event)
+      const asset = await extractAsset(metaAsObject.avatarPhoto, assets, db, event)
+      integrateAsset('avatarPhoto', result, asset) // changes `result` inline!
+      delete metaAsObject.avatarPhoto
     }
 
     // prepare language if needed
@@ -125,12 +125,16 @@ export async function readProtobuf(
 
     // prepare thumbnail photo asset if needed
     if (metaAsObject.thumbnailPhoto !== undefined) {
-      result.thumbnailPhoto = await extractAsset(metaAsObject.thumbnailPhoto, assets, db, event)
+      const asset = await extractAsset(metaAsObject.thumbnailPhoto, assets, db, event)
+      integrateAsset('thumbnail', result, asset) // changes `result` inline!
+      delete metaAsObject.thumbnailPhoto
     }
 
     // prepare video asset if needed
     if (metaAsObject.video !== undefined) {
-      result.media = await extractAsset(metaAsObject.video, assets, db, event)
+      const asset = await extractAsset(metaAsObject.video, assets, db, event)
+      integrateAsset('media', result, asset) // changes `result` inline!
+      delete metaAsObject.video
     }
 
     // prepare language if needed
@@ -166,34 +170,27 @@ function handlePublishedBeforeJoystream(video: Video, publishedAtString?: string
   delete video.publishedBeforeJoystream
 }
 
-async function convertAsset(rawAsset: NewAsset, db: DatabaseManager, event: SubstrateEvent): Promise<typeof Asset> {
+async function convertAsset(rawAsset: NewAsset, db: DatabaseManager, event: SubstrateEvent): Promise<AssetStorageOrUrls> {
   if (rawAsset.isUrls) {
-    const assetUrl = new AssetUrl()
-    assetUrl.urls = rawAsset.asUrls.toArray().map(item => item.toString())
+    const urls = rawAsset.asUrls.toArray().map(item => item.toString())
 
-    return assetUrl
+    return urls
   }
 
   // !rawAsset.isUrls && rawAsset.isUpload
 
   const contentParameters: ContentParameters = rawAsset.asUpload
+  const dataObject = await prepareDataObject(contentParameters, event.blockNumber)
 
-  const block = await prepareBlock(db, event)
-  const assetStorage = await prepareAssetDataObject(contentParameters, block)
-
-  return assetStorage
+  return dataObject
 }
 
 async function extractAsset(
-  assetIndex: number | undefined,
+  assetIndex: number,
   assets: NewAsset[],
   db: DatabaseManager,
   event: SubstrateEvent,
-): Promise<typeof Asset | undefined> {
-  if (assetIndex === undefined) {
-    return undefined
-  }
-
+): Promise<AssetStorageOrUrls> {
   if (assetIndex > assets.length) {
     return inconsistentState(`Non-existing asset extraction requested`, {assetsProvided: assets.length, assetIndex})
   }
@@ -201,6 +198,28 @@ async function extractAsset(
   return convertAsset(assets[assetIndex], db, event)
 }
 
+// changes `result` inline!
+function integrateAsset<T>(propertyName: string, result: T, asset?: AssetStorageOrUrls): T {
+  const nameUrl = propertyName + 'Urls'
+  const nameDataObject = propertyName + 'DataObject'
+  const nameAvailability = propertyName + 'Availability'
+
+  const isUrls = Array.isArray(asset) // simple check if asset contains urls (thus it's not stored in storage)
+  if (isUrls) {
+    result[nameUrl] = asset
+    result[nameAvailability] = AssetAvailability.ACCEPTED // TODO: solve availability
+    delete result[nameDataObject]
+
+    return result
+  }
+
+  result[nameUrl] = asset
+  result[nameAvailability] = AssetAvailability.ACCEPTED // TODO: solve availability
+  delete result[nameDataObject]
+
+  return result
+}
+
 async function extractVideoSize(assets: NewAsset[], assetIndex: number | undefined): Promise<BN | undefined> {
   if (assetIndex === undefined) {
     return undefined

+ 2 - 3
query-node/mappings/src/content/video.ts

@@ -8,7 +8,6 @@ import {
 import {
   inconsistentState,
   logger,
-  prepareBlock,
 } from '../common'
 
 import { readProtobuf } from './utils'
@@ -42,7 +41,7 @@ export async function content_VideoCategoryCreated(
     id: videoCategoryId.toString(), // ChannelId
     isCensored: false,
     videos: [],
-    happenedIn: await prepareBlock(db, event),
+    happenedIn: event.blockNumber,
     ...Object(protobufContent)
   })
 
@@ -137,7 +136,7 @@ export async function content_VideoCreated(
     id: videoId,
     isCensored: false,
     channel: channelId,
-    happenedIn: await prepareBlock(db, event),
+    happenedIn: event.blockNumber,
     ...Object(protobufContent)
   })
 

+ 1 - 3
query-node/mappings/src/membership.ts

@@ -7,11 +7,9 @@ import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 import {
   inconsistentState,
   logger,
-  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
@@ -48,7 +46,7 @@ export async function members_MemberRegistered(db: DatabaseManager, event_: Subs
     handle: convertBytesToString(handle.unwrap()), // TODO: get rid of unwraps
     about: convertBytesToString(about.unwrap()),
     avatarUri: convertBytesToString(avatarUri.unwrap()),
-    registeredAtBlock: await prepareBlock(db, event_),
+    registeredAtBlock: event_.blockNumber,
     registeredAtTime: new Date(event_.blockTimestamp.toNumber()),
     // TODO: in the runtime there is currently no way to distinguish distinguish `buy_membership`(method `Paid`) and `add_screened_member`(`Screening`)
     entry: MembershipEntryMethod.PAID,

+ 16 - 21
query-node/mappings/src/storage.ts

@@ -6,8 +6,7 @@ import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 import {
   inconsistentState,
   logger,
-  prepareAssetDataObject,
-  prepareBlock,
+  prepareDataObject,
 } from './common'
 
 import { Storage as StorageTypes } from '../../generated/types'
@@ -15,22 +14,18 @@ import {
   ContentId,
   ContentParameters,
 } from '@joystream/types/augment'
-import {
-  AssetStorage,
-} from 'query-node/src/modules/variants/variants.model'
 import { LiaisonJudgement } from 'query-node/src/modules/enums/enums'
 
-import { AssetDataObject } from 'query-node/src/modules/asset-data-object/asset-data-object.model'
+import { DataObject } from 'query-node/src/modules/data-object/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)
+  const dataObject = await prepareDataObject(contentParameters[0], event.blockNumber)
 
-  await db.save<AssetStorage>(assetStorage)
+  await db.save<DataObject>(dataObject)
 
   // emit log event
   logger.info("Storage content has beed added", {/*id: assetStorage.id, */channelId}) // TODO: update after Asset change merge
@@ -41,15 +36,15 @@ export async function ContentRemoved(db: DatabaseManager, event: SubstrateEvent)
   const {contentId: contentIds} = new StorageTypes.ContentRemovedEvent(event).data
 
   // load assets
-  const assetDataObjects = await db.getMany(AssetDataObject, { where: { joystreamContentId: contentIds }})
+  const dataObjects = await db.getMany(DataObject, { where: { joystreamContentId: contentIds }})
 
   // remove assets from database
-  for (let item of assetDataObjects) {
-      await db.remove<AssetDataObject>(item)
+  for (let item of dataObjects) {
+      await db.remove<DataObject>(item)
   }
 
   // emit log event
-  logger.info("Storage content have been removed", {id: contentIds, dataObjectIds: assetDataObjects.map(item => item.id)})
+  logger.info("Storage content have been removed", {id: contentIds, dataObjectIds: dataObjects.map(item => item.id)})
 }
 
 export async function ContentAccepted(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
@@ -57,18 +52,18 @@ export async function ContentAccepted(db: DatabaseManager, event: SubstrateEvent
   const {contentId} = new StorageTypes.ContentAcceptedEvent(event).data
 
   // load asset
-  const assetDataObject = await db.get(AssetDataObject, { where: { joystreamContentId: contentId }})
+  const dataObject = await db.get(DataObject, { where: { joystreamContentId: contentId }})
 
   // ensure object exists
-  if (!assetDataObject) {
+  if (!dataObject) {
     return inconsistentState('Non-existing content acceptation requested', contentId)
   }
 
   // update object
-  assetDataObject.liaisonJudgement = LiaisonJudgement.ACCEPTED
+  dataObject.liaisonJudgement = LiaisonJudgement.ACCEPTED
 
   // save object
-  await db.save<AssetDataObject>(assetDataObject)
+  await db.save<DataObject>(dataObject)
 
   // emit log event
   logger.info("Storage content has been accepted", {id: contentId})
@@ -79,18 +74,18 @@ export async function ContentRejected(db: DatabaseManager, event: SubstrateEvent
   const {contentId} = new StorageTypes.ContentRejectedEvent(event).data
 
   // load asset
-  const assetDataObject = await db.get(AssetDataObject, { where: { joystreamContentId: contentId }})
+  const dataObject = await db.get(DataObject, { where: { joystreamContentId: contentId }})
 
   // ensure object exists
-  if (!assetDataObject) {
+  if (!dataObject) {
     return inconsistentState('Non-existing content rejection requested', contentId)
   }
 
   // update object
-  assetDataObject.liaisonJudgement = LiaisonJudgement.REJECTED
+  dataObject.liaisonJudgement = LiaisonJudgement.REJECTED
 
   // save object
-  await db.save<AssetDataObject>(assetDataObject)
+  await db.save<DataObject>(dataObject)
 
   // emit log event
   logger.info("Storage content has been rejected", {id: contentId})

+ 2 - 2
query-node/package.json

@@ -38,8 +38,8 @@
     "@types/bn.js": "^4.11.6",
     "bn.js": "^5.1.2",
     "@polkadot/metadata": "^4.1.1",
-    "@dzlzv/hydra-cli": "2.0.1-beta.16",
-    "@dzlzv/hydra-processor": "2.0.1-beta.16"
+    "@dzlzv/hydra-cli": "2.0.1-beta.17",
+    "@dzlzv/hydra-processor": "2.0.1-beta.17"
   },
   "devDependencies": {
     "@dzlzv/hydra-typegen": "2.0.1-beta.16"

+ 12 - 9
query-node/schema.graphql

@@ -31,7 +31,7 @@ type Membership @entity {
   rootAccount: String!
 
   "Blocknumber when member was registered"
-  registeredAtBlock: BigInt!
+  registeredAtBlock: Int!
 
   "Timestamp when member was registered"
   registeredAtTime: DateTime!
@@ -54,7 +54,7 @@ type ChannelCategory @entity {
 
   channels: [Channel!]! @derivedFrom(field: "category")
 
-  happenedIn: BigInt!
+  happenedIn: Int!
 }
 
 "Asset availability representation"
@@ -87,7 +87,7 @@ type DataObject @entity {
   owner: DataObjectOwner!
 
   "Content added at"
-  addedAt: BigInt!
+  addedAt: Int!
 
   "Content type id"
   typeId: Int!
@@ -117,8 +117,11 @@ union DataObjectOwner = DataObjectOwnerMember
 
 "Asset owned by a member"
 type DataObjectOwnerMember @variant {
+  # use `BigInt` instead of `Membership` before variant relations are featured in Hydra
+  #"Member identifier"
+  #memberId: Membership!
   "Member identifier"
-  memberId: Membership!
+  memberId: BigInt!
 
   "Variant needs to have at least one property. This value is not used."
   dummy: Int!
@@ -160,7 +163,7 @@ type Language @entity {
   "Language identifier ISO 639-1"
   iso: String!
 
-  happenedIn: BigInt!
+  happenedIn: Int!
 }
 
 type Channel @entity {
@@ -223,7 +226,7 @@ type Channel @entity {
 
   videos: [Video!]! @derivedFrom(field: "channel")
 
-  happenedIn: BigInt!
+  happenedIn: Int!
 }
 
 type CuratorGroup @entity {
@@ -248,7 +251,7 @@ type VideoCategory @entity {
 
   videos: [Video!]! @derivedFrom(field: "category")
 
-  happenedIn: BigInt!
+  happenedIn: Int!
 }
 
 type Video @entity {
@@ -324,7 +327,7 @@ type Video @entity {
   "Video file metadata"
   mediaMetadata: VideoMediaMetadata
 
-  happenedIn: BigInt!
+  happenedIn: Int!
 
   "Is video featured or not"
   isFeatured: Boolean!
@@ -350,7 +353,7 @@ type VideoMediaMetadata @entity {
 
   video: Video @derivedFrom(field: "mediaMetadata")
 
-  happenedIn: BigInt!
+  happenedIn: Int!
 }
 
 type VideoMediaEncoding @entity {