Skip to content

Commit

Permalink
feat: add totalResultCount to StakePoolSearch response
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan Cruz committed May 13, 2022
1 parent 9adff62 commit 4265f6a
Show file tree
Hide file tree
Showing 17 changed files with 8,311 additions and 8,112 deletions.
2 changes: 1 addition & 1 deletion packages/cardano-services/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"cleanup": "shx rm -rf dist node_modules",
"lint": "eslint --ignore-path ../../.eslintignore \"**/*.ts\"",
"lint:fix": "eslint --fix --ignore-path ../../.eslintignore \"**/*.ts\"",
"test": "jest -c ./jest.config.js -t stakepool",
"test": "jest -c ./jest.config.js",
"test:e2e": "shx echo 'test:e2e' command not implemented yet",
"coverage": "yarn test --coverage",
"prepack": "yarn build",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable sonarjs/no-nested-template-literals */
import { Cardano, StakePoolQueryOptions, StakePoolSearchProvider, util } from '@cardano-sdk/core';
import { DbSyncProvider } from '../../DbSyncProvider';
import { Logger, dummyLogger } from 'ts-log';
import { Pool } from 'pg';
import { StakePoolQueryOptions, StakePoolSearchProvider, StakePoolSearchResults, util } from '@cardano-sdk/core';
import { StakePoolSearchBuilder } from './StakePoolSearchBuilder';
import { toCoreStakePool } from './mappers';

Expand All @@ -16,7 +16,7 @@ export class DbSyncStakePoolSearchProvider extends DbSyncProvider implements Sta
this.#logger = logger;
}

