231 lines
6.5 KiB
Go
231 lines
6.5 KiB
Go
|
package explorer
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/google/uuid"
|
||
|
"github.com/jmoiron/sqlx"
|
||
|
"go.signoz.io/signoz/pkg/query-service/auth"
|
||
|
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
|
||
|
)
|
||
|
|
||
|
var db *sqlx.DB
|
||
|
|
||
|
type SavedView struct {
|
||
|
UUID string `json:"uuid" db:"uuid"`
|
||
|
Name string `json:"name" db:"name"`
|
||
|
Category string `json:"category" db:"category"`
|
||
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||
|
CreatedBy string `json:"created_by" db:"created_by"`
|
||
|
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||
|
UpdatedBy string `json:"updated_by" db:"updated_by"`
|
||
|
SourcePage string `json:"source_page" db:"source_page"`
|
||
|
Tags string `json:"tags" db:"tags"`
|
||
|
Data string `json:"data" db:"data"`
|
||
|
ExtraData string `json:"extra_data" db:"extra_data"`
|
||
|
}
|
||
|
|
||
|
// InitWithDSN sets up setting up the connection pool global variable.
|
||
|
func InitWithDSN(dataSourceName string) (*sqlx.DB, error) {
|
||
|
var err error
|
||
|
|
||
|
db, err = sqlx.Open("sqlite3", dataSourceName)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
tableSchema := `CREATE TABLE IF NOT EXISTS saved_views (
|
||
|
uuid TEXT PRIMARY KEY,
|
||
|
name TEXT NOT NULL,
|
||
|
category TEXT NOT NULL,
|
||
|
created_at datetime NOT NULL,
|
||
|
created_by TEXT,
|
||
|
updated_at datetime NOT NULL,
|
||
|
updated_by TEXT,
|
||
|
source_page TEXT NOT NULL,
|
||
|
tags TEXT,
|
||
|
data TEXT NOT NULL,
|
||
|
extra_data TEXT
|
||
|
);`
|
||
|
|
||
|
_, err = db.Exec(tableSchema)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error in creating saved views table: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
return db, nil
|
||
|
}
|
||
|
|
||
|
func InitWithDB(sqlDB *sqlx.DB) {
|
||
|
db = sqlDB
|
||
|
}
|
||
|
|
||
|
func GetViews() ([]*v3.SavedView, error) {
|
||
|
var views []SavedView
|
||
|
err := db.Select(&views, "SELECT * FROM saved_views")
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error in getting saved views: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
var savedViews []*v3.SavedView
|
||
|
for _, view := range views {
|
||
|
var compositeQuery v3.CompositeQuery
|
||
|
err = json.Unmarshal([]byte(view.Data), &compositeQuery)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error in unmarshalling explorer query data: %s", err.Error())
|
||
|
}
|
||
|
savedViews = append(savedViews, &v3.SavedView{
|
||
|
UUID: view.UUID,
|
||
|
Name: view.Name,
|
||
|
Category: view.Category,
|
||
|
CreatedAt: view.CreatedAt,
|
||
|
CreatedBy: view.CreatedBy,
|
||
|
UpdatedAt: view.UpdatedAt,
|
||
|
UpdatedBy: view.UpdatedBy,
|
||
|
Tags: strings.Split(view.Tags, ","),
|
||
|
SourcePage: view.SourcePage,
|
||
|
CompositeQuery: &compositeQuery,
|
||
|
ExtraData: view.ExtraData,
|
||
|
})
|
||
|
}
|
||
|
return savedViews, nil
|
||
|
}
|
||
|
|
||
|
func GetViewsForFilters(sourcePage string, name string, category string) ([]*v3.SavedView, error) {
|
||
|
var views []SavedView
|
||
|
var err error
|
||
|
if len(category) == 0 {
|
||
|
err = db.Select(&views, "SELECT * FROM saved_views WHERE source_page = ? AND name LIKE ?", sourcePage, "%"+name+"%")
|
||
|
} else {
|
||
|
err = db.Select(&views, "SELECT * FROM saved_views WHERE source_page = ? AND category LIKE ? AND name LIKE ?", sourcePage, "%"+category+"%", "%"+name+"%")
|
||
|
}
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error in getting saved views: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
var savedViews []*v3.SavedView
|
||
|
for _, view := range views {
|
||
|
var compositeQuery v3.CompositeQuery
|
||
|
err = json.Unmarshal([]byte(view.Data), &compositeQuery)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error in unmarshalling explorer query data: %s", err.Error())
|
||
|
}
|
||
|
savedViews = append(savedViews, &v3.SavedView{
|
||
|
UUID: view.UUID,
|
||
|
Name: view.Name,
|
||
|
CreatedAt: view.CreatedAt,
|
||
|
CreatedBy: view.CreatedBy,
|
||
|
UpdatedAt: view.UpdatedAt,
|
||
|
UpdatedBy: view.UpdatedBy,
|
||
|
Tags: strings.Split(view.Tags, ","),
|
||
|
SourcePage: view.SourcePage,
|
||
|
CompositeQuery: &compositeQuery,
|
||
|
ExtraData: view.ExtraData,
|
||
|
})
|
||
|
}
|
||
|
return savedViews, nil
|
||
|
}
|
||
|
|
||
|
func CreateView(ctx context.Context, view v3.SavedView) (string, error) {
|
||
|
data, err := json.Marshal(view.CompositeQuery)
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("error in marshalling explorer query data: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
uuid_ := view.UUID
|
||
|
|
||
|
if uuid_ == "" {
|
||
|
uuid_ = uuid.New().String()
|
||
|
}
|
||
|
createdAt := time.Now()
|
||
|
updatedAt := time.Now()
|
||
|
|
||
|
email, err := auth.GetEmailFromJwt(ctx)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
createBy := email
|
||
|
updatedBy := email
|
||
|
|
||
|
_, err = db.Exec(
|
||
|
"INSERT INTO saved_views (uuid, name, category, created_at, created_by, updated_at, updated_by, source_page, tags, data, extra_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||
|
uuid_,
|
||
|
view.Name,
|
||
|
view.Category,
|
||
|
createdAt,
|
||
|
createBy,
|
||
|
updatedAt,
|
||
|
updatedBy,
|
||
|
view.SourcePage,
|
||
|
strings.Join(view.Tags, ","),
|
||
|
data,
|
||
|
view.ExtraData,
|
||
|
)
|
||
|
if err != nil {
|
||
|
return "", fmt.Errorf("error in creating saved view: %s", err.Error())
|
||
|
}
|
||
|
return uuid_, nil
|
||
|
}
|
||
|
|
||
|
func GetView(uuid_ string) (*v3.SavedView, error) {
|
||
|
var view SavedView
|
||
|
err := db.Get(&view, "SELECT * FROM saved_views WHERE uuid = ?", uuid_)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error in getting saved view: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
var compositeQuery v3.CompositeQuery
|
||
|
err = json.Unmarshal([]byte(view.Data), &compositeQuery)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("error in unmarshalling explorer query data: %s", err.Error())
|
||
|
}
|
||
|
return &v3.SavedView{
|
||
|
UUID: view.UUID,
|
||
|
Name: view.Name,
|
||
|
Category: view.Category,
|
||
|
CreatedAt: view.CreatedAt,
|
||
|
CreatedBy: view.CreatedBy,
|
||
|
UpdatedAt: view.UpdatedAt,
|
||
|
UpdatedBy: view.UpdatedBy,
|
||
|
SourcePage: view.SourcePage,
|
||
|
Tags: strings.Split(view.Tags, ","),
|
||
|
CompositeQuery: &compositeQuery,
|
||
|
ExtraData: view.ExtraData,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func UpdateView(ctx context.Context, uuid_ string, view v3.SavedView) error {
|
||
|
data, err := json.Marshal(view.CompositeQuery)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("error in marshalling explorer query data: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
email, err := auth.GetEmailFromJwt(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
updatedAt := time.Now()
|
||
|
updatedBy := email
|
||
|
|
||
|
_, err = db.Exec("UPDATE saved_views SET updated_at = ?, updated_by = ?, name = ?, category = ?, source_page = ?, tags = ?, data = ?, extra_data = ? WHERE uuid = ?",
|
||
|
updatedAt, updatedBy, view.Name, view.Category, view.SourcePage, strings.Join(view.Tags, ","), data, view.ExtraData, uuid_)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("error in updating saved view: %s", err.Error())
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func DeleteView(uuid_ string) error {
|
||
|
_, err := db.Exec("DELETE FROM saved_views WHERE uuid = ?", uuid_)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("error in deleting explorer query: %s", err.Error())
|
||
|
}
|
||
|
return nil
|
||
|
}
|