Skip to content

Commit

Permalink
Merge pull request #1175 from merico-dev/1173-add-content_id-query_id…
Browse files Browse the repository at this point in the history
…-params-filters-and-context-variables-to-query-interface

1173 add content id query id params filters and context variables to query interface
  • Loading branch information
miguel-lansdorf authored Oct 9, 2023
2 parents 52779d7 + 91623a4 commit 3595465
Show file tree
Hide file tree
Showing 25 changed files with 1,444 additions and 255 deletions.
1 change: 1 addition & 0 deletions api/.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ SERVER_PORT=31200
CORS_ALLOW_ORIGIN=
SECRET_KEY="secret key for encrypting datasource passwords"
ENABLE_AUTH=0
ENABLE_QUERY_PARSER=0
SUPER_ADMIN_PASSWORD=
DATABASE_CONNECTION_TIMEOUT_MS=
DATABASE_POOL_SIZE=
Expand Down
1 change: 1 addition & 0 deletions api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Add a `.env` file based on `.env.sample`
- `CORS_ALLOW_ORIGIN` for configuring cors. separate multiple origins by `;`. Defaults to `http://localhost`
- `SECRET_KEY` for encrypting and decrypting passwords used in datasource configurations
- `ENABLE_AUTH` Whether to add authentication and authorization to routes. 0 = disabled, 1 = enabled
- `ENABLE_QUERY_PARSER` Whether to enable Server-Side Query parsing. 0 = disabled, 1 = enabled
- `SUPER_ADMIN_PASSWORD` The password which will be configured for the superadmin account during migration. Must be configured before migration is run. If value is not set, password will be 'secret'
- `DATABASE_CONNECTION_TIMEOUT_MS` for configuration the time after which the db connection will timeout in milliseconds. Default is 30000ms (30 seconds)
- `DATABASE_POOL_SIZE` for configuration the maximum number of clients in the pool
Expand Down
129 changes: 122 additions & 7 deletions api/src/api_models/dashboard_content.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,118 @@
import { ApiModel, ApiModelProperty, SwaggerDefinitionConstant } from 'swagger-express-ts';
import { IsObject, Length, IsString, IsOptional, ValidateNested, IsUUID, IsIn } from 'class-validator';
import { IsObject, Length, IsString, IsOptional, ValidateNested, IsUUID, IsIn, IsArray } from 'class-validator';
import { Type } from 'class-transformer';
import { Authentication, FilterObject, PaginationRequest, PaginationResponse, SortRequest } from './base';

@ApiModel({
description: 'Definition Query object',
name: 'Query',
})
export class Query {
@IsString()
@ApiModelProperty({
description: 'Query ID',
required: true,
})
id: string;

@IsIn(['postgresql', 'mysql', 'http'])
@ApiModelProperty({
description: 'Datasource type',
required: true,
})
type: 'postgresql' | 'mysql' | 'http';

@IsString()
@ApiModelProperty({
description: 'Datasource key',
required: true,
})
key: string;

@IsString()
@ApiModelProperty({
description: 'Query SQL',
required: true,
})
sql: string;

@IsString()
@ApiModelProperty({
description: 'Query pre-processing',
required: true,
})
pre_process: string;
}

@ApiModel({
description: 'Definition SQL Snippets object',
name: 'Snippet',
})
export class Snippet {
@IsString()
@ApiModelProperty({
description: 'Snippet ID',
required: true,
})
key: string;

@IsString()
@ApiModelProperty({
description: 'Snippet definition',
required: true,
})
value: string;
}

@ApiModel({
description: 'Content definition object',
name: 'ContentDefinition',
})
export class ContentDefinition {
@IsArray()
@Type(() => Query)
@ValidateNested({ each: true })
@ApiModelProperty({
description: 'Content query definitions',
required: true,
model: 'Query',
})
queries: Query[];

@IsArray()
@Type(() => Snippet)
@ValidateNested({ each: true })
@ApiModelProperty({
description: 'Content sql snippet definitions',
required: true,
model: 'Snippet',
})
sqlSnippets: Snippet[];
}

@ApiModel({
description: 'Content object',
name: 'Content',
})
export class Content {
@IsObject()
@Type(() => ContentDefinition)
@ValidateNested({ each: true })
@ApiModelProperty({
description: 'Content definitions',
required: true,
model: 'ContentDefinition',
})
definition: ContentDefinition;

@IsString()
@ApiModelProperty({
description: 'Content schema version',
required: true,
})
version: string;
}

