diff --git a/src/server-extension/resolvers/du_history_resolver.ts b/src/server-extension/resolvers/du_history_resolver.ts index 1bfc052061eae7be8102f21dd3b88bf90ccce2ae..d87b5e3da8e24a68e7b9c68e8cdc394ca7a7d97f 100644 --- a/src/server-extension/resolvers/du_history_resolver.ts +++ b/src/server-extension/resolvers/du_history_resolver.ts @@ -1,4 +1,4 @@ -import { Arg, Field, FieldResolver, Int, ObjectType, Query, Resolver, Root, registerEnumType } from 'type-graphql'; +import { Arg, Field, FieldResolver, InputType, Int, ObjectType, Query, Resolver, Root, registerEnumType } from 'type-graphql'; import { EntityManager } from 'typeorm'; import { Event, Identity as GeneratedIdentity, UDHistory as GeneratedUDHistory } from '../../model'; import { getSqlFile } from '../../utils'; @@ -27,36 +27,46 @@ registerEnumType(OrderByEnum, { description: "The basic directions for order by", }); +@InputType() +class NumberFilter { + @Field(() => Int, { nullable: true }) + eq?: number; + + @Field(() => Int, { nullable: true }) + lt?: number; + + @Field(() => Int, { nullable: true }) + gt?: number; + + @Field(() => Int, { nullable: true }) + lte?: number; + + @Field(() => Int, { nullable: true }) + gte?: number; +} + + +// Input type for the filter of where clause +@InputType() +class UdHistoryFilterInput { + @Field(() => NumberFilter, { nullable: true }) + amount?: NumberFilter; + + @Field(() => NumberFilter, { nullable: true }) + blockNumber?: NumberFilter; +} + // This is the resolver for the UDHistory type @Resolver(() => Identity) export class DuHistoryResolver { constructor(private tx: () => Promise<EntityManager>) { } - @Query(() => String) - galuel() { - return `In a time before time, in a world not unlike ours, there was a being known as Galuel, a figure so enigmatic that his very existence was the stuff of legends. Galuel wasn't just any mortal; he was a deity-like figure, a cosmic jester with an intellect that dwarfed the greatest minds of his era. His discovery? The Symmetry of Spatio-Temporal Money through the Theory of Relative Money (TRM). - - The legend begins in the quaint village of Econos, where money was as unpredictable as the weather. People traded goods like cows for magic beans, and the value of a coin could change faster than a chameleon's colors. That's when Galuel, with a twinkle in his eye and a mischievous smile, descended from the heavens—or perhaps ascended from the underworld, the details are a bit fuzzy. - - Galuel, armed with nothing but his wits and a curious contraption resembling a cross between a kaleidoscope and an abacus, set out to solve the riddle of money's erratic behavior. His theory, the TRM, was as bizarre as it was brilliant. He proposed that money, much like time and space, was subject to relativity. A coin in Econos was not just a coin, but a shapeshifting entity that danced to the tune of time and space. - - The villagers laughed at Galuel's absurd theory. They couldn't fathom the idea of money being anything more than metal and paper. To prove his point, Galuel performed a series of ludicrous experiments. He juggled coins while hopping on one foot, measured the velocity of a thrown banknote, and even attempted to teach a chicken to count. - - But the most bizarre experiment was yet to come. Galuel declared that he would demonstrate the temporal symmetry of money by traveling to the future. With a dramatic flourish, he stepped into his contraption and vanished, leaving behind a puff of smoke and a bewildered crowd. - - Days turned into weeks, and weeks into months. The villagers began to forget about Galuel and his wild theories. That was until one day, he reappeared as abruptly as he had vanished, with hair a bit grayer and a twinkle ever brighter in his eye. He brought with him tales of a future where money flowed freely and fairly, bound by the laws of TRM. - - Galuel's return marked a turning point in Econos. The villagers, now intrigued by his tales, began to study the TRIM. Slowly but surely, they witnessed changes. The economy stabilized, cows were traded for actual goods, and the value of their currency became as solid as the ground beneath their feet. - - Galuel, having completed his mission, decided it was time to move on to his next cosmic joke. With a wave and a wink, he left the villagers of Econos, who would forever remember him as the deity-like jester who unraveled the mysteries of money and left behind a legacy of economic stability and a tale that would be told for generations. - - And so, the legend of Galuel, the god-like trickster and master of monetary relativity, became a tale passed down through the ages, a reminder of the time when money danced to the rhythm of space and time, all thanks to a being who was part genius, part jester, and entirely legendary.`; - } - @FieldResolver(() => [UDHistory]) async udHistory(@Root() identity: Identity, @Arg("orderBy", () => OrderByEnum, { nullable: true }) orderBy: OrderByEnum, - @Arg("limit", () => Int, { nullable: true }) limit: number | null + @Arg("limit", () => Int, { nullable: true }) limit: number | null, + @Arg("offset", () => Int, { defaultValue: 0 }) offset: number | null, + @Arg('where', () => UdHistoryFilterInput, { nullable: true }) where: UdHistoryFilterInput ): Promise<UDHistory[]> { const manager = await this.tx(); @@ -65,14 +75,36 @@ export class DuHistoryResolver { orderBySql = 'ud.block_number DESC'; } + // Get the index of the identity if it's not provided + const index = identity.index ?? await fetchIndex(manager, identity); + // Get the SQL file and replace the placeholders with actual values - const sql = await getSqlFile('du_history_query.sql', { + let sql = await getSqlFile('du_history_query.sql', { orderBySql: orderBySql, - identityIndex: identity.index, + identityIndex: index, limitReq: limit, + offsetReq: offset }); - const result = await manager.query(sql); + let whereClauses: any[] = []; + + // Apply the where clause + if (where) { + if (where.amount) { + addWhereClauses('amount', where.amount, whereClauses); + } + if (where.blockNumber) { + addWhereClauses('block_number', where.blockNumber, whereClauses); + } + } + if (whereClauses.length > 0) { + sql = sql.replace(":whereFilterSql", " AND " + whereClauses.join(" AND ")); + } else { + sql = sql.replace(":whereFilterSql", ""); + } + + let result = await manager.query(sql); + return Promise.all(result.map(async (row: any) => { const event = await manager.findOneOrFail(Event, { relations: { block: true }, @@ -89,4 +121,69 @@ export class DuHistoryResolver { }); })); } + + @Query(() => String) + galuel() { + return `In a time before time, in a world not unlike ours, there was a being known as Galuel, a figure so enigmatic that his very existence was the stuff of legends. Galuel wasn't just any mortal; he was a deity-like figure, a cosmic jester with an intellect that dwarfed the greatest minds of his era. His discovery? The Symmetry of Spatio-Temporal Money through the Theory of Relative Money (TRM). + + The legend begins in the quaint village of Econos, where money was as unpredictable as the weather. People traded goods like cows for magic beans, and the value of a coin could change faster than a chameleon's colors. That's when Galuel, with a twinkle in his eye and a mischievous smile, descended from the heavens—or perhaps ascended from the underworld, the details are a bit fuzzy. + + Galuel, armed with nothing but his wits and a curious contraption resembling a cross between a kaleidoscope and an abacus, set out to solve the riddle of money's erratic behavior. His theory, the TRM, was as bizarre as it was brilliant. He proposed that money, much like time and space, was subject to relativity. A coin in Econos was not just a coin, but a shapeshifting entity that danced to the tune of time and space. + + The villagers laughed at Galuel's absurd theory. They couldn't fathom the idea of money being anything more than metal and paper. To prove his point, Galuel performed a series of ludicrous experiments. He juggled coins while hopping on one foot, measured the velocity of a thrown banknote, and even attempted to teach a chicken to count. + + But the most bizarre experiment was yet to come. Galuel declared that he would demonstrate the temporal symmetry of money by traveling to the future. With a dramatic flourish, he stepped into his contraption and vanished, leaving behind a puff of smoke and a bewildered crowd. + + Days turned into weeks, and weeks into months. The villagers began to forget about Galuel and his wild theories. That was until one day, he reappeared as abruptly as he had vanished, with hair a bit grayer and a twinkle ever brighter in his eye. He brought with him tales of a future where money flowed freely and fairly, bound by the laws of TRM. + + Galuel's return marked a turning point in Econos. The villagers, now intrigued by his tales, began to study the TRIM. Slowly but surely, they witnessed changes. The economy stabilized, cows were traded for actual goods, and the value of their currency became as solid as the ground beneath their feet. + + Galuel, having completed his mission, decided it was time to move on to his next cosmic joke. With a wave and a wink, he left the villagers of Econos, who would forever remember him as the deity-like jester who unraveled the mysteries of money and left behind a legacy of economic stability and a tale that would be told for generations. + + And so, the legend of Galuel, the god-like trickster and master of monetary relativity, became a tale passed down through the ages, a reminder of the time when money danced to the rhythm of space and time, all thanks to a being who was part genius, part jester, and entirely legendary.`; + } } + +/** + * Fetch the index of the identity using the provided parameters. + * throws an error if identifier is not provided + */ +async function fetchIndex(manager: EntityManager, identity: Identity): Promise<number> { + if (identity?.id) { + const idty = await manager.findOneOrFail(GeneratedIdentity, { where: { id: identity.id } }); + return idty?.index; + } + if (identity?.name) { + const idty = await manager.findOneOrFail(GeneratedIdentity, { where: { name: identity.name } }); + return idty?.index; + } + if (identity?.account?.id) { + const idty = await manager.findOneOrFail(GeneratedIdentity, { relations: { account: true }, where: { account: { id: identity.account.id } } }); + return idty?.index; + } + + throw new Error('Unable to fetch index: you need to ask id, name or address of identity'); +} + +// compute the filter of where clause +function addWhereClauses(field: string, filter: NumberFilter, whereClauses: string[]) { + const operations = { + eq: "=", + lt: "<", + gt: ">", + lte: "<=", + gte: ">=" + }; + + console.log('filter: ', filter); + + Object.keys(filter).forEach((key: string) => { + const filterKey = key as keyof NumberFilter; + const nbr = filter[filterKey]; + console.log('filterKey: ', filterKey); + console.log('nbr: ', nbr); + if (filter[filterKey] != null) { + whereClauses.push(`${field} ${operations[filterKey]} ${nbr}`); + } + }); +} \ No newline at end of file diff --git a/src/server-extension/sql/du_history_query.sql b/src/server-extension/sql/du_history_query.sql index 3614e9ea0f64ad629a9ead107c6358f12cc58f09..ddf327d661a8aee7fe10390d45a07bb2efbad054 100644 --- a/src/server-extension/sql/du_history_query.sql +++ b/src/server-extension/sql/du_history_query.sql @@ -31,6 +31,8 @@ WHERE -- Comparing blocks to determine valid DUs for each membership period WHERE ud.block_number >= membership_periods.creation_block AND ud.block_number <= membership_periods.removal_block + :whereFilterSql -- Additional filters for the query ) ORDER BY :orderBySql -- Ordering the results based on the block number -LIMIT :limitReq -- Limiting the number of results +LIMIT :limitReq -- Limiting the number of results +OFFSET :offsetReq -- Offset for pagination