mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-01-26 04:50:35 +00:00
188 lines
6.9 KiB
TypeScript
188 lines
6.9 KiB
TypeScript
//
|
|
// Copyright 2021 Vulcanize, Inc.
|
|
//
|
|
|
|
import assert from 'assert';
|
|
import { Connection, ConnectionOptions, DeepPartial, FindConditions, FindManyOptions, QueryRunner } from 'typeorm';
|
|
import path from 'path';
|
|
|
|
import { Database as BaseDatabase } from '@vulcanize/util';
|
|
|
|
import { Allowance } from './entity/Allowance';
|
|
import { Balance } from './entity/Balance';
|
|
import { Contract } from './entity/Contract';
|
|
import { Event } from './entity/Event';
|
|
import { SyncStatus } from './entity/SyncStatus';
|
|
import { BlockProgress } from './entity/BlockProgress';
|
|
|
|
const CONTRACT_KIND = 'token';
|
|
|
|
export class Database {
|
|
_config: ConnectionOptions
|
|
_conn!: Connection
|
|
_baseDatabase: BaseDatabase;
|
|
|
|
constructor (config: ConnectionOptions) {
|
|
assert(config);
|
|
|
|
this._config = {
|
|
...config,
|
|
entities: [path.join(__dirname, 'entity/*')]
|
|
};
|
|
|
|
this._baseDatabase = new BaseDatabase(this._config);
|
|
}
|
|
|
|
async init (): Promise<void> {
|
|
this._conn = await this._baseDatabase.init();
|
|
}
|
|
|
|
async close (): Promise<void> {
|
|
return this._baseDatabase.close();
|
|
}
|
|
|
|
async getBalance ({ blockHash, token, owner }: { blockHash: string, token: string, owner: string }): Promise<Balance | undefined> {
|
|
return this._conn.getRepository(Balance)
|
|
.createQueryBuilder('balance')
|
|
.where('block_hash = :blockHash AND token = :token AND owner = :owner', {
|
|
blockHash,
|
|
token,
|
|
owner
|
|
})
|
|
.getOne();
|
|
}
|
|
|
|
async getAllowance ({ blockHash, token, owner, spender }: { blockHash: string, token: string, owner: string, spender: string }): Promise<Allowance | undefined> {
|
|
return this._conn.getRepository(Allowance)
|
|
.createQueryBuilder('allowance')
|
|
.where('block_hash = :blockHash AND token = :token AND owner = :owner AND spender = :spender', {
|
|
blockHash,
|
|
token,
|
|
owner,
|
|
spender
|
|
})
|
|
.getOne();
|
|
}
|
|
|
|
async saveBalance ({ blockHash, blockNumber, token, owner, value, proof }: DeepPartial<Balance>): Promise<Balance> {
|
|
const repo = this._conn.getRepository(Balance);
|
|
const entity = repo.create({ blockHash, blockNumber, token, owner, value, proof });
|
|
return repo.save(entity);
|
|
}
|
|
|
|
async saveAllowance ({ blockHash, blockNumber, token, owner, spender, value, proof }: DeepPartial<Allowance>): Promise<Allowance> {
|
|
const repo = this._conn.getRepository(Allowance);
|
|
const entity = repo.create({ blockHash, blockNumber, token, owner, spender, value, proof });
|
|
return repo.save(entity);
|
|
}
|
|
|
|
async getContract (address: string): Promise<Contract | undefined> {
|
|
const repo = this._conn.getRepository(Contract);
|
|
|
|
return this._baseDatabase.getContract(repo, address);
|
|
}
|
|
|
|
async createTransactionRunner (): Promise<QueryRunner> {
|
|
return this._baseDatabase.createTransactionRunner();
|
|
}
|
|
|
|
async getProcessedBlockCountForRange (fromBlockNumber: number, toBlockNumber: number): Promise<{ expected: number, actual: number }> {
|
|
const repo = this._conn.getRepository(BlockProgress);
|
|
|
|
return this._baseDatabase.getProcessedBlockCountForRange(repo, fromBlockNumber, toBlockNumber);
|
|
}
|
|
|
|
async getEventsInRange (fromBlockNumber: number, toBlockNumber: number): Promise<Array<Event>> {
|
|
const repo = this._conn.getRepository(Event);
|
|
|
|
return this._baseDatabase.getEventsInRange(repo, fromBlockNumber, toBlockNumber);
|
|
}
|
|
|
|
async saveEventEntity (queryRunner: QueryRunner, entity: Event): Promise<Event> {
|
|
const repo = queryRunner.manager.getRepository(Event);
|
|
return this._baseDatabase.saveEventEntity(repo, entity);
|
|
}
|
|
|
|
async getBlockEvents (blockHash: string, where: FindConditions<Event>): Promise<Event[]> {
|
|
const repo = this._conn.getRepository(Event);
|
|
|
|
return this._baseDatabase.getBlockEvents(repo, blockHash, where);
|
|
}
|
|
|
|
async saveEvents (queryRunner: QueryRunner, block: DeepPartial<BlockProgress>, events: DeepPartial<Event>[]): Promise<void> {
|
|
const blockRepo = queryRunner.manager.getRepository(BlockProgress);
|
|
const eventRepo = queryRunner.manager.getRepository(Event);
|
|
|
|
return this._baseDatabase.saveEvents(blockRepo, eventRepo, block, events);
|
|
}
|
|
|
|
async saveContract (address: string, startingBlock: number): Promise<void> {
|
|
await this._conn.transaction(async (tx) => {
|
|
const repo = tx.getRepository(Contract);
|
|
|
|
return this._baseDatabase.saveContract(repo, address, startingBlock, CONTRACT_KIND);
|
|
});
|
|
}
|
|
|
|
async updateSyncStatusIndexedBlock (queryRunner: QueryRunner, blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
|
const repo = queryRunner.manager.getRepository(SyncStatus);
|
|
|
|
return this._baseDatabase.updateSyncStatusIndexedBlock(repo, blockHash, blockNumber, force);
|
|
}
|
|
|
|
async updateSyncStatusCanonicalBlock (queryRunner: QueryRunner, blockHash: string, blockNumber: number, force = false): Promise<SyncStatus> {
|
|
const repo = queryRunner.manager.getRepository(SyncStatus);
|
|
|
|
return this._baseDatabase.updateSyncStatusCanonicalBlock(repo, blockHash, blockNumber, force);
|
|
}
|
|
|
|
async updateSyncStatusChainHead (queryRunner: QueryRunner, blockHash: string, blockNumber: number): Promise<SyncStatus> {
|
|
const repo = queryRunner.manager.getRepository(SyncStatus);
|
|
|
|
return this._baseDatabase.updateSyncStatusChainHead(repo, blockHash, blockNumber);
|
|
}
|
|
|
|
async getSyncStatus (queryRunner: QueryRunner): Promise<SyncStatus | undefined> {
|
|
const repo = queryRunner.manager.getRepository(SyncStatus);
|
|
|
|
return this._baseDatabase.getSyncStatus(repo);
|
|
}
|
|
|
|
async getEvent (id: string): Promise<Event | undefined> {
|
|
const repo = this._conn.getRepository(Event);
|
|
|
|
return this._baseDatabase.getEvent(repo, id);
|
|
}
|
|
|
|
async getBlocksAtHeight (height: number, isPruned: boolean): Promise<BlockProgress[]> {
|
|
const repo = this._conn.getRepository(BlockProgress);
|
|
|
|
return this._baseDatabase.getBlocksAtHeight(repo, height, isPruned);
|
|
}
|
|
|
|
async markBlocksAsPruned (queryRunner: QueryRunner, blocks: BlockProgress[]): Promise<void> {
|
|
const repo = queryRunner.manager.getRepository(BlockProgress);
|
|
|
|
return this._baseDatabase.markBlocksAsPruned(repo, blocks);
|
|
}
|
|
|
|
async getBlockProgress (blockHash: string): Promise<BlockProgress | undefined> {
|
|
const repo = this._conn.getRepository(BlockProgress);
|
|
return this._baseDatabase.getBlockProgress(repo, blockHash);
|
|
}
|
|
|
|
async updateBlockProgress (queryRunner: QueryRunner, blockHash: string, lastProcessedEventIndex: number): Promise<void> {
|
|
const repo = queryRunner.manager.getRepository(BlockProgress);
|
|
|
|
return this._baseDatabase.updateBlockProgress(repo, blockHash, lastProcessedEventIndex);
|
|
}
|
|
|
|
async removeEntities<Entity> (queryRunner: QueryRunner, entity: new () => Entity, findConditions?: FindManyOptions<Entity> | FindConditions<Entity>): Promise<void> {
|
|
return this._baseDatabase.removeEntities(queryRunner, entity, findConditions);
|
|
}
|
|
|
|
async getAncestorAtDepth (blockHash: string, depth: number): Promise<string> {
|
|
return this._baseDatabase.getAncestorAtDepth(blockHash, depth);
|
|
}
|
|
}
|