From d06af1ebafc37078c3bcc857638f08f40c8a12eb Mon Sep 17 00:00:00 2001 From: vorujack Date: Fri, 22 Dec 2023 15:21:16 +0330 Subject: [PATCH 1/2] fix revenue chart --- services/watcher/src/api/revenue.ts | 3 + .../database/entities/revenueChartDataView.ts | 4 + .../watcher/src/database/migrations/index.ts | 6 +- .../1703244656364-watcherMigration.ts | 94 +++++++++++++++++++ .../sqlite/1703244614956-watcherMigration.ts | 94 +++++++++++++++++++ .../src/database/models/watcherModel.ts | 24 +++-- services/watcher/src/ergo/utils.ts | 9 +- 7 files changed, 223 insertions(+), 11 deletions(-) create mode 100644 services/watcher/src/database/migrations/postgres/1703244656364-watcherMigration.ts create mode 100644 services/watcher/src/database/migrations/sqlite/1703244614956-watcherMigration.ts diff --git a/services/watcher/src/api/revenue.ts b/services/watcher/src/api/revenue.ts index 3c9fdc3a..8cebfe6b 100644 --- a/services/watcher/src/api/revenue.ts +++ b/services/watcher/src/api/revenue.ts @@ -77,13 +77,16 @@ revenueRouter.get('/chart', async (req, res) => { : Math.min(Number(limitString), MAX_API_LIMIT); let queryResult; + const wid = Transaction.watcherWID || ''; if (periodString === 'week') { queryResult = await watcherDatabase.getWeeklyRevenueChartData( + wid, finalOffset, finalLimit ); } else if (periodString === 'month' || periodString === 'year') { queryResult = await watcherDatabase.getRevenueChartData( + wid, periodString, finalOffset, finalLimit diff --git a/services/watcher/src/database/entities/revenueChartDataView.ts b/services/watcher/src/database/entities/revenueChartDataView.ts index 699e4925..20e9ab54 100644 --- a/services/watcher/src/database/entities/revenueChartDataView.ts +++ b/services/watcher/src/database/entities/revenueChartDataView.ts @@ -11,6 +11,7 @@ import { ViewEntity, ViewColumn } from 'typeorm'; .addSelect(`be.day`, 'day') .addSelect(`be.month`, 'month') .addSelect(`be.year`, 'year') + .addSelect('pe.WID', 'wid') .from('revenue_entity', 're') .innerJoin('permit_entity', 'pe', 're."permitId" = pe.id') .innerJoin('block_entity', 'be', 'pe.block = be.hash'), @@ -28,6 +29,9 @@ export class RevenueChartDataView { @ViewColumn() month!: number; + @ViewColumn() + wid!: string; + @ViewColumn() year!: number; diff --git a/services/watcher/src/database/migrations/index.ts b/services/watcher/src/database/migrations/index.ts index 8c3c9436..67d513fb 100644 --- a/services/watcher/src/database/migrations/index.ts +++ b/services/watcher/src/database/migrations/index.ts @@ -1,7 +1,9 @@ import { WatcherMigration1700710099334 } from './postgres/1700710099334-watcherMigration'; +import { WatcherMigration1703244656364 } from './postgres/1703244656364-watcherMigration'; import { WatcherMigration1700641198429 } from './sqlite/1700641198429-watcherMigration'; +import { WatcherMigration1703244614956 } from './sqlite/1703244614956-watcherMigration'; export default { - sqlite: [WatcherMigration1700641198429], - postgres: [WatcherMigration1700710099334], + sqlite: [WatcherMigration1700641198429, WatcherMigration1703244614956], + postgres: [WatcherMigration1700710099334, WatcherMigration1703244656364], }; diff --git a/services/watcher/src/database/migrations/postgres/1703244656364-watcherMigration.ts b/services/watcher/src/database/migrations/postgres/1703244656364-watcherMigration.ts new file mode 100644 index 00000000..60c9ef99 --- /dev/null +++ b/services/watcher/src/database/migrations/postgres/1703244656364-watcherMigration.ts @@ -0,0 +1,94 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class WatcherMigration1703244656364 implements MigrationInterface { + name = 'WatcherMigration1703244656364'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + ` + DELETE FROM "typeorm_metadata" + WHERE "type" = ? + AND "name" = ? + `, + ['VIEW', 'revenue_chart_data'] + ); + await queryRunner.query(` + DROP VIEW "revenue_chart_data" + `); + await queryRunner.query(` + CREATE VIEW "revenue_chart_data" AS + SELECT "pe"."WID" AS "wid", + "be"."year" AS "year", + "be"."month" AS "month", + "be"."day" AS "day", + re."tokenId" AS "tokenId", + re."amount" AS "amount", + be."timestamp" AS "timestamp" + FROM "revenue_entity" "re" + INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" + INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash" + `); + await queryRunner.query( + ` + INSERT INTO "typeorm_metadata"( + "database", + "schema", + "table", + "type", + "name", + "value" + ) + VALUES (NULL, NULL, NULL, ?, ?, ?) + `, + [ + 'VIEW', + 'revenue_chart_data', + 'SELECT "pe"."WID" AS "wid", "be"."year" AS "year", "be"."month" AS "month", "be"."day" AS "day", re."tokenId" AS "tokenId", re."amount" AS "amount", be."timestamp" AS "timestamp" FROM "revenue_entity" "re" INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash"', + ] + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + ` + DELETE FROM "typeorm_metadata" + WHERE "type" = ? + AND "name" = ? + `, + ['VIEW', 'revenue_chart_data'] + ); + await queryRunner.query(` + DROP VIEW "revenue_chart_data" + `); + await queryRunner.query(` + CREATE VIEW "revenue_chart_data" AS + SELECT "be"."year" AS "year", + "be"."month" AS "month", + "be"."day" AS "day", + re."tokenId" AS "tokenId", + re."amount" AS "amount", + be."timestamp" AS "timestamp" + FROM "revenue_entity" "re" + INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" + INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash" + `); + await queryRunner.query( + ` + INSERT INTO "typeorm_metadata"( + "database", + "schema", + "table", + "type", + "name", + "value" + ) + VALUES (NULL, NULL, NULL, ?, ?, ?) + `, + [ + 'VIEW', + 'revenue_chart_data', + 'SELECT "be"."year" AS "year", "be"."month" AS "month", "be"."day" AS "day", re."tokenId" AS "tokenId", re."amount" AS "amount", be."timestamp" AS "timestamp" FROM "revenue_entity" "re" INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash"', + ] + ); + } +} diff --git a/services/watcher/src/database/migrations/sqlite/1703244614956-watcherMigration.ts b/services/watcher/src/database/migrations/sqlite/1703244614956-watcherMigration.ts new file mode 100644 index 00000000..6ee88f74 --- /dev/null +++ b/services/watcher/src/database/migrations/sqlite/1703244614956-watcherMigration.ts @@ -0,0 +1,94 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class WatcherMigration1703244614956 implements MigrationInterface { + name = 'WatcherMigration1703244614956'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + ` + DELETE FROM "typeorm_metadata" + WHERE "type" = ? + AND "name" = ? + `, + ['VIEW', 'revenue_chart_data'] + ); + await queryRunner.query(` + DROP VIEW "revenue_chart_data" + `); + await queryRunner.query(` + CREATE VIEW "revenue_chart_data" AS + SELECT "pe"."WID" AS "wid", + "be"."year" AS "year", + "be"."month" AS "month", + "be"."day" AS "day", + re."tokenId" AS "tokenId", + re."amount" AS "amount", + be."timestamp" AS "timestamp" + FROM "revenue_entity" "re" + INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" + INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash" + `); + await queryRunner.query( + ` + INSERT INTO "typeorm_metadata"( + "database", + "schema", + "table", + "type", + "name", + "value" + ) + VALUES (NULL, NULL, NULL, ?, ?, ?) + `, + [ + 'VIEW', + 'revenue_chart_data', + 'SELECT "pe"."WID" AS "wid", "be"."year" AS "year", "be"."month" AS "month", "be"."day" AS "day", re."tokenId" AS "tokenId", re."amount" AS "amount", be."timestamp" AS "timestamp" FROM "revenue_entity" "re" INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash"', + ] + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + ` + DELETE FROM "typeorm_metadata" + WHERE "type" = ? + AND "name" = ? + `, + ['VIEW', 'revenue_chart_data'] + ); + await queryRunner.query(` + DROP VIEW "revenue_chart_data" + `); + await queryRunner.query(` + CREATE VIEW "revenue_chart_data" AS + SELECT "be"."year" AS "year", + "be"."month" AS "month", + "be"."day" AS "day", + re."tokenId" AS "tokenId", + re."amount" AS "amount", + be."timestamp" AS "timestamp" + FROM "revenue_entity" "re" + INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" + INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash" + `); + await queryRunner.query( + ` + INSERT INTO "typeorm_metadata"( + "database", + "schema", + "table", + "type", + "name", + "value" + ) + VALUES (NULL, NULL, NULL, ?, ?, ?) + `, + [ + 'VIEW', + 'revenue_chart_data', + 'SELECT "be"."year" AS "year", "be"."month" AS "month", "be"."day" AS "day", re."tokenId" AS "tokenId", re."amount" AS "amount", be."timestamp" AS "timestamp" FROM "revenue_entity" "re" INNER JOIN "permit_entity" "pe" ON re."permitId" = "pe"."id" INNER JOIN "block_entity" "be" ON "pe"."block" = "be"."hash"', + ] + ); + } +} diff --git a/services/watcher/src/database/models/watcherModel.ts b/services/watcher/src/database/models/watcherModel.ts index 80391ea6..76afbe97 100644 --- a/services/watcher/src/database/models/watcherModel.ts +++ b/services/watcher/src/database/models/watcherModel.ts @@ -889,17 +889,23 @@ class WatcherDataBase { * @param offset * @param limit */ - getWeeklyRevenueChartData = async (offset: number, limit: number) => { - let qb = this.revenueChartView.createQueryBuilder('rcv'); - qb = qb + getWeeklyRevenueChartData = async ( + wid: string, + offset: number, + limit: number + ) => { + return this.revenueChartView + .createQueryBuilder('rcv') .select('"tokenId"') .addSelect('timestamp/604800 as week_number') .addSelect('sum(amount) as revenue') + .where('wid = :wid', { wid }) .groupBy('"tokenId"') .addGroupBy('week_number') - .orderBy('week_number', 'DESC'); - - return qb.offset(offset).limit(limit).execute(); + .orderBy('week_number', 'DESC') + .offset(offset) + .limit(limit) + .execute(); }; /** @@ -909,15 +915,17 @@ class WatcherDataBase { * @param limit */ getRevenueChartData = async ( + wid: string, period: string, offset: number, limit: number ) => { - let qb = this.revenueChartView.createQueryBuilder('rcv'); - qb = qb + let qb = this.revenueChartView + .createQueryBuilder('rcv') .select('"tokenId"') .addSelect('year') .addSelect('sum(amount) as revenue') + .where('wid = :wid', { wid }) .groupBy('"tokenId"') .addGroupBy('year') .orderBy('year', 'DESC'); diff --git a/services/watcher/src/ergo/utils.ts b/services/watcher/src/ergo/utils.ts index 2912022f..03c14d3f 100644 --- a/services/watcher/src/ergo/utils.ts +++ b/services/watcher/src/ergo/utils.ts @@ -521,6 +521,7 @@ export class ErgoUtils { static transformChartData = (chartData: RevenueChartRecord[]) => { const chartMap = new Map>(); + const labels: Array = []; chartData.forEach((record) => { const year = Number(record.year); const month = Number(record.month) || 1; @@ -535,6 +536,7 @@ export class ErgoUtils { label: String(timestamp), amount: record.revenue.toString(), }; + if (!labels.includes(String(timestamp))) labels.push(String(timestamp)); const chartRecords = chartMap.get(record.tokenId) || []; chartRecords.push(chartRecord); chartMap.set(record.tokenId, chartRecords); @@ -545,9 +547,14 @@ export class ErgoUtils { data: Array; }[] = []; chartMap.forEach((records, tokenId) => { + const filledRecords = labels.map((timestamp) => { + const filtered = records.filter((rec) => rec.label === timestamp); + if (filtered.length) return filtered[0]; + return { label: timestamp, amount: '0' }; + }); jsonObject.push({ title: this.tokenDetailByTokenMap(tokenId, ERGO_CHAIN_NAME), - data: records, + data: filledRecords, }); }); return jsonObject; From 8bcf21b79c49fc847e6219972005f7ce95dc58cf Mon Sep 17 00:00:00 2001 From: vorujack Date: Fri, 22 Dec 2023 15:57:02 +0330 Subject: [PATCH 2/2] fix tests --- services/watcher/tests/ergo/statistics/mockUtils.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/watcher/tests/ergo/statistics/mockUtils.ts b/services/watcher/tests/ergo/statistics/mockUtils.ts index 60964b7a..e3fb0161 100644 --- a/services/watcher/tests/ergo/statistics/mockUtils.ts +++ b/services/watcher/tests/ergo/statistics/mockUtils.ts @@ -321,7 +321,10 @@ const revenueWeeklyChart = [ tokenId: '0034c44f0c7a38f833190d44125ff9b3a0dd9dbb89138160182a930bc521db95', }, - data: [{ label: '123379200000', amount: '10' }], + data: [ + { label: '123379200000', amount: '10' }, + { label: '0', amount: '0' }, + ], }, { title: {