mirror of
https://github.com/cerc-io/watcher-ts
synced 2026-09-08 00:44:06 +00:00
Handle type and field name conflicts for eden-watcher subgraph entities (#50)
* Rename Block, Transaction types and add block query in eden-watcher schema * Handle field name conflicts in eden subgraph entities * Resolve entity field name conflicts while sending data for auto-diff
This commit is contained in:
@@ -83,7 +83,7 @@ export class Database {
|
||||
const entityValuePromises = entityFields.filter(field => {
|
||||
const { propertyName } = field;
|
||||
|
||||
// TODO: Will clash if entity has blockHash and blockNumber fields.
|
||||
// Filter out blockHash and blockNumber from entity fields to fill the entityInstance (wasm).
|
||||
if (propertyName === 'blockHash' || propertyName === 'blockNumber') {
|
||||
return false;
|
||||
}
|
||||
@@ -92,6 +92,11 @@ export class Database {
|
||||
}).map(async (field) => {
|
||||
const { type, propertyName } = field;
|
||||
|
||||
// Fill _blockNumber as blockNumber and _blockHash as blockHash in the entityInstance (wasm).
|
||||
if (['_blockNumber', '_blockHash'].includes(propertyName)) {
|
||||
return toEntityValue(instanceExports, entityInstance, data, type.toString(), propertyName.slice(1));
|
||||
}
|
||||
|
||||
return toEntityValue(instanceExports, entityInstance, data, type.toString(), propertyName);
|
||||
}, {});
|
||||
|
||||
@@ -112,15 +117,21 @@ export class Database {
|
||||
const entityValuePromises = entityFields.map(async (field: any) => {
|
||||
const { type, propertyName } = field;
|
||||
|
||||
// TODO: Will clash if entity has blockHash and blockNumber fields.
|
||||
// Get blockHash property for db entry from block instance.
|
||||
if (propertyName === 'blockHash') {
|
||||
return block.blockHash;
|
||||
}
|
||||
|
||||
// Get blockNumber property for db entry from block instance.
|
||||
if (propertyName === 'blockNumber') {
|
||||
return block.blockNumber;
|
||||
}
|
||||
|
||||
// Get blockNumber as _blockNumber and blockHash as _blockHash from the entityInstance (wasm).
|
||||
if (['_blockNumber', '_blockHash'].includes(propertyName)) {
|
||||
return fromEntityValue(instanceExports, entityInstance, type.toString(), propertyName.slice(1));
|
||||
}
|
||||
|
||||
return fromEntityValue(instanceExports, entityInstance, type.toString(), propertyName);
|
||||
}, {});
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import JSONbig from 'json-bigint';
|
||||
import { IndexerInterface } from '@vulcanize/util';
|
||||
|
||||
import { TypeId } from './types';
|
||||
import { Block, fromEthereumValue, toEthereumValue } from './utils';
|
||||
import { Block, fromEthereumValue, toEthereumValue, resolveEntityFieldConflicts } from './utils';
|
||||
import { Database } from './database';
|
||||
|
||||
const NETWORK_URL = 'http://127.0.0.1:8081';
|
||||
@@ -66,15 +66,15 @@ export const instantiate = async (database: Database, indexer: IndexerInterface,
|
||||
const entityInstance = await Entity.wrap(data);
|
||||
|
||||
assert(context.event.block);
|
||||
const dbData = await database.fromGraphEntity(exports, context.event.block, entityName, entityInstance);
|
||||
let dbData = await database.fromGraphEntity(exports, context.event.block, entityName, entityInstance);
|
||||
await database.saveEntity(entityName, dbData);
|
||||
|
||||
// Remove blockNumber and blockHash from dbData for auto-diff.
|
||||
delete dbData.blockNumber;
|
||||
delete dbData.blockHash;
|
||||
// Resolve any field name conflicts in the dbData for auto-diff.
|
||||
dbData = resolveEntityFieldConflicts(dbData);
|
||||
|
||||
// Prepare the diff data.
|
||||
const diffData: any = { state: {} };
|
||||
|
||||
// JSON stringify and parse data for handling unknown types when encoding.
|
||||
// For example, decimal.js values are converted to string in the diff data.
|
||||
diffData.state[entityName] = JSONbig.parse(JSONbig.stringify(dbData));
|
||||
|
||||
@@ -396,3 +396,25 @@ export const fromEntityValue = async (instanceExports: any, entityInstance: any,
|
||||
throw new Error(`Unsupported type: ${type}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const resolveEntityFieldConflicts = (entity: any): any => {
|
||||
if (entity) {
|
||||
// Remove fields blockHash and blockNumber from the entity.
|
||||
delete entity.blockHash;
|
||||
delete entity.blockNumber;
|
||||
|
||||
// Rename _blockHash -> blockHash.
|
||||
if ('_blockHash' in entity) {
|
||||
entity.blockHash = entity._blockHash;
|
||||
delete entity._blockHash;
|
||||
}
|
||||
|
||||
// Rename _blockNumber -> blockNumber.
|
||||
if ('_blockNumber' in entity) {
|
||||
entity.blockNumber = entity._blockNumber;
|
||||
delete entity._blockNumber;
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ import { ResultObject } from '@vulcanize/assemblyscript/lib/loader';
|
||||
import { EthClient } from '@vulcanize/ipld-eth-client';
|
||||
import { IndexerInterface } from '@vulcanize/util';
|
||||
|
||||
import { createBlock, createEvent, getSubgraphConfig } from './utils';
|
||||
import { createBlock, createEvent, getSubgraphConfig, resolveEntityFieldConflicts } from './utils';
|
||||
import { Context, instantiate } from './loader';
|
||||
import { Database } from './database';
|
||||
|
||||
@@ -183,7 +183,11 @@ export class GraphWatcher {
|
||||
this._indexer = indexer;
|
||||
}
|
||||
|
||||
async getEntity<Entity> (entity: new () => Entity, id: string, blockHash: string): Promise<Entity | undefined> {
|
||||
return this._database.getEntity(entity, id, blockHash);
|
||||
async getEntity<Entity> (entity: new () => Entity, id: string, blockHash: string): Promise<any> {
|
||||
// Get entity from the database.
|
||||
const result = await this._database.getEntity(entity, id, blockHash) as any;
|
||||
|
||||
// Resolve any field name conflicts in the entity result.
|
||||
return resolveEntityFieldConflicts(result);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user