@ApiModel({
description: 'Dashboard content entity',
name: 'DashboardContent',
Expand All @@ -23,11 +133,12 @@ export class DashboardContent {
})
name: string;

@Type(() => Content)
@ApiModelProperty({
description: 'content of the dashboard stored in json object format',
type: SwaggerDefinitionConstant.JSON,
model: 'Content',
})
content: object | null;
content: Content;

@ApiModelProperty({
description: 'Create time',
Expand Down Expand Up @@ -176,12 +287,14 @@ export class DashboardContentCreateRequest {
name: string;

@IsObject()
@Type(() => Content)
@ValidateNested({ each: true })
@ApiModelProperty({
description: 'content stored in json object format',
required: true,
type: SwaggerDefinitionConstant.JSON,
model: 'Content',
})
content: Record<string, any>;
content: Content;

@IsOptional()
@Type(() => Authentication)
Expand Down Expand Up @@ -217,12 +330,14 @@ export class DashboardContentUpdateRequest {

@IsOptional()
@IsObject()
@Type(() => Content)
@ValidateNested({ each: true })
@ApiModelProperty({
description: 'content of the dashboard stored in json object format',
required: false,
type: SwaggerDefinitionConstant.JSON,
model: 'Content',
})
content?: Record<string, any>;
content?: Content;

@IsOptional()
@Type(() => Authentication)
Expand Down
12 changes: 11 additions & 1 deletion api/src/api_models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
ApiKeyIDRequest,
} from './api';
import { Role, RolePermission, RoleCreateOrUpdateRequest, RoleIDRequest } from './role';
import { QueryRequest, HttpParams } from './query';
import { QueryParams, QueryRequest, HttpParams, QueryStructureRequest } from './query';
import { Job, JobFilterObject, JobListRequest, JobPaginationResponse, JobSortObject, JobRunRequest } from './job';
import { Config, ConfigDescription, ConfigGetRequest, ConfigUpdateRequest } from './config';
import {
Expand Down Expand Up @@ -74,6 +74,10 @@ import {
DashboardContentSortObject,
DashboardContentIDRequest,
DashboardContentUpdateRequest,
Content,
ContentDefinition,
Query,
Snippet,
} from './dashboard_content';
import {
DashboardContentChangelog,
Expand Down Expand Up @@ -154,8 +158,10 @@ export default {
RoleCreateOrUpdateRequest,
RoleIDRequest,

QueryParams,
QueryRequest,
HttpParams,
QueryStructureRequest,

Job,
JobFilterObject,
Expand Down Expand Up @@ -192,6 +198,10 @@ export default {
DashboardContentSortObject,
DashboardContentIDRequest,
DashboardContentUpdateRequest,
Content,
ContentDefinition,
Query,
Snippet,

DashboardContentChangelog,
DashboardContentChangelogFilterObject,
Expand Down
112 changes: 111 additions & 1 deletion api/src/api_models/query.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
import { Type } from 'class-transformer';
import { IsBoolean, IsIn, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
import { IsBoolean, IsIn, IsNumber, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
import { ApiModel, ApiModelProperty, SwaggerDefinitionConstant } from 'swagger-express-ts';
import { Authentication } from './base';

@ApiModel({
description: 'Query params object',
name: 'QueryParams',
})
export class QueryParams {
@IsObject()
@ApiModelProperty({
description: 'Query filter params',
required: true,
type: SwaggerDefinitionConstant.JSON,
})
filters: Record<string, any>;

@IsObject()
@ApiModelProperty({
description: 'Query context params',
required: true,
type: SwaggerDefinitionConstant.JSON,
})
context: Record<string, any>;
}

@ApiModel({
description: 'Query object',
name: 'QueryRequest',
Expand Down Expand Up @@ -31,6 +53,30 @@ export class QueryRequest {
})
query: string;

@IsString()
@ApiModelProperty({
description: 'id of the dashboard content',
required: true,
})
content_id: string;

@IsString()
@ApiModelProperty({
description: 'id of the query defined in dashboard content',
required: true,
})
query_id: string;

@IsObject()
@Type(() => QueryParams)
@ValidateNested({ each: true })
@ApiModelProperty({
description: 'Query params',
required: true,
model: 'QueryParams',
})
params: QueryParams;

@IsOptional()
@IsObject()
@ApiModelProperty({
Expand Down Expand Up @@ -109,3 +155,67 @@ export class HttpParams {
})
url: string;
}

@ApiModel({
description: 'Query Structure object',
name: 'QueryStructureRequest',
})
export class QueryStructureRequest {
@IsIn(['TABLES', 'COLUMNS', 'DATA', 'INDEXES', 'COUNT'])
@ApiModelProperty({
description: `type of query.
TABLES = get all tables in database
COLUMNS = get column structure of table
DATA = get data of table
INDEXES = get indexes of table
COUNT = get total number of rows in table`,
required: true,
enum: ['TABLES', 'COLUMNS', 'DATA', 'INDEXES', 'COUNT'],
})
query_type: 'TABLES' | 'COLUMNS' | 'DATA' | 'INDEXES' | 'COUNT';

@IsIn(['postgresql', 'mysql'])
@ApiModelProperty({
description: 'datasource type of query',
required: true,
enum: ['postgresql', 'mysql'],
})
type: 'postgresql' | 'mysql';

@IsString()
@ApiModelProperty({
description: 'datasource key',
required: true,
})
key: string;

@IsString()
@ApiModelProperty({
description: 'table schema',
required: true,
})
table_schema: string;

@IsString()
@ApiModelProperty({
description: 'table schema',
required: true,
})
table_name: string;

@IsNumber()
@IsOptional()
@ApiModelProperty({
description: 'Limit of query results. Default = 20',
required: false,
})
limit?: number;

@IsNumber()
@IsOptional()
@ApiModelProperty({
description: 'Offset of query results, Default = 0',
required: false,
})
offset?: number;
}
Loading

0 comments on commit 3595465

Please sign in to comment.