2022-01-28 17:55:09 +01:00
package queryhistory
import (
"net/http"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
2022-04-29 09:55:33 +02:00
"github.com/grafana/grafana/pkg/tsdb/legacydata"
2022-02-04 16:14:36 +01:00
"github.com/grafana/grafana/pkg/util"
2022-01-28 17:55:09 +01:00
"github.com/grafana/grafana/pkg/web"
)
func ( s * QueryHistoryService ) registerAPIEndpoints () {
s . RouteRegister . Group ( "/api/query-history" , func ( entities routing . RouteRegister ) {
entities . Post ( "/" , middleware . ReqSignedIn , routing . Wrap ( s . createHandler ))
2022-03-07 12:28:04 +01:00
entities . Get ( "/" , middleware . ReqSignedIn , routing . Wrap ( s . searchHandler ))
2022-02-04 16:14:36 +01:00
entities . Delete ( "/:uid" , middleware . ReqSignedIn , routing . Wrap ( s . deleteHandler ))
2022-02-23 17:03:04 +01:00
entities . Post ( "/star/:uid" , middleware . ReqSignedIn , routing . Wrap ( s . starHandler ))
entities . Delete ( "/star/:uid" , middleware . ReqSignedIn , routing . Wrap ( s . unstarHandler ))
2022-02-15 15:43:17 +01:00
entities . Patch ( "/:uid" , middleware . ReqSignedIn , routing . Wrap ( s . patchCommentHandler ))
2022-04-14 09:33:41 +02:00
// Remove migrate endpoint in Grafana v10 as breaking change
entities . Post ( "/migrate" , middleware . ReqSignedIn , routing . Wrap ( s . migrateHandler ))
2022-01-28 17:55:09 +01:00
})
}
2022-07-27 16:54:37 +03:00
// swagger:route POST /query-history query_history createQuery
//
// Add query to query history.
//
// Adds new query to query history.
//
// Responses:
// 200: getQueryHistoryResponse
// 400: badRequestError
// 401: unauthorisedError
// 500: internalServerError
2022-01-28 17:55:09 +01:00
func ( s * QueryHistoryService ) createHandler ( c * models . ReqContext ) response . Response {
cmd := CreateQueryInQueryHistoryCommand {}
if err := web . Bind ( c . Req , & cmd ); err != nil {
return response . Error ( http . StatusBadRequest , "bad request data" , err )
}
2022-02-04 16:14:36 +01:00
query , err := s . CreateQueryInQueryHistory ( c . Req . Context (), c . SignedInUser , cmd )
2022-01-28 17:55:09 +01:00
if err != nil {
2022-02-04 16:14:36 +01:00
return response . Error ( http . StatusInternalServerError , "Failed to create query history" , err )
2022-01-28 17:55:09 +01:00
}
2022-02-04 16:14:36 +01:00
return response . JSON ( http . StatusOK , QueryHistoryResponse { Result : query })
}
2022-07-27 16:54:37 +03:00
// swagger:route GET /query-history query_history searchQueries
//
// Query history search.
//
// Returns a list of queries in the query history that matches the search criteria.
// Query history search supports pagination. Use the `limit` parameter to control the maximum number of queries returned; the default limit is 100.
// You can also use the `page` query parameter to fetch queries from any page other than the first one.
//
// Responses:
// 200: getQueryHistorySearchResponse
// 401: unauthorisedError
// 500: internalServerError
2022-03-07 12:28:04 +01:00
func ( s * QueryHistoryService ) searchHandler ( c * models . ReqContext ) response . Response {
2022-04-29 09:55:33 +02:00
timeRange := legacydata . NewDataTimeRange ( c . Query ( "from" ), c . Query ( "to" ))
2022-03-07 12:28:04 +01:00
query := SearchInQueryHistoryQuery {
DatasourceUIDs : c . QueryStrings ( "datasourceUid" ),
SearchString : c . Query ( "searchString" ),
OnlyStarred : c . QueryBoolWithDefault ( "onlyStarred" , false ),
Sort : c . Query ( "sort" ),
Page : c . QueryInt ( "page" ),
Limit : c . QueryInt ( "limit" ),
2022-04-29 09:55:33 +02:00
From : timeRange . GetFromAsSecondsEpoch (),
To : timeRange . GetToAsSecondsEpoch (),
2022-03-07 12:28:04 +01:00
}
result , err := s . SearchInQueryHistory ( c . Req . Context (), c . SignedInUser , query )
if err != nil {
return response . Error ( http . StatusInternalServerError , "Failed to get query history" , err )
}
return response . JSON ( http . StatusOK , QueryHistorySearchResponse { Result : result })
}
2022-07-27 16:54:37 +03:00
// swagger:route DELETE /query-history/{query_history_uid} query_history deleteQuery
//
// Delete query in query history.
//
// Deletes an existing query in query history as specified by the UID. This operation cannot be reverted.
//
// Responses:
// 200: getQueryHistoryDeleteQueryResponse
// 401: unauthorisedError
// 500: internalServerError
2022-02-04 16:14:36 +01:00
func ( s * QueryHistoryService ) deleteHandler ( c * models . ReqContext ) response . Response {
queryUID := web . Params ( c . Req )[ ":uid" ]
2022-02-23 17:03:04 +01:00
if len ( queryUID ) > 0 && ! util . IsValidShortUID ( queryUID ) {
2022-02-04 16:14:36 +01:00
return response . Error ( http . StatusNotFound , "Query in query history not found" , nil )
}
id , err := s . DeleteQueryFromQueryHistory ( c . Req . Context (), c . SignedInUser , queryUID )
if err != nil {
return response . Error ( http . StatusInternalServerError , "Failed to delete query from query history" , err )
}
2022-06-13 09:47:40 +02:00
return response . JSON ( http . StatusOK , QueryHistoryDeleteQueryResponse {
2022-02-04 16:14:36 +01:00
Message : "Query deleted" ,
ID : id ,
})
2022-01-28 17:55:09 +01:00
}
2022-02-15 15:43:17 +01:00
2022-07-27 16:54:37 +03:00
// swagger:route PATCH /query-history/{query_history_uid} query_history patchQueryComment
//
// Update comment for query in query history.
//
// Updates comment for query in query history as specified by the UID.
//
// Responses:
// 200: getQueryHistoryResponse
// 400: badRequestError
// 401: unauthorisedError
// 500: internalServerError
2022-02-15 15:43:17 +01:00
func ( s * QueryHistoryService ) patchCommentHandler ( c * models . ReqContext ) response . Response {
queryUID := web . Params ( c . Req )[ ":uid" ]
2022-02-23 17:03:04 +01:00
if len ( queryUID ) > 0 && ! util . IsValidShortUID ( queryUID ) {
2022-02-15 15:43:17 +01:00
return response . Error ( http . StatusNotFound , "Query in query history not found" , nil )
}
cmd := PatchQueryCommentInQueryHistoryCommand {}
if err := web . Bind ( c . Req , & cmd ); err != nil {
return response . Error ( http . StatusBadRequest , "bad request data" , err )
}
query , err := s . PatchQueryCommentInQueryHistory ( c . Req . Context (), c . SignedInUser , queryUID , cmd )
if err != nil {
return response . Error ( http . StatusInternalServerError , "Failed to update comment of query in query history" , err )
}
return response . JSON ( http . StatusOK , QueryHistoryResponse { Result : query })
}
2022-02-23 17:03:04 +01:00
2022-07-27 16:54:37 +03:00
// swagger:route POST /query-history/star/{query_history_uid} query_history starQuery
//
// Add star to query in query history.
//
// Adds star to query in query history as specified by the UID.
//
// Responses:
// 200: getQueryHistoryResponse
// 401: unauthorisedError
// 500: internalServerError
2022-02-23 17:03:04 +01:00
func ( s * QueryHistoryService ) starHandler ( c * models . ReqContext ) response . Response {
queryUID := web . Params ( c . Req )[ ":uid" ]
if len ( queryUID ) > 0 && ! util . IsValidShortUID ( queryUID ) {
return response . Error ( http . StatusNotFound , "Query in query history not found" , nil )
}
query , err := s . StarQueryInQueryHistory ( c . Req . Context (), c . SignedInUser , queryUID )
if err != nil {
return response . Error ( http . StatusInternalServerError , "Failed to star query in query history" , err )
}
return response . JSON ( http . StatusOK , QueryHistoryResponse { Result : query })
}
2022-07-27 16:54:37 +03:00
// swagger:route DELETE /query-history/star/{query_history_uid} query_history unstarQuery
//
// Remove star to query in query history.
//
// Removes star from query in query history as specified by the UID.
//
// Responses:
// 200: getQueryHistoryResponse
// 401: unauthorisedError
// 500: internalServerError
2022-02-23 17:03:04 +01:00
func ( s * QueryHistoryService ) unstarHandler ( c * models . ReqContext ) response . Response {
queryUID := web . Params ( c . Req )[ ":uid" ]
if len ( queryUID ) > 0 && ! util . IsValidShortUID ( queryUID ) {
return response . Error ( http . StatusNotFound , "Query in query history not found" , nil )
}
query , err := s . UnstarQueryInQueryHistory ( c . Req . Context (), c . SignedInUser , queryUID )
if err != nil {
return response . Error ( http . StatusInternalServerError , "Failed to unstar query in query history" , err )
}
return response . JSON ( http . StatusOK , QueryHistoryResponse { Result : query })
}
2022-04-14 09:33:41 +02:00
2022-07-27 16:54:37 +03:00
// swagger:route POST /query-history/migrate query_history migrateQueries
//
// Migrate queries to query history.
//
// Adds multiple queries to query history.
//
// Responses:
// 200: getQueryHistoryMigrationResponse
// 400: badRequestError
// 401: unauthorisedError
// 500: internalServerError
2022-04-14 09:33:41 +02:00
func ( s * QueryHistoryService ) migrateHandler ( c * models . ReqContext ) response . Response {
cmd := MigrateQueriesToQueryHistoryCommand {}
if err := web . Bind ( c . Req , & cmd ); err != nil {
return response . Error ( http . StatusBadRequest , "bad request data" , err )
}
totalCount , starredCount , err := s . MigrateQueriesToQueryHistory ( c . Req . Context (), c . SignedInUser , cmd )
if err != nil {
return response . Error ( http . StatusInternalServerError , "Failed to migrate query history" , err )
}
return response . JSON ( http . StatusOK , QueryHistoryMigrationResponse { Message : "Query history successfully migrated" , TotalCount : totalCount , StarredCount : starredCount })
}
2022-07-27 16:54:37 +03:00
// swagger:parameters starQuery patchQueryComment deleteQuery unstarQuery
type QueryHistoryByUID struct {
// in:path
// required:true
UID string `json:"query_history_uid"`
}
// swagger:parameters searchQueries
type SearchQueriesParams struct {
// List of data source UIDs to search for
// in:query
// required: false
// type: array
// collectionFormat: multi
DatasourceUid [] string `json:"datasourceUid"`
// Text inside query or comments that is searched for
// in:query
// required: false
SearchString string `json:"searchString"`
// Flag indicating if only starred queries should be returned
// in:query
// required: false
OnlyStarred bool `json:"onlyStarred"`
// Sort method
// in:query
// required: false
// default: time-desc
// Enum: time-desc,time-asc
Sort string `json:"sort"`
// Use this parameter to access hits beyond limit. Numbering starts at 1. limit param acts as page size.
// in:query
// required: false
Page int `json:"page"`
// Limit the number of returned results
// in:query
// required: false
Limit int `json:"limit"`
// From range for the query history search
// in:query
// required: false
From int64 `json:"from"`
// To range for the query history search
// in:query
// required: false
To int64 `json:"to"`
}
// swagger:parameters createQuery
type CreateQueryParams struct {
// in:body
// required:true
Body CreateQueryInQueryHistoryCommand `json:"body"`
}
// swagger:parameters patchQueryComment
type PatchQueryCommentParams struct {
// in:body
// required:true
Body PatchQueryCommentInQueryHistoryCommand `json:"body"`
}
// swagger:parameters migrateQueries
type MigrateQueriesParams struct {
// in:body
// required:true
Body MigrateQueriesToQueryHistoryCommand `json:"body"`
}
//swagger:response getQueryHistorySearchResponse
type GetQueryHistorySearchResponse struct {
// in: body
Body QueryHistorySearchResponse `json:"body"`
}
// swagger:response getQueryHistoryResponse
type GetQueryHistoryResponse struct {
// in: body
Body QueryHistoryResponse `json:"body"`
}
// swagger:response getQueryHistoryDeleteQueryResponse
type GetQueryHistoryDeleteQueryResponse struct {
// in: body
Body QueryHistoryDeleteQueryResponse `json:"body"`
}
// swagger:response getQueryHistoryMigrationResponse
type GetQueryHistoryMigrationResponse struct {
// in: body
Body QueryHistoryMigrationResponse `json:"body"`
}