Skip to content

Commit

Permalink
Implement block filter for plural queries on subgraph entities (#444)
Browse files Browse the repository at this point in the history
* Fix bigint values transformation

* Fix starts and ends filter operator resolution

* Support case insensitive filters for string fields

* Add support for global filter _change_block

* Handle _change_block filter in all query types
  • Loading branch information
prathamesh0 authored Nov 1, 2023
1 parent 6c17662 commit 1b6ca6e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 6 deletions.
19 changes: 18 additions & 1 deletion packages/graph-node/src/watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import {
getSubgraphConfig,
Transaction,
EthClient,
DEFAULT_LIMIT
DEFAULT_LIMIT,
FILTER_CHANGE_BLOCK
} from '@cerc-io/util';

import { Context, GraphData, instantiate } from './loader';
Expand Down Expand Up @@ -322,6 +323,17 @@ export class GraphWatcher {

try {
where = Object.entries(where).reduce((acc: { [key: string]: any }, [fieldWithSuffix, value]) => {
if (fieldWithSuffix === FILTER_CHANGE_BLOCK) {
assert(value.number_gte && typeof value.number_gte === 'number');

// Maintain util.Where type
acc[FILTER_CHANGE_BLOCK] = [{
value: value.number_gte
}];

return acc;
}

const [field, ...suffix] = fieldWithSuffix.split('_');

if (!acc[field]) {
Expand All @@ -345,6 +357,11 @@ export class GraphWatcher {
filter.operator = operator;
}

// If filter field ends with "nocase", use case insensitive version of the operator
if (suffix[suffix.length - 1] === 'nocase') {
filter.operator = `${operator}_nocase`;
}

acc[field].push(filter);

return acc;
Expand Down
16 changes: 11 additions & 5 deletions packages/util/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ export const OPERATOR_MAP = {
in: 'IN',
contains: 'LIKE',
starts: 'LIKE',
ends: 'LIKE'
ends: 'LIKE',
contains_nocase: 'ILIKE',
starts_nocase: 'ILIKE',
ends_nocase: 'ILIKE'
};

const INSERT_EVENTS_BATCH = 100;
Expand Down Expand Up @@ -875,11 +878,11 @@ export class Database {
}
}

if (['contains', 'starts'].some(el => el === operator)) {
if (['contains', 'contains_nocase', 'ends', 'ends_nocase'].some(el => el === operator)) {
value = `%${value}`;
}

if (['contains', 'ends'].some(el => el === operator)) {
if (['contains', 'contains_nocase', 'starts', 'starts_nocase'].some(el => el === operator)) {
value += '%';
}

Expand Down Expand Up @@ -927,19 +930,22 @@ export class Database {
eventCount.set(res);
}

// TODO: Transform in the GQL type BigInt parsing itself
_transformBigIntValues (value: any): any {
// Handle array of bigints
if (Array.isArray(value)) {
if (value.length > 0 && typeof value[0] === 'bigint') {
return value.map(val => {
return val.toString();
});
}

return value;
}

// Handle bigint
if (typeof value === 'bigint') {
return value.toString();
}

return value;
}
}
32 changes: 32 additions & 0 deletions packages/util/src/graph/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import { fromStateEntityValues } from './state-utils';

const log = debug('vulcanize:graph-database');

export const FILTER_CHANGE_BLOCK = '_change_block';

export const DEFAULT_LIMIT = 100;
const DEFAULT_CLEAR_ENTITIES_CACHE_INTERVAL = 1000;

Expand Down Expand Up @@ -433,6 +435,11 @@ export class GraphDatabase {
delete where.id;
}

if (where[FILTER_CHANGE_BLOCK]) {
subQuery = subQuery.andWhere('subTable.block_number >= :changeBlockNumber', { changeBlockNumber: where[FILTER_CHANGE_BLOCK][0].value });
delete where[FILTER_CHANGE_BLOCK];
}

if (block.hash) {
const { canonicalBlockNumber, blockHashes } = await this._baseDatabase.getFrothyRegion(queryRunner, block.hash);

Expand Down Expand Up @@ -496,6 +503,11 @@ export class GraphDatabase {
delete where.id;
}

if (where[FILTER_CHANGE_BLOCK]) {
subQuery = subQuery.andWhere('subTable.block_number >= :changeBlockNumber', { changeBlockNumber: where[FILTER_CHANGE_BLOCK][0].value });
delete where[FILTER_CHANGE_BLOCK];
}

if (block.hash) {
const { canonicalBlockNumber, blockHashes } = await this._baseDatabase.getFrothyRegion(queryRunner, block.hash);

Expand Down Expand Up @@ -554,6 +566,11 @@ export class GraphDatabase {
.addOrderBy(`${tableName}.block_number`, 'DESC')
.limit(1);

if (where[FILTER_CHANGE_BLOCK]) {
selectQueryBuilder = selectQueryBuilder.andWhere(`${tableName}.block_number >= :changeBlockNumber`, { changeBlockNumber: where[FILTER_CHANGE_BLOCK][0].value });
delete where[FILTER_CHANGE_BLOCK];
}

if (block.hash) {
const { canonicalBlockNumber, blockHashes } = await this._baseDatabase.getFrothyRegion(queryRunner, block.hash);

Expand Down Expand Up @@ -588,6 +605,11 @@ export class GraphDatabase {
let selectQueryBuilder = repo.createQueryBuilder(tableName)
.where('is_pruned = :isPruned', { isPruned: false });

if (where[FILTER_CHANGE_BLOCK]) {
selectQueryBuilder = selectQueryBuilder.andWhere(`${tableName}.block_number >= :changeBlockNumber`, { changeBlockNumber: where[FILTER_CHANGE_BLOCK][0].value });
delete where[FILTER_CHANGE_BLOCK];
}

if (block.hash) {
const { canonicalBlockNumber, blockHashes } = await this._baseDatabase.getFrothyRegion(queryRunner, block.hash);

Expand Down Expand Up @@ -658,6 +680,11 @@ export class GraphDatabase {
);
}

if (where[FILTER_CHANGE_BLOCK]) {
selectQueryBuilder = selectQueryBuilder.andWhere('latest.block_number >= :changeBlockNumber', { changeBlockNumber: where[FILTER_CHANGE_BLOCK][0].value });
delete where[FILTER_CHANGE_BLOCK];
}

selectQueryBuilder = this._baseDatabase.buildQuery(repo, selectQueryBuilder, where, 'latest');

if (queryOptions.orderBy) {
Expand Down Expand Up @@ -694,6 +721,11 @@ export class GraphDatabase {
.orderBy('subTable.block_number', 'DESC')
.limit(1);

if (where[FILTER_CHANGE_BLOCK]) {
subQuery = subQuery.andWhere('subTable.block_number >= :changeBlockNumber', { changeBlockNumber: where[FILTER_CHANGE_BLOCK][0].value });
delete where[FILTER_CHANGE_BLOCK];
}

if (block.hash) {
const { canonicalBlockNumber, blockHashes } = await this._baseDatabase.getFrothyRegion(queryRunner, block.hash);

Expand Down

0 comments on commit 1b6ca6e

Please sign in to comment.