public async queryStakePools(options?: StakePoolQueryOptions): Promise<Cardano.StakePool[]> {
public async queryStakePools(options?: StakePoolQueryOptions): Promise<StakePoolSearchResults> {
const { params, query } =
options?.filters?._condition === 'or'
? this.#builder.buildOrQuery(options?.filters)
Expand All @@ -27,17 +27,27 @@ export class DbSyncStakePoolSearchProvider extends DbSyncProvider implements Sta
this.#logger.debug(`${hashesIds.length} pools found`);
const updatesIds = poolUpdates.map(({ updateId }) => updateId);
const totalAdaAmount = await this.#builder.getTotalAmountOfAda();
const [poolDatas, poolRelays, poolOwners, poolRegistrations, poolRetirements, poolRewards, lastEpoch, poolMetrics] =
await Promise.all([
this.#builder.queryPoolData(updatesIds),
this.#builder.queryPoolRelays(updatesIds),
this.#builder.queryPoolOwners(updatesIds),
this.#builder.queryRegistrations(hashesIds),
this.#builder.queryRetirements(hashesIds),
this.#builder.queryPoolRewards(hashesIds, options?.rewardsHistoryLimit),
this.#builder.getLastEpoch(),
this.#builder.queryPoolMetrics(hashesIds, totalAdaAmount)
]);
const [
poolDatas,
poolRelays,
poolOwners,
poolRegistrations,
poolRetirements,
poolRewards,
lastEpoch,
poolMetrics,
totalCount
] = await Promise.all([
this.#builder.queryPoolData(updatesIds),
this.#builder.queryPoolRelays(updatesIds),
this.#builder.queryPoolOwners(updatesIds),
this.#builder.queryRegistrations(hashesIds),
this.#builder.queryRetirements(hashesIds),
this.#builder.queryPoolRewards(hashesIds, options?.rewardsHistoryLimit),
this.#builder.getLastEpoch(),
this.#builder.queryPoolMetrics(hashesIds, totalAdaAmount),
this.#builder.queryTotalCount(query, params)
]);
return toCoreStakePool({
lastEpoch,
poolDatas,
Expand All @@ -46,7 +56,8 @@ export class DbSyncStakePoolSearchProvider extends DbSyncProvider implements Sta
poolRegistrations,
poolRelays,
poolRetirements,
poolRewards: poolRewards.filter(util.isNotNil)
poolRewards: poolRewards.filter(util.isNotNil),
totalCount
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
PoolUpdateModel,
RelayModel,
SubQuery,
TotalAdaModel
TotalAdaModel,
TotalCountModel
} from './types';
import { Logger, dummyLogger } from 'ts-log';
import { Pool, QueryResult } from 'pg';
Expand All @@ -32,6 +33,7 @@ import Queries, {
getIdentifierFullJoinClause,
getIdentifierWhereClause,
getStatusWhereClause,
getTotalCountQueryFromQuery,
poolsByPledgeMetSubqueries,
withPagination
} from './queries';
Expand Down Expand Up @@ -216,4 +218,10 @@ export class StakePoolSearchBuilder {
query = addSentenceToQuery(query, groupByClause);
return { params, query };
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async queryTotalCount(query: string, _params: any[]) {
this.#logger.debug('About to get total count of pools');
const result: QueryResult<TotalCountModel> = await this.#db.query(getTotalCountQueryFromQuery(query), _params);
return result.rows[0].total_count;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Cardano } from '@cardano-sdk/core';
import { Cardano, StakePoolSearchResults } from '@cardano-sdk/core';
import {
EpochReward,
EpochRewardModel,
Expand Down Expand Up @@ -43,6 +43,7 @@ interface ToCoreStakePoolInput {
poolRewards: EpochReward[];
lastEpoch: number;
poolMetrics: PoolMetrics[];
totalCount: number;
}

export const toCoreStakePool = ({
Expand All @@ -53,9 +54,10 @@ export const toCoreStakePool = ({
poolRetirements,
poolRewards,
lastEpoch,
poolMetrics
}: ToCoreStakePoolInput): Cardano.StakePool[] =>
poolDatas.map((poolData) => {
poolMetrics,
totalCount
}: ToCoreStakePoolInput): StakePoolSearchResults => ({
pageResults: poolDatas.map((poolData) => {
const registrations = poolRegistrations.filter((r) => r.hashId === poolData.hashId);
const retirements = poolRetirements.filter((r) => r.hashId === poolData.hashId);
const toReturn: Cardano.StakePool = {
Expand All @@ -80,7 +82,9 @@ export const toCoreStakePool = ({
if (poolData.metadata) toReturn.metadata = poolData.metadata;
if (poolData.metadataJson) toReturn.metadataJson = poolData.metadataJson;
return toReturn;
});
}),
totalResultCount: Number(totalCount)
});

export const mapPoolUpdate = (poolUpdateModel: PoolUpdateModel): PoolUpdate => ({
id: poolUpdateModel.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,12 @@ export const buildOrQueryFromClauses = (clauses: SubQuery[]) => {
`;
};

export const getTotalCountQueryFromQuery = (query: string) => `
SELECT
COUNT(1) AS total_count
FROM (${query}) as query
`;

const Queries = {
IDENTIFIER_QUERY,
POOLS_WITH_PLEDGE_MET,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,7 @@ export interface PoolMetrics {
hashId: number;
metrics: Cardano.StakePoolMetrics;
}

export interface TotalCountModel {
total_count: number;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as OpenApiValidator from 'express-openapi-validator';
import { Cardano, ProviderError, ProviderFailure, StakePoolQueryOptions } from '@cardano-sdk/core';
import { DbSyncStakePoolSearchProvider } from './DbSyncStakePoolSearchProvider';
import { HttpServer, HttpService } from '../Http';
import { Logger, dummyLogger } from 'ts-log';
import { ProviderError, ProviderFailure, StakePoolQueryOptions, StakePoolSearchResults } from '@cardano-sdk/core';
import { ServiceNames } from '../Program';
import { providerHandler } from '../util';
import express from 'express';
Expand Down Expand Up @@ -36,7 +36,7 @@ export class StakePoolSearchHttpService extends HttpService {
// Add initial healthCheck of the provider when implemented
router.post(
'/search',
providerHandler<[StakePoolQueryOptions], Cardano.StakePool[]>(async ([stakePoolOptions], _, res) => {
providerHandler<[StakePoolQueryOptions], StakePoolSearchResults>(async ([stakePoolOptions], _, res) => {
try {
return HttpServer.sendJSON(res, await stakePoolSearchProvider.queryStakePools(stakePoolOptions));
} catch (error) {
Expand Down
21 changes: 15 additions & 6 deletions packages/cardano-services/src/StakePoolSearch/openApi.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SearchStakePoolResponse"
"type": "object",
"properties": {
"pageResults": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SearchStakePool"
}
},
"totalResultCount": {
"type": "number"
}
}

}
}
}
Expand Down Expand Up @@ -76,7 +85,7 @@
}
}
},
"SearchStakePoolResponse": {
"SearchStakePool": {
"required": ["cost", "id", "margin", "owners", "pledge", "relays", "vrf"],
"type": "object",
"properties": {
Expand All @@ -96,7 +105,7 @@
"$ref": "#/components/schemas/Fraction"
},
"metadataJson": {
"$ref": "#/components/schemas/SearchStakePoolResponse_metadataJson"
"$ref": "#/components/schemas/MetadataJson"
},
"relays": {
"type": "array",
Expand Down Expand Up @@ -328,7 +337,7 @@
}
}
},
"SearchStakePoolResponse_metadataJson": {
"MetadataJson": {
"type": "object",
"properties": {
"hash": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,19 +180,25 @@ describe('StakePoolSearchBuilder', () => {
});
});
describe('buildOrQuery', () => {
it('buildOrQuery & queryPoolHashes', async () => {
it('buildOrQuery, queryPoolHashes & queryTotalCount', async () => {
const builtQuery = builder.buildOrQuery(filters);
const poolHashes = await builder.queryPoolHashes(builtQuery.query, builtQuery.params);
const { query, params } = builtQuery;
const poolHashes = await builder.queryPoolHashes(query, params);
const totalCount = await builder.queryTotalCount(query, params);
expect(builtQuery).toMatchSnapshot();
expect(poolHashes).toMatchSnapshot();
expect(totalCount).toMatchSnapshot();
});
});
describe('buildAndQuery', () => {
it('buildAndQuery & queryPoolHashes', async () => {
it('buildAndQuery, queryPoolHashes & queryTotalCount', async () => {
const builtQuery = builder.buildAndQuery(filters);
const poolHashes = await builder.queryPoolHashes(builtQuery.query, builtQuery.params);
const { query, params } = builtQuery;
const poolHashes = await builder.queryPoolHashes(query, params);
const totalCount = await builder.queryTotalCount(query, params);
expect(builtQuery).toMatchSnapshot();
expect(poolHashes).toMatchSnapshot();
expect(totalCount).toMatchSnapshot();
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`StakePoolSearchBuilder buildAndQuery buildAndQuery & queryPoolHashes 1`] = `
exports[`StakePoolSearchBuilder buildAndQuery buildAndQuery, queryPoolHashes & queryTotalCount 1`] = `
Object {
"params": Array [
"%(CL)%",
Expand Down Expand Up @@ -137,7 +137,7 @@ Object {
}
`;

exports[`StakePoolSearchBuilder buildAndQuery buildAndQuery & queryPoolHashes 2`] = `
exports[`StakePoolSearchBuilder buildAndQuery buildAndQuery, queryPoolHashes & queryTotalCount 2`] = `
Array [
Object {
"id": "15",
Expand All @@ -146,7 +146,9 @@ Array [
]
`;

exports[`StakePoolSearchBuilder buildOrQuery buildOrQuery & queryPoolHashes 1`] = `
exports[`StakePoolSearchBuilder buildAndQuery buildAndQuery, queryPoolHashes & queryTotalCount 3`] = `"1"`;

exports[`StakePoolSearchBuilder buildOrQuery buildOrQuery, queryPoolHashes & queryTotalCount 1`] = `
Object {
"params": Array [
"%(CL)%",
Expand Down Expand Up @@ -314,7 +316,7 @@ Object {
}
`;

exports[`StakePoolSearchBuilder buildOrQuery buildOrQuery & queryPoolHashes 2`] = `
exports[`StakePoolSearchBuilder buildOrQuery buildOrQuery, queryPoolHashes & queryTotalCount 2`] = `
Array [
Object {
"id": "2056",
Expand Down Expand Up @@ -351,6 +353,8 @@ Array [
]
`;

exports[`StakePoolSearchBuilder buildOrQuery buildOrQuery, queryPoolHashes & queryTotalCount 3`] = `"8"`;

exports[`StakePoolSearchBuilder buildPoolsByIdentifierQuery buildPoolsByIdentifierQuery 1`] = `
Object {
"id": Object {
Expand Down
Loading

0 comments on commit 4265f6a

Please sign in to comment.