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:
prathamesh0
2021-12-28 16:08:05 +05:30
committed by nabarun
parent fd86b4d5e3
commit 158c3928c9
9 changed files with 103 additions and 37 deletions
+13 -2
View File
@@ -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);
}, {});
+5 -5
View File
@@ -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));
+22
View File
@@ -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;
};
+7 -3
View File
@@ -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);
}
}