add paging

This commit is contained in:
Don Cote 2022-06-29 11:22:11 -04:00
parent 9e7391b112
commit deb4ee68aa
10 changed files with 76 additions and 9 deletions

View File

@ -84,6 +84,12 @@ type Query = {
// The number of minutes until your query run times out
timeoutMinutes?: number;
// The number of records to return, defaults to 100000
pageSize?: number;
// The page number to return, defaults to 1
pageNumber?: number;
};
```
@ -97,6 +103,8 @@ const query: Query = {
ttlMinutes: 60,
cached: true,
timeoutMinutes: 15,
pageNumber: 1,
pageSize: 10,
};
```
@ -135,6 +143,12 @@ interface QueryResultSet {
// The results of the query transformed as an array of objects
records: QueryResultRecord[] | null;
// The number of records to return
pageSize: number;
// The page number to return
pageNumber: number;
// If the query failed, this will contain the error
error:
| QueryRunRateLimitError
@ -154,10 +168,12 @@ Our query selected `nft_address`, `mint_price_eth`, and `mint_price_usd`. We can
```typescript
result.records.map((record) => {
const nftAddress = record.nft_address
const mintPriceEth = record.mint_price_eth
const mintPriceUSD = = record.mint_price_usd
console.log(`address ${nftAddress} minted at a price of ${mintPrice} ETH or $${mintPriceUSD} USD`);
const nftAddress = record.nft_address;
const mintPriceEth = record.mint_price_eth;
const mintPriceUSD = record.mint_price_usd;
console.log(
`address ${nftAddress} minted at a price of ${mintPriceEth} ETH or $${mintPriceUSD} USD`
);
});
```

View File

@ -64,10 +64,11 @@ export class API implements ApiClient {
};
}
async getQueryResult(queryID: string): Promise<QueryResultResp> {
async getQueryResult(queryID: string, pageNumber: number, pageSize: number): Promise<QueryResultResp> {
let result;
try {
result = await axios.get(this.getUrl(`queries/${queryID}`), {
params: { pageNumber: pageNumber, pageSize: pageSize },
method: "GET",
headers: this.#headers,
});

View File

@ -28,6 +28,8 @@ const DEFAULTS: QueryDefaults = {
cached: true,
timeoutMinutes: 20,
retryIntervalSeconds: 0.5,
pageSize: 100000,
pageNumber: 1,
};
export class QueryIntegration {
@ -64,7 +66,9 @@ export class QueryIntegration {
}
const [getQueryResultJson, getQueryErr] = await this.#getQueryResult(
createQueryJson.token
createQueryJson.token,
query.pageNumber || 1,
query.pageSize || 100000,
);
if (getQueryErr) {
@ -74,6 +78,7 @@ export class QueryIntegration {
});
}
if (!getQueryResultJson) {
return new QueryResultSetBuilder({
queryResultJson: null,
@ -132,6 +137,8 @@ export class QueryIntegration {
async #getQueryResult(
queryID: string,
pageNumber: number,
pageSize: number,
attempts: number = 0
): Promise<
[
@ -139,7 +146,7 @@ export class QueryIntegration {
QueryRunTimeoutError | ServerError | UserError | null
]
> {
const resp = await this.#api.getQueryResult(queryID);
const resp = await this.#api.getQueryResult(queryID, pageNumber, pageSize);
if (resp.statusCode > 299) {
if (resp.statusCode >= 400 && resp.statusCode <= 499) {
let errorMsg = resp.statusMsg || "user input error";
@ -183,6 +190,6 @@ export class QueryIntegration {
return [null, new QueryRunTimeoutError(elapsedSeconds * 60)];
}
return this.#getQueryResult(queryID, attempts + 1);
return this.#getQueryResult(queryID, pageNumber, pageSize, attempts + 1);
}
}

View File

@ -0,0 +1,27 @@
import { Flipside } from "../flipside";
import { Query, QueryResultSet } from "../types";
const runIt = async (): Promise<void> => {
// Initialize `Flipside` with your API key
const flipside = new Flipside(
"api-key-here",
"https://api.flipsidecrypto.com",
);
// Create a query object for the `query.run` function to execute
const query: Query = {
sql: "select nft_address, mint_price_eth, mint_price_usd from flipside_prod_db.ethereum_core.ez_nft_mints limit 100",
ttlMinutes: 10,
pageSize: 100,
pageNumber: 1
};
// Send the `Query` to Flipside's query engine and await the results
const result: QueryResultSet = await flipside.query.run(query);
if (!result || !result.records) throw "null result";
console.log(result);
};
runIt();

View File

@ -58,6 +58,8 @@ function generateQueryResultData(status: QueryStatus) {
columnTypes: ["string", "string"],
message: "",
errors: "invalid sql",
pageNumber: 1,
pageSize: 100,
};
}
@ -173,6 +175,8 @@ describe("run: timeout_error", () => {
cached: false,
timeoutMinutes: 0.01,
retryIntervalSeconds: 0.001,
pageNumber: 1,
pageSize: 100,
});
const result = await queryIntegration.run(defaultQueryData);
assert.equal(result.error?.errorType, ERROR_TYPES.query_run_timeout_error);
@ -190,6 +194,8 @@ describe("run: timeout_error", () => {
cached: false,
timeoutMinutes: 0.01,
retryIntervalSeconds: 0.001,
pageNumber: 1,
pageSize: 100,
});
const result = await queryIntegration.run(defaultQueryData);
assert.equal(

View File

@ -33,6 +33,8 @@ function getQueryResultSetBuilder(
columnTypes: ["number", "string", "string", "boolean", "number"],
message: "",
errors: null,
pageSize: 100,
pageNumber: 0,
},
error: null,
};

View File

@ -5,5 +5,5 @@ import { QueryResultResp } from "./query-result-resp.type";
export interface ApiClient {
getUrl(path: string): string;
createQuery(query: Query): Promise<CreateQueryResp>;
getQueryResult(queryID: string): Promise<QueryResultResp>;
getQueryResult(queryID: string, pageNumber: number, pageSize: number): Promise<QueryResultResp>;
}

View File

@ -12,6 +12,8 @@ export type QueryResultJson = {
columnTypes: string[];
message?: string;
errors?: string | null;
pageNumber: number;
pageSize: number;
};
export interface QueryResultResp extends ApiResponse {

View File

@ -3,4 +3,6 @@ export type QueryDefaults = {
cached: boolean;
timeoutMinutes: number;
retryIntervalSeconds: number;
pageSize: number;
pageNumber: number;
};

View File

@ -7,4 +7,8 @@ export type Query = {
cached?: boolean;
// The number of minutes until your query time out
timeoutMinutes?: number;
// The number of records to return
pageSize?: number;
// The page number to return
pageNumber?: number;
};