Преглед на файлове

Merge pull request #1892 from metmirr/query-node-entity-remove-fix

Query node entity remove fix
Mokhtar Naamani преди 4 години
родител
ревизия
d46d66caeb

+ 2 - 2
query-node/mappings/content-directory/content-dir-consts.ts

@@ -1,4 +1,4 @@
-import { IPropertyWithId } from '../types'
+import { IKnownClass, IPropertyWithId } from '../types'
 
 // Content directory predefined class names
 export enum ContentDirectoryKnownClasses {
@@ -18,7 +18,7 @@ export enum ContentDirectoryKnownClasses {
 }
 
 // Predefined content-directory classes, classId may change after the runtime seeding
-export const contentDirectoryClassNamesWithId: { classId: number; name: string }[] = [
+export const contentDirectoryClassNamesWithId: IKnownClass[] = [
   { name: ContentDirectoryKnownClasses.CHANNEL, classId: 1 },
   { name: ContentDirectoryKnownClasses.CATEGORY, classId: 2 },
   { name: ContentDirectoryKnownClasses.HTTPMEDIALOCATION, classId: 3 },

+ 15 - 37
query-node/mappings/content-directory/entity/index.ts

@@ -57,7 +57,6 @@ import {
   userDefinedLicensePropertyNamesWithId,
   videoMediaEncodingPropertyNamesWithId,
   videoPropertyNamesWithId,
-  contentDirectoryClassNamesWithId,
   ContentDirectoryKnownClasses,
   featuredVideoPropertyNamesWithId,
 } from '../content-dir-consts'
@@ -80,7 +79,7 @@ import {
   IMediaLocation,
   IFeaturedVideo,
 } from '../../types'
-import { getOrCreate } from '../get-or-create'
+import { getOrCreate, getKnownClass } from '../get-or-create'
 
 const debug = Debug('mappings:content-directory')
 
@@ -91,22 +90,13 @@ async function contentDirectory_EntitySchemaSupportAdded(db: DB, event: Substrat
 
   const { blockNumber: block } = event
   const entityId = decode.stringIfyEntityId(event)
-  const classEntity = await db.get(ClassEntity, { where: { id: entityId } })
 
-  if (classEntity === undefined) {
-    console.log(`Class not found for the EntityId: ${entityId}`)
-    return
-  }
-
-  const cls = contentDirectoryClassNamesWithId.find((c) => c.classId === classEntity.classId)
-  if (cls === undefined) {
-    console.log('Not recognized class')
-    return
-  }
+  const [knownClass] = await getKnownClass(db, { where: { id: entityId } })
+  if (!knownClass) return
 
   const arg: IDBBlockId = { db, block, id: entityId }
 
-  switch (cls.name) {
+  switch (knownClass.name) {
     case ContentDirectoryKnownClasses.CHANNEL:
       await createChannel(
         arg,
@@ -183,7 +173,7 @@ async function contentDirectory_EntitySchemaSupportAdded(db: DB, event: Substrat
       break
 
     default:
-      throw new Error(`Unknown class name: ${cls.name}`)
+      throw new Error(`Unknown class name: ${knownClass.name}`)
   }
 }
 
@@ -194,19 +184,10 @@ async function contentDirectory_EntityRemoved(db: DB, event: SubstrateEvent): Pr
   const entityId = decode.stringIfyEntityId(event)
   const where: IWhereCond = { where: { id: entityId } }
 
-  const classEntity = await db.get(ClassEntity, where)
-  if (classEntity === undefined) {
-    console.log(`Class not found for the EntityId: ${entityId}`)
-    return
-  }
-
-  const cls = contentDirectoryClassNamesWithId.find((c) => c.classId === classEntity.classId)
-  if (cls === undefined) {
-    console.log('Unknown class')
-    return
-  }
+  const [knownClass, classEntity] = await getKnownClass(db, where)
+  if (!knownClass) return
 
-  switch (cls.name) {
+  switch (knownClass.name) {
     case ContentDirectoryKnownClasses.CHANNEL:
       await removeChannel(db, where)
       break
@@ -259,8 +240,9 @@ async function contentDirectory_EntityRemoved(db: DB, event: SubstrateEvent): Pr
       break
 
     default:
-      throw new Error(`Unknown class name: ${cls.name}`)
+      throw new Error(`Unknown class name: ${knownClass.name}`)
   }
+  await db.remove<ClassEntity>(classEntity)
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
@@ -290,21 +272,17 @@ async function contentDirectory_EntityPropertyValuesUpdated(db: DB, event: Subst
 
   const { 2: newPropertyValues } = extrinsic.args
   const entityId = decode.stringIfyEntityId(event)
-
-  const ce = await db.get(ClassEntity, { where: { id: entityId } })
-  if (ce === undefined) throw Error(`Class not found for the entity id: ${entityId}`)
-
-  const cls = contentDirectoryClassNamesWithId.find((c) => c.classId === ce.classId)
-  if (cls === undefined) throw Error(`Not known class id: ${ce.classId}`)
-
   const where: IWhereCond = { where: { id: entityId } }
 
+  const [knownClass] = await getKnownClass(db, where)
+  if (!knownClass) return
+
   // TODO: change setProperties method signature to accecpt SubstrateExtrinsic, then remove the following
   // line. The reason we push the same arg is beacuse of the setProperties method check the 3rd indices
   // to get properties values
   extrinsic.args.push(newPropertyValues)
 
-  switch (cls.name) {
+  switch (knownClass.name) {
     case ContentDirectoryKnownClasses.CHANNEL:
       updateChannelEntityPropertyValues(db, where, decode.setProperties<IChannel>(event, channelPropertyNamesWithId), 0)
       break
@@ -406,7 +384,7 @@ async function contentDirectory_EntityPropertyValuesUpdated(db: DB, event: Subst
       break
 
     default:
-      throw new Error(`Unknown class name: ${cls.name}`)
+      throw new Error(`Unknown class name: ${knownClass.name}`)
   }
 }
 

+ 21 - 13
query-node/mappings/content-directory/entity/remove.ts

@@ -1,4 +1,5 @@
 import assert from 'assert'
+import Debug from 'debug'
 
 import { DB } from '../../../generated/indexer'
 import { Channel } from '../../../generated/graphql-server/src/modules/channel/channel.model'
@@ -17,63 +18,70 @@ import { FeaturedVideo } from '../../../generated/graphql-server/src/modules/fea
 
 import { IWhereCond } from '../../types'
 
+const debug = Debug(`mappings:remove-entity`)
+
 function assertKeyViolation(entityName: string, entityId: string) {
   assert(false, `Can not remove ${entityName}(${entityId})! There are references to this entity`)
 }
 
+function logEntityNotFound(className: string, where: IWhereCond) {
+  debug(`${className}(${where.where.id}) not found. This happen when schema support is not added for the entity.`)
+}
+
 async function removeChannel(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Channel, where)
-  if (!record) throw Error(`Channel(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`Channel`, where)
   if (record.videos && record.videos.length) assertKeyViolation(`Channel`, record.id)
   await db.remove<Channel>(record)
 }
 
 async function removeCategory(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Category, where)
-  if (!record) throw Error(`Category(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`Category`, where)
   if (record.videos && record.videos.length) assertKeyViolation(`Category`, record.id)
   await db.remove<Category>(record)
 }
 async function removeVideoMedia(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(VideoMedia, where)
-  if (!record) throw Error(`VideoMedia(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`VideoMedia`, where)
   if (record.video) assertKeyViolation(`VideoMedia`, record.id)
   await db.remove<VideoMedia>(record)
 }
+
 async function removeVideo(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Video, where)
-  if (!record) throw Error(`Video(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`Video`, where)
   await db.remove<Video>(record)
 }
 
 async function removeLicense(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(LicenseEntity, where)
-  if (!record) throw Error(`License(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`License`, where)
   if (record.videolicense && record.videolicense.length) assertKeyViolation(`License`, record.id)
   await db.remove<LicenseEntity>(record)
 }
 
 async function removeUserDefinedLicense(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(UserDefinedLicenseEntity, where)
-  if (!record) throw Error(`UserDefinedLicense(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`UserDefinedLicense`, where)
   await db.remove<UserDefinedLicenseEntity>(record)
 }
 
 async function removeKnownLicense(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(KnownLicenseEntity, where)
-  if (!record) throw Error(`KnownLicense(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`KnownLicense`, where)
   await db.remove<KnownLicenseEntity>(record)
 }
 async function removeMediaLocation(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(MediaLocationEntity, where)
-  if (!record) throw Error(`MediaLocation(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`MediaLocation`, where)
   if (record.videoMedia) assertKeyViolation('MediaLocation', record.id)
   await db.remove<MediaLocationEntity>(record)
 }
 
 async function removeHttpMediaLocation(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(HttpMediaLocationEntity, where)
-  if (!record) throw Error(`HttpMediaLocation(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`HttpMediaLocation`, where)
   if (record.medialocationentityhttpMediaLocation && record.medialocationentityhttpMediaLocation.length) {
     assertKeyViolation('HttpMediaLocation', record.id)
   }
@@ -82,7 +90,7 @@ async function removeHttpMediaLocation(db: DB, where: IWhereCond): Promise<void>
 
 async function removeJoystreamMediaLocation(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(JoystreamMediaLocationEntity, where)
-  if (!record) throw Error(`JoystreamMediaLocation(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`JoystreamMediaLocation`, where)
   if (record.medialocationentityjoystreamMediaLocation && record.medialocationentityjoystreamMediaLocation.length) {
     assertKeyViolation('JoystreamMediaLocation', record.id)
   }
@@ -91,7 +99,7 @@ async function removeJoystreamMediaLocation(db: DB, where: IWhereCond): Promise<
 
 async function removeLanguage(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Language, where)
-  if (!record) throw Error(`Language(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`Language`, where)
   if (record.channellanguage && record.channellanguage.length) assertKeyViolation('Language', record.id)
   if (record.videolanguage && record.videolanguage.length) assertKeyViolation('Language', record.id)
   await db.remove<Language>(record)
@@ -99,13 +107,13 @@ async function removeLanguage(db: DB, where: IWhereCond): Promise<void> {
 
 async function removeVideoMediaEncoding(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(VideoMediaEncoding, where)
-  if (!record) throw Error(`VideoMediaEncoding(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`VideoMediaEncoding`, where)
   await db.remove<VideoMediaEncoding>(record)
 }
 
 async function removeFeaturedVideo(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(FeaturedVideo, { ...where, relations: ['video'] })
-  if (!record) throw Error(`FeaturedVideo(${where.where.id}) not found`)
+  if (!record) return logEntityNotFound(`FeaturedVideo`, where)
 
   record.video.isFeatured = false
   record.video.featured = undefined

+ 15 - 0
query-node/mappings/content-directory/get-or-create.ts

@@ -11,11 +11,13 @@ import { LicenseEntity } from '../../generated/graphql-server/src/modules/licens
 import { MediaLocationEntity } from '../../generated/graphql-server/src/modules/media-location-entity/media-location-entity.model'
 import { Video } from '../../generated/graphql-server/src/modules/video/video.model'
 import { NextEntityId } from '../../generated/graphql-server/src/modules/next-entity-id/next-entity-id.model'
+import { ClassEntity } from '../../generated/graphql-server/src/modules/class-entity/class-entity.model'
 
 import { decode } from './decode'
 import {
   categoryPropertyNamesWithId,
   channelPropertyNamesWithId,
+  contentDirectoryClassNamesWithId,
   httpMediaLocationPropertyNamesWithId,
   joystreamMediaLocationPropertyNamesWithId,
   knownLicensePropertyNamesWIthId,
@@ -34,6 +36,7 @@ import {
   IEntity,
   IHttpMediaLocation,
   IJoystreamMediaLocation,
+  IKnownClass,
   IKnownLicense,
   ILanguage,
   ILicense,
@@ -43,6 +46,7 @@ import {
   IVideo,
   IVideoMedia,
   IVideoMediaEncoding,
+  IWhereCond,
 } from '../types'
 
 import {
@@ -423,6 +427,17 @@ async function video(
   )
 }
 
+export async function getKnownClass(db: DB, where: IWhereCond): Promise<[IKnownClass | undefined, ClassEntity]> {
+  const ce = await db.get(ClassEntity, where)
+  if (!ce) {
+    throw Error(`Class not found for the EntityId: ${where.where.id} or the entity has not been created.`)
+  }
+
+  const knownClass = contentDirectoryClassNamesWithId.find((c) => c.classId === ce.classId)
+  if (!knownClass) console.log('Unknown class')
+  return [knownClass, ce]
+}
+
 export const getOrCreate = {
   language,
   videoMediaEncoding,

+ 5 - 0
query-node/mappings/types.ts

@@ -202,3 +202,8 @@ export type ClassEntityMap = Map<string, IEntity[]>
 export interface IFeaturedVideo {
   video?: IReference
 }
+
+export interface IKnownClass {
+  name: string
+  classId: number
+}