Skip to content

Commit 378a80e

Browse files
Merge pull request #1601 from RedisInsight/be/feature/RI-3997_Display_indexes_in_Workbench_and_Analytics
#RI-3997 - [BE] Display db indexes in Workbench and Database analysis
2 parents 21ea3ba + 4ea43b0 commit 378a80e

21 files changed

+121
-7
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { MigrationInterface, QueryRunner } from "typeorm";
2+
3+
export class workbenchAndAnalysisDbIndex1673934231410 implements MigrationInterface {
4+
name = 'workbenchAndAnalysisDbIndex1673934231410'
5+
6+
public async up(queryRunner: QueryRunner): Promise<void> {
7+
await queryRunner.query(`DROP INDEX "IDX_5cd90dd6def1fd7c521e53fb2c"`);
8+
await queryRunner.query(`CREATE TABLE "temporary_command_execution" ("id" varchar PRIMARY KEY NOT NULL, "databaseId" varchar NOT NULL, "command" text NOT NULL, "result" text NOT NULL, "role" varchar, "nodeOptions" varchar, "encryption" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "mode" varchar, "resultsMode" varchar, "summary" varchar, "executionTime" integer, "db" integer, CONSTRAINT "FK_ea8adfe9aceceb79212142206b8" FOREIGN KEY ("databaseId") REFERENCES "database_instance" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`);
9+
await queryRunner.query(`INSERT INTO "temporary_command_execution"("id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary", "executionTime") SELECT "id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary", "executionTime" FROM "command_execution"`);
10+
await queryRunner.query(`DROP TABLE "command_execution"`);
11+
await queryRunner.query(`ALTER TABLE "temporary_command_execution" RENAME TO "command_execution"`);
12+
await queryRunner.query(`CREATE INDEX "IDX_5cd90dd6def1fd7c521e53fb2c" ON "command_execution" ("createdAt") `);
13+
await queryRunner.query(`DROP INDEX "IDX_d174a8edc2201d6c5781f0126a"`);
14+
await queryRunner.query(`DROP INDEX "IDX_fdd0daeb4d8f226cf1ff79bebb"`);
15+
await queryRunner.query(`CREATE TABLE "temporary_database_analysis" ("id" varchar PRIMARY KEY NOT NULL, "databaseId" varchar NOT NULL, "filter" blob, "delimiter" varchar NOT NULL, "progress" blob, "totalKeys" blob, "totalMemory" blob, "topKeysNsp" blob, "topMemoryNsp" blob, "topKeysLength" blob, "topKeysMemory" blob, "encryption" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "expirationGroups" blob, "db" integer, CONSTRAINT "FK_d174a8edc2201d6c5781f0126ae" FOREIGN KEY ("databaseId") REFERENCES "database_instance" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`);
16+
await queryRunner.query(`INSERT INTO "temporary_database_analysis"("id", "databaseId", "filter", "delimiter", "progress", "totalKeys", "totalMemory", "topKeysNsp", "topMemoryNsp", "topKeysLength", "topKeysMemory", "encryption", "createdAt", "expirationGroups") SELECT "id", "databaseId", "filter", "delimiter", "progress", "totalKeys", "totalMemory", "topKeysNsp", "topMemoryNsp", "topKeysLength", "topKeysMemory", "encryption", "createdAt", "expirationGroups" FROM "database_analysis"`);
17+
await queryRunner.query(`DROP TABLE "database_analysis"`);
18+
await queryRunner.query(`ALTER TABLE "temporary_database_analysis" RENAME TO "database_analysis"`);
19+
await queryRunner.query(`CREATE INDEX "IDX_d174a8edc2201d6c5781f0126a" ON "database_analysis" ("databaseId") `);
20+
await queryRunner.query(`CREATE INDEX "IDX_fdd0daeb4d8f226cf1ff79bebb" ON "database_analysis" ("createdAt") `);
21+
}
22+
23+
public async down(queryRunner: QueryRunner): Promise<void> {
24+
await queryRunner.query(`DROP INDEX "IDX_fdd0daeb4d8f226cf1ff79bebb"`);
25+
await queryRunner.query(`DROP INDEX "IDX_d174a8edc2201d6c5781f0126a"`);
26+
await queryRunner.query(`ALTER TABLE "database_analysis" RENAME TO "temporary_database_analysis"`);
27+
await queryRunner.query(`CREATE TABLE "database_analysis" ("id" varchar PRIMARY KEY NOT NULL, "databaseId" varchar NOT NULL, "filter" blob, "delimiter" varchar NOT NULL, "progress" blob, "totalKeys" blob, "totalMemory" blob, "topKeysNsp" blob, "topMemoryNsp" blob, "topKeysLength" blob, "topKeysMemory" blob, "encryption" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "expirationGroups" blob, CONSTRAINT "FK_d174a8edc2201d6c5781f0126ae" FOREIGN KEY ("databaseId") REFERENCES "database_instance" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`);
28+
await queryRunner.query(`INSERT INTO "database_analysis"("id", "databaseId", "filter", "delimiter", "progress", "totalKeys", "totalMemory", "topKeysNsp", "topMemoryNsp", "topKeysLength", "topKeysMemory", "encryption", "createdAt", "expirationGroups") SELECT "id", "databaseId", "filter", "delimiter", "progress", "totalKeys", "totalMemory", "topKeysNsp", "topMemoryNsp", "topKeysLength", "topKeysMemory", "encryption", "createdAt", "expirationGroups" FROM "temporary_database_analysis"`);
29+
await queryRunner.query(`DROP TABLE "temporary_database_analysis"`);
30+
await queryRunner.query(`CREATE INDEX "IDX_fdd0daeb4d8f226cf1ff79bebb" ON "database_analysis" ("createdAt") `);
31+
await queryRunner.query(`CREATE INDEX "IDX_d174a8edc2201d6c5781f0126a" ON "database_analysis" ("databaseId") `);
32+
await queryRunner.query(`DROP INDEX "IDX_5cd90dd6def1fd7c521e53fb2c"`);
33+
await queryRunner.query(`ALTER TABLE "command_execution" RENAME TO "temporary_command_execution"`);
34+
await queryRunner.query(`CREATE TABLE "command_execution" ("id" varchar PRIMARY KEY NOT NULL, "databaseId" varchar NOT NULL, "command" text NOT NULL, "result" text NOT NULL, "role" varchar, "nodeOptions" varchar, "encryption" varchar, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "mode" varchar, "resultsMode" varchar, "summary" varchar, "executionTime" integer, CONSTRAINT "FK_ea8adfe9aceceb79212142206b8" FOREIGN KEY ("databaseId") REFERENCES "database_instance" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`);
35+
await queryRunner.query(`INSERT INTO "command_execution"("id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary", "executionTime") SELECT "id", "databaseId", "command", "result", "role", "nodeOptions", "encryption", "createdAt", "mode", "resultsMode", "summary", "executionTime" FROM "temporary_command_execution"`);
36+
await queryRunner.query(`DROP TABLE "temporary_command_execution"`);
37+
await queryRunner.query(`CREATE INDEX "IDX_5cd90dd6def1fd7c521e53fb2c" ON "command_execution" ("createdAt") `);
38+
}
39+
40+
}

redisinsight/api/migration/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { databaseAnalysisExpirationGroups1664886479051 } from './1664886479051-d
2222
import { workbenchExecutionTime1667368983699 } from './1667368983699-workbench-execution-time';
2323
import { database1667477693934 } from './1667477693934-database';
2424
import { databaseNew1670252337342 } from './1670252337342-database-new';
25+
import { workbenchAndAnalysisDbIndex1673934231410 } from './1673934231410-workbench_and_analysis_db';
2526

2627
export default [
2728
initialMigration1614164490968,
@@ -48,4 +49,5 @@ export default [
4849
workbenchExecutionTime1667368983699,
4950
database1667477693934,
5051
databaseNew1670252337342,
52+
workbenchAndAnalysisDbIndex1673934231410,
5153
];

redisinsight/api/src/modules/database-analysis/database-analysis.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export class DatabaseAnalysisService {
5252

5353
const analysis = plainToClass(DatabaseAnalysis, await this.analyzer.analyze({
5454
databaseId: clientMetadata.databaseId,
55+
db: client?.options?.db || 0,
5556
...dto,
5657
progress,
5758
}, [].concat(...scanResults.map((nodeResult) => nodeResult.keys))));

redisinsight/api/src/modules/database-analysis/entities/database-analysis.entity.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn, JoinColumn, Index,
33
} from 'typeorm';
4+
import { IsInt, Min } from 'class-validator';
45
import { Expose, Transform } from 'class-transformer';
56
import { DataAsJsonString } from 'src/common/decorators';
67
import { DatabaseEntity } from 'src/modules/database/entities/database.entity';
@@ -118,6 +119,12 @@ export class DatabaseAnalysisEntity {
118119
@Column({ nullable: true })
119120
encryption: string;
120121

122+
@Column({ nullable: true })
123+
@Expose()
124+
@IsInt()
125+
@Min(0)
126+
db?: number;
127+
121128
@CreateDateColumn()
122129
@Index()
123130
@Expose()

redisinsight/api/src/modules/database-analysis/models/database-analysis.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { NspSummary } from 'src/modules/database-analysis/models/nsp-summary';
22
import { Key } from 'src/modules/database-analysis/models/key';
3+
import { IsInt, IsOptional, Min } from 'class-validator';
34
import { Expose, Type } from 'class-transformer';
45
import { SimpleSummary } from 'src/modules/database-analysis/models/simple-summary';
5-
import { ApiProperty } from '@nestjs/swagger';
6+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
67
import { ScanFilter } from 'src/modules/database-analysis/models/scan-filter';
78
import { AnalysisProgress } from 'src/modules/database-analysis/models/analysis-progress';
89
import { SumGroup } from 'src/modules/database-analysis/models/sum-group';
@@ -114,4 +115,14 @@ export class DatabaseAnalysis {
114115
@Expose()
115116
@Type(() => SumGroup)
116117
expirationGroups: SumGroup[];
118+
119+
@ApiPropertyOptional({
120+
description: 'Logical database number.',
121+
type: Number,
122+
})
123+
@Expose()
124+
@IsInt()
125+
@Min(0)
126+
@IsOptional()
127+
db?: number;
117128
}

redisinsight/api/src/modules/database-analysis/models/short-database-analysis.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import { PartialType, PickType } from '@nestjs/swagger';
22
import { DatabaseAnalysis } from 'src/modules/database-analysis/models/database-analysis';
33

44
export class ShortDatabaseAnalysis extends PartialType(
5-
PickType(DatabaseAnalysis, ['id', 'createdAt'] as const),
5+
PickType(DatabaseAnalysis, ['id', 'createdAt', 'db'] as const),
66
) {}

redisinsight/api/src/modules/database-analysis/providers/database-analysis.provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class DatabaseAnalysisProvider {
7676
const entities = await this.repository
7777
.createQueryBuilder('a')
7878
.where({ databaseId })
79-
.select(['a.id', 'a.createdAt'])
79+
.select(['a.id', 'a.createdAt', 'a.db'])
8080
.orderBy('a.createdAt', 'DESC')
8181
.limit(DATABASE_ANALYSIS_CONFIG.maxItemsPerDb)
8282
.getMany();

redisinsight/api/src/modules/workbench/entities/command-execution.entity.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
import { DatabaseEntity } from 'src/modules/database/entities/database.entity';
55
import { RunQueryMode, ResultsMode } from 'src/modules/workbench/dto/create-command-execution.dto';
66
import { Expose, Transform } from 'class-transformer';
7+
import { IsInt, Min } from 'class-validator';
78

89
@Entity('command_execution')
910
export class CommandExecutionEntity {
@@ -84,6 +85,12 @@ export class CommandExecutionEntity {
8485
@Expose()
8586
executionTime?: number;
8687

88+
@Column({ nullable: true })
89+
@Expose()
90+
@IsInt()
91+
@Min(0)
92+
db?: number;
93+
8794
@CreateDateColumn()
8895
@Index()
8996
@Expose()

redisinsight/api/src/modules/workbench/models/command-execution.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2-
import { IsDefined } from 'class-validator';
2+
import { IsDefined, IsInt, IsOptional, Min } from 'class-validator';
33
import { CommandExecutionResult } from 'src/modules/workbench/models/command-execution-result';
44
import { ClusterNodeRole, RunQueryMode, ResultsMode } from 'src/modules/workbench/dto/create-command-execution.dto';
55
import { ClusterSingleNodeOptions } from 'src/modules/cli/dto/cli.dto';
@@ -117,6 +117,16 @@ export class CommandExecution {
117117
@Expose()
118118
executionTime?: number;
119119

120+
@ApiPropertyOptional({
121+
description: 'Logical database number.',
122+
type: Number,
123+
})
124+
@Expose()
125+
@IsInt()
126+
@Min(0)
127+
@IsOptional()
128+
db?: number;
129+
120130
constructor(partial: Partial<CommandExecution> = {}) {
121131
Object.assign(this, partial);
122132
}

redisinsight/api/src/modules/workbench/providers/command-execution.provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export class CommandExecutionProvider {
9797
'e.summary',
9898
'e.resultsMode',
9999
'e.executionTime',
100+
'e.db',
100101
])
101102
.orderBy('e.createdAt', 'DESC')
102103
.limit(WORKBENCH_CONFIG.maxItemsPerDb)

0 commit comments

Comments
 (0)