From aefeef641794f61c1374b844ba1939a5ba992a4b Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Fri, 1 Nov 2024 05:05:24 +0530 Subject: [PATCH 1/4] hacked working results --- cmd/queryList.go | 2 +- pkg/model/savedQueries.go | 224 ++++++++++++++++++++++++++++++++------ 2 files changed, 194 insertions(+), 32 deletions(-) diff --git a/cmd/queryList.go b/cmd/queryList.go index 9af5bad..64a6060 100644 --- a/cmd/queryList.go +++ b/cmd/queryList.go @@ -82,7 +82,7 @@ func savedQueryToPbQuery(query string, start string, end string) { } queryTemplate := `pb query run ` + query + timeStamps fmt.Printf("\nCopy and paste the command") - fmt.Printf("\n\n%s\n\n", queryTemplate) + fmt.Printf("%s", queryTemplate) } // Parses all UTC time format from string to time interface diff --git a/pkg/model/savedQueries.go b/pkg/model/savedQueries.go index 064bf24..3a67e86 100644 --- a/pkg/model/savedQueries.go +++ b/pkg/model/savedQueries.go @@ -16,10 +16,12 @@ package model import ( + "bytes" "encoding/json" "fmt" "io" "net/http" + "os/exec" "strings" "time" @@ -39,17 +41,47 @@ const ( ) var ( - docStyle = lipgloss.NewStyle().Margin(1, 2) + docStyle = lipgloss.NewStyle().Margin(1, 2, 3) deleteSavedQueryState = false ) -// FilterDetails represents the struct of filter data fetched from the server -type FilterDetails struct { - SavedQueryID string `json:"filter_id"` - SavedQueryName string `json:"filter_name"` - StreamName string `json:"stream_name"` - QueryField map[string]interface{} `json:"query"` - TimeFilter map[string]interface{} `json:"time_filter"` +type Filter struct { + Version string `json:"version"` + UserID string `json:"user_id"` + StreamName string `json:"stream_name"` + FilterName string `json:"filter_name"` + FilterID string `json:"filter_id"` + Query Query `json:"query"` + TimeFilter TimeFilter `json:"time_filter"` +} + +type TimeFilter struct { + To string `json:"to"` + From string `json:"from"` +} +type Query struct { + FilterType string `json:"filter_type"` + FilterQuery *string `json:"filter_query,omitempty"` // SQL query as string or null + FilterBuilder *FilterBuilder `json:"filter_builder,omitempty"` // Builder or null +} + +type FilterBuilder struct { + ID string `json:"id"` + Combinator string `json:"combinator"` + Rules []RuleSet `json:"rules"` +} + +type RuleSet struct { + ID string `json:"id"` + Combinator string `json:"combinator"` + Rules []Rule `json:"rules"` +} + +type Rule struct { + ID string `json:"id"` + Field string `json:"field"` + Value string `json:"value"` + Operator string `json:"operator"` } // Item represents the struct of the saved query item @@ -157,13 +189,50 @@ func (i Item) StartTime() string { return i.from } func (i Item) EndTime() string { return i.to } type modelSavedQueries struct { - list list.Model + list list.Model + commandOutput string } func (m modelSavedQueries) Init() tea.Cmd { return nil } +// Define a message type for command results +type commandResultMsg string + +// RunCommand executes a command based on the selected item +func RunCommand(item Item) (string, error) { + // Clean the description by removing any backslashes + cleaned := strings.ReplaceAll(item.desc, "\\", "") // Remove any backslashes + cleaned = strings.TrimSpace(cleaned) // Trim any leading/trailing whitespace + cleanedStr := strings.ReplaceAll(cleaned, `"`, "") + + // Prepare the command with the cleaned SQL query + fmt.Printf("Executing command: pb query run %s\n", cleanedStr) // Log the command for debugging + //qExecuting command: pb query run "SELECT * FROM "frontend" LIMIT 1000" + // Execute the command without adding extra quotes + // TODO: add timestamp + cmd := exec.Command("pb", "query", "run", cleanedStr) // Directly pass cleaned + + // Set up pipes to capture stdout and stderr + var output bytes.Buffer + cmd.Stdout = &output + cmd.Stderr = &output // Capture both stdout and stderr in the same buffer + + // Run the command + err := cmd.Run() + if err != nil { + return "", fmt.Errorf("error executing command: %v, output: %s", err, output.String()) + } + + // Log the raw output for debugging + fmt.Printf("Raw output: %s\n", output.String()) + + time.Sleep(10 * time.Second) + // Return the output as a string + return output.String(), nil +} + func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: @@ -172,7 +241,17 @@ func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } if msg.String() == "a" || msg.Type == tea.KeyEnter { selectedQueryApply = m.list.SelectedItem().(Item) - return m, tea.Quit + + // Run the command and capture the output in a function + cmd := func() tea.Msg { + output, err := RunCommand(selectedQueryApply) + if err != nil { + return commandResultMsg(fmt.Sprintf("Error: %s", err)) + } + return commandResultMsg(output) + } + + return m, cmd } if msg.String() == "d" { deleteSavedQueryState = true @@ -192,6 +271,11 @@ func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.WindowSizeMsg: h, v := docStyle.GetFrameSize() m.list.SetSize(msg.Width-h, msg.Height-v) + + // Handle the command result + case commandResultMsg: + m.commandOutput = string(msg) // Set the output in the model for display + return m, nil } var cmd tea.Cmd @@ -200,7 +284,10 @@ func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } func (m modelSavedQueries) View() string { - return docStyle.Render(m.list.View()) + if m.commandOutput != "" { + return fmt.Sprintf("Command output:%s\nPress any key to go back.", m.commandOutput) + } + return m.list.View() } // SavedQueriesMenu is a TUI which lists all available saved queries for the active user (only SQL queries ) @@ -225,6 +312,78 @@ func SavedQueriesMenu() *tea.Program { return tea.NewProgram(m, tea.WithAltScreen()) } +// // Convert a saved query to executable pb query +// func savedQueryToPbQuery(query string, start string, end string) string { +// var timeStamps string +// if start == "" || end == "" { +// timeStamps = `` +// } else { +// startFormatted := formatToRFC3339(start) +// endFormatted := formatToRFC3339(end) +// timeStamps = ` --from=` + startFormatted + ` --to=` + endFormatted +// } +// queryTemplate := "pb query run" + query + timeStamps +// fmt.Printf("\nCopy and paste the command") +// fmt.Printf("%s", queryTemplate) +// return queryTemplate +// } + +// // Parses all UTC time format from string to time interface +// func parseTimeToFormat(input string) (time.Time, error) { +// // List of possible formats +// formats := []string{ +// time.RFC3339, +// "2006-01-02 15:04:05", +// "2006-01-02", +// "01/02/2006 15:04:05", +// "02-Jan-2006 15:04:05 MST", +// "2006-01-02T15:04:05Z", +// "02-Jan-2006", +// } + +// var err error +// var t time.Time + +// for _, format := range formats { +// t, err = time.Parse(format, input) +// if err == nil { +// return t, nil +// } +// } + +// return t, fmt.Errorf("unable to parse time: %s", input) +// } + +// // Converts to RFC3339 +// func convertTime(input string) (string, error) { +// t, err := parseTimeToFormat(input) +// if err != nil { +// return "", err +// } + +// return t.Format(time.RFC3339), nil +// } + +// // Converts User inputted time to string type RFC3339 time +// func formatToRFC3339(time string) string { +// var formattedTime string +// if len(strings.Fields(time)) > 1 { +// newTime := strings.Fields(time)[0:2] +// rfc39990time, err := convertTime(strings.Join(newTime, " ")) +// if err != nil { +// fmt.Println("error formatting time") +// } +// formattedTime = rfc39990time +// } else { +// rfc39990time, err := convertTime(time) +// if err != nil { +// fmt.Println("error formatting time") +// } +// formattedTime = rfc39990time +// } +// return formattedTime +// } + // fetchFilters fetches saved SQL queries for the active user from the server func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { endpoint := fmt.Sprintf("%s/%s", profile.URL, "api/v1/filters") @@ -249,7 +408,7 @@ func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { return nil } - var filters []FilterDetails + var filters []Filter err = json.Unmarshal(body, &filters) if err != nil { fmt.Println("Error unmarshalling response:", err) @@ -259,29 +418,32 @@ func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { // This returns only the SQL type filters var userSavedQueries []list.Item for _, filter := range filters { - var userSavedQuery Item - queryBytes, _ := json.Marshal(filter.QueryField["filter_query"]) + //var userSavedQuery Item + + queryBytes, _ := json.Marshal(filter.Query.FilterQuery) + + fmt.Println(string(queryBytes)) // Extract "from" and "to" from time_filter - var from, to string - if fromValue, exists := filter.TimeFilter["from"]; exists { - from = fmt.Sprintf("%v", fromValue) - } - if toValue, exists := filter.TimeFilter["to"]; exists { - to = fmt.Sprintf("%v", toValue) - } + // var from, to string + // if fromValue, exists := filter.TimeFilter["from"]; exists { + // from = fmt.Sprintf("%v", fromValue) + // } + // if toValue, exists := filter.TimeFilter["to"]; exists { + // to = fmt.Sprintf("%v", toValue) + // } // filtering only SQL type filters.. **Filter_name is title and Stream Name is desc - if string(queryBytes) != "null" { - userSavedQuery = Item{ - id: filter.SavedQueryID, - title: filter.SavedQueryName, - stream: filter.StreamName, - desc: string(queryBytes), - from: from, - to: to, - } - userSavedQueries = append(userSavedQueries, userSavedQuery) + //if string(queryBytes) != "null" { + userSavedQuery := Item{ + id: filter.FilterID, + title: filter.FilterName, + stream: filter.StreamName, + desc: string(queryBytes), + from: filter.TimeFilter.From, + to: filter.TimeFilter.To, } + userSavedQueries = append(userSavedQueries, userSavedQuery) + //} } return userSavedQueries } From f66c501a34c4c22b707157548e69a8b00972ef5d Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Fri, 1 Nov 2024 05:07:53 +0530 Subject: [PATCH 2/4] update --- pkg/model/savedQueries.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/model/savedQueries.go b/pkg/model/savedQueries.go index 3a67e86..6cea070 100644 --- a/pkg/model/savedQueries.go +++ b/pkg/model/savedQueries.go @@ -228,9 +228,19 @@ func RunCommand(item Item) (string, error) { // Log the raw output for debugging fmt.Printf("Raw output: %s\n", output.String()) - time.Sleep(10 * time.Second) + // Format the output as pretty-printed JSON + var jsonResponse interface{} + if err := json.Unmarshal(output.Bytes(), &jsonResponse); err != nil { + return "", fmt.Errorf("invalid JSON output: %s, error: %v", output.String(), err) + } + + prettyOutput, err := json.MarshalIndent(jsonResponse, "", " ") + if err != nil { + return "", fmt.Errorf("error formatting JSON output: %v", err) + } + // Return the output as a string - return output.String(), nil + return string(prettyOutput), nil } func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { From 774b136aa84e51dd6c66d4b713bce5238e982604 Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Fri, 1 Nov 2024 19:38:39 +0530 Subject: [PATCH 3/4] fixes --- cmd/queryList.go | 136 ++++++++++++++++++++++++++++-- pkg/model/savedQueries.go | 172 ++++++++------------------------------ 2 files changed, 166 insertions(+), 142 deletions(-) diff --git a/cmd/queryList.go b/cmd/queryList.go index 64a6060..993ffdf 100644 --- a/cmd/queryList.go +++ b/cmd/queryList.go @@ -16,8 +16,12 @@ package cmd import ( + "encoding/json" "fmt" + "io" + "net/http" "os" + "pb/pkg/config" "pb/pkg/model" "strings" "time" @@ -25,15 +29,75 @@ import ( "github.com/spf13/cobra" ) +var outputFlag string + var SavedQueryList = &cobra.Command{ Use: "list", - Example: "pb query list ", + Example: "pb query list [-o | --output]", Short: "List of saved queries", - Long: "\nShow the list of saved quries for active user", + Long: "\nShow the list of saved queries for active user", PreRunE: PreRunDefaultProfile, Run: func(_ *cobra.Command, _ []string) { client := DefaultClient() + // Check if the output flag is set + if outputFlag != "" { + // Display all filters if output flag is set + userConfig, err := config.ReadConfigFromFile() + if err != nil { + fmt.Println("Error reading Default Profile") + } + var userProfile config.Profile + if profile, ok := userConfig.Profiles[userConfig.DefaultProfile]; ok { + userProfile = profile + } + + client := &http.Client{ + Timeout: time.Second * 60, + } + userSavedQueries := fetchFilters(client, &userProfile) + // Collect all filter titles in a slice and join with commas + var filterDetails []string + + if outputFlag == "json" { + // If JSON output is requested, marshal the saved queries to JSON + jsonOutput, err := json.MarshalIndent(userSavedQueries, "", " ") + if err != nil { + fmt.Println("Error converting saved queries to JSON:", err) + return + } + fmt.Println(string(jsonOutput)) + } else { + for _, query := range userSavedQueries { + // Build the line conditionally + var parts []string + if query.Title != "" { + parts = append(parts, query.Title) + } + if query.Stream != "" { + parts = append(parts, query.Stream) + } + if query.Desc != "" { + parts = append(parts, query.Desc) + } + if query.From != "" { + parts = append(parts, query.From) + } + if query.To != "" { + parts = append(parts, query.To) + } + + // Join parts with commas and print each query on a new line + fmt.Println(strings.Join(parts, ", ")) + } + } + // Print all titles as a single line, comma-separated + fmt.Println(strings.Join(filterDetails, " ")) + return + + } + + // Normal Saved Queries Menu if output flag not set p := model.SavedQueriesMenu() if _, err := p.Run(); err != nil { os.Exit(1) @@ -80,9 +144,7 @@ func savedQueryToPbQuery(query string, start string, end string) { endFormatted := formatToRFC3339(end) timeStamps = ` --from=` + startFormatted + ` --to=` + endFormatted } - queryTemplate := `pb query run ` + query + timeStamps - fmt.Printf("\nCopy and paste the command") - fmt.Printf("%s", queryTemplate) + _ = `pb query run ` + query + timeStamps } // Parses all UTC time format from string to time interface @@ -140,3 +202,67 @@ func formatToRFC3339(time string) string { } return formattedTime } + +func init() { + // Add the output flag to the SavedQueryList command + SavedQueryList.Flags().StringVarP(&outputFlag, "output", "o", "", "Output format (text or json)") +} + +type Item struct { + ID string `json:"id"` + Title string `json:"title"` + Stream string `json:"stream"` + Desc string `json:"desc"` + From string `json:"from,omitempty"` + To string `json:"to,omitempty"` +} + +func fetchFilters(client *http.Client, profile *config.Profile) []Item { + endpoint := fmt.Sprintf("%s/%s", profile.URL, "api/v1/filters") + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + fmt.Println("Error creating request:", err) + return nil + } + + req.SetBasicAuth(profile.Username, profile.Password) + req.Header.Add("Content-Type", "application/json") + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error making request:", err) + return nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println("Error reading response body:", err) + return nil + } + + var filters []model.Filter + err = json.Unmarshal(body, &filters) + if err != nil { + fmt.Println("Error unmarshalling response:", err) + return nil + } + + // This returns only the SQL type filters + var userSavedQueries []Item + for _, filter := range filters { + + queryBytes, _ := json.Marshal(filter.Query.FilterQuery) + + userSavedQuery := Item{ + ID: filter.FilterID, + Title: filter.FilterName, + Stream: filter.StreamName, + Desc: string(queryBytes), + From: filter.TimeFilter.From, + To: filter.TimeFilter.To, + } + userSavedQueries = append(userSavedQueries, userSavedQuery) + + } + return userSavedQueries +} diff --git a/pkg/model/savedQueries.go b/pkg/model/savedQueries.go index 6cea070..8e26a40 100644 --- a/pkg/model/savedQueries.go +++ b/pkg/model/savedQueries.go @@ -29,20 +29,20 @@ import ( "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" + "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" ) const ( - applyQueryButton = "a" - deleteQueryButton = "d" - confirmDelete = "y" - cancelDelete = "n" + applyQueryButton = "a" + backButton = "b" + confirmDelete = "y" + cancelDelete = "n" ) var ( - docStyle = lipgloss.NewStyle().Margin(1, 2, 3) - deleteSavedQueryState = false + docStyle = lipgloss.NewStyle().Margin(1, 2, 3) ) type Filter struct { @@ -94,7 +94,6 @@ var ( queryStyle = lipgloss.NewStyle().PaddingLeft(0).Foreground(lipgloss.Color("7")) itemStyle = lipgloss.NewStyle().PaddingLeft(4).Foreground(lipgloss.Color("8")) selectedItemStyle = lipgloss.NewStyle().PaddingLeft(1).Foreground(lipgloss.AdaptiveColor{Light: "16", Dark: "226"}) - confirmModal = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.AdaptiveColor{Light: "16", Dark: "226"}) ) type itemDelegate struct{} @@ -127,32 +126,21 @@ func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list fmt.Fprint(w, fn(tr(i.title)+"\n"+qr(i.desc)+"\n"+str)) } +// Implement itemDelegate ShortHelp to show only relevant bindings. func (d itemDelegate) ShortHelp() []key.Binding { - if deleteSavedQueryState { - return []key.Binding{ - key.NewBinding( - key.WithKeys(confirmDelete), - key.WithHelp(confirmDelete, confirmModal.Render("confirm delete")), - ), - key.NewBinding( - key.WithKeys(cancelDelete), - key.WithHelp(cancelDelete, confirmModal.Render("cancel delete")), - ), - } - } return []key.Binding{ key.NewBinding( key.WithKeys(applyQueryButton), key.WithHelp(applyQueryButton, "apply"), ), key.NewBinding( - key.WithKeys(deleteQueryButton), - key.WithHelp(deleteQueryButton, "delete"), + key.WithKeys(backButton), + key.WithHelp(backButton, "back"), ), } } -// FullHelp returns the extended list of keybindings. +// Implement FullHelp to show only "apply" and "back" key bindings. func (d itemDelegate) FullHelp() [][]key.Binding { return [][]key.Binding{ { @@ -161,8 +149,8 @@ func (d itemDelegate) FullHelp() [][]key.Binding { key.WithHelp(applyQueryButton, "apply"), ), key.NewBinding( - key.WithKeys(deleteQueryButton), - key.WithHelp(deleteQueryButton, "delete"), + key.WithKeys(backButton), + key.WithHelp(backButton, "back"), ), }, } @@ -191,6 +179,7 @@ func (i Item) EndTime() string { return i.to } type modelSavedQueries struct { list list.Model commandOutput string + viewport viewport.Model } func (m modelSavedQueries) Init() tea.Cmd { @@ -209,9 +198,10 @@ func RunCommand(item Item) (string, error) { // Prepare the command with the cleaned SQL query fmt.Printf("Executing command: pb query run %s\n", cleanedStr) // Log the command for debugging - //qExecuting command: pb query run "SELECT * FROM "frontend" LIMIT 1000" - // Execute the command without adding extra quotes - // TODO: add timestamp + + if item.StartTime() != "" && item.EndTime() != "" { + cleanedStr = cleanedStr + " --from=" + item.StartTime() + " --to=" + item.EndTime() + } cmd := exec.Command("pb", "query", "run", cleanedStr) // Directly pass cleaned // Set up pipes to capture stdout and stderr @@ -246,13 +236,12 @@ func RunCommand(item Item) (string, error) { func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: - if msg.String() == "ctrl+c" { + switch msg.String() { + case "ctrl+c": return m, tea.Quit - } - if msg.String() == "a" || msg.Type == tea.KeyEnter { + case "a", "enter": + // Apply the selected query selectedQueryApply = m.list.SelectedItem().(Item) - - // Run the command and capture the output in a function cmd := func() tea.Msg { output, err := RunCommand(selectedQueryApply) if err != nil { @@ -260,31 +249,25 @@ func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } return commandResultMsg(output) } - return m, cmd - } - if msg.String() == "d" { - deleteSavedQueryState = true - return m, nil - } - if msg.String() != "d" { - deleteSavedQueryState = false - } - if msg.String() == "y" { - selectedQueryDelete = m.list.SelectedItem().(Item) - return m, tea.Quit - } - if msg.String() == "n" { - deleteSavedQueryState = false + case "b": // 'b' to go back to the saved query list + m.commandOutput = "" // Clear the command output + m.viewport.SetContent("") // Clear viewport content + m.viewport.GotoTop() // Reset viewport to the top return m, nil + case "down", "j": + m.viewport.LineDown(1) // Scroll down in the viewport + case "up", "k": + m.viewport.LineUp(1) // Scroll up in the viewport } case tea.WindowSizeMsg: h, v := docStyle.GetFrameSize() m.list.SetSize(msg.Width-h, msg.Height-v) - - // Handle the command result + m.viewport.Width = msg.Width - h + m.viewport.Height = msg.Height - v case commandResultMsg: - m.commandOutput = string(msg) // Set the output in the model for display + m.commandOutput = string(msg) + m.viewport.SetContent(m.commandOutput) // Update viewport content with command output return m, nil } @@ -295,7 +278,7 @@ func (m modelSavedQueries) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m modelSavedQueries) View() string { if m.commandOutput != "" { - return fmt.Sprintf("Command output:%s\nPress any key to go back.", m.commandOutput) + return m.viewport.View() } return m.list.View() } @@ -322,78 +305,6 @@ func SavedQueriesMenu() *tea.Program { return tea.NewProgram(m, tea.WithAltScreen()) } -// // Convert a saved query to executable pb query -// func savedQueryToPbQuery(query string, start string, end string) string { -// var timeStamps string -// if start == "" || end == "" { -// timeStamps = `` -// } else { -// startFormatted := formatToRFC3339(start) -// endFormatted := formatToRFC3339(end) -// timeStamps = ` --from=` + startFormatted + ` --to=` + endFormatted -// } -// queryTemplate := "pb query run" + query + timeStamps -// fmt.Printf("\nCopy and paste the command") -// fmt.Printf("%s", queryTemplate) -// return queryTemplate -// } - -// // Parses all UTC time format from string to time interface -// func parseTimeToFormat(input string) (time.Time, error) { -// // List of possible formats -// formats := []string{ -// time.RFC3339, -// "2006-01-02 15:04:05", -// "2006-01-02", -// "01/02/2006 15:04:05", -// "02-Jan-2006 15:04:05 MST", -// "2006-01-02T15:04:05Z", -// "02-Jan-2006", -// } - -// var err error -// var t time.Time - -// for _, format := range formats { -// t, err = time.Parse(format, input) -// if err == nil { -// return t, nil -// } -// } - -// return t, fmt.Errorf("unable to parse time: %s", input) -// } - -// // Converts to RFC3339 -// func convertTime(input string) (string, error) { -// t, err := parseTimeToFormat(input) -// if err != nil { -// return "", err -// } - -// return t.Format(time.RFC3339), nil -// } - -// // Converts User inputted time to string type RFC3339 time -// func formatToRFC3339(time string) string { -// var formattedTime string -// if len(strings.Fields(time)) > 1 { -// newTime := strings.Fields(time)[0:2] -// rfc39990time, err := convertTime(strings.Join(newTime, " ")) -// if err != nil { -// fmt.Println("error formatting time") -// } -// formattedTime = rfc39990time -// } else { -// rfc39990time, err := convertTime(time) -// if err != nil { -// fmt.Println("error formatting time") -// } -// formattedTime = rfc39990time -// } -// return formattedTime -// } - // fetchFilters fetches saved SQL queries for the active user from the server func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { endpoint := fmt.Sprintf("%s/%s", profile.URL, "api/v1/filters") @@ -429,21 +340,8 @@ func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { var userSavedQueries []list.Item for _, filter := range filters { - //var userSavedQuery Item - queryBytes, _ := json.Marshal(filter.Query.FilterQuery) - fmt.Println(string(queryBytes)) - // Extract "from" and "to" from time_filter - // var from, to string - // if fromValue, exists := filter.TimeFilter["from"]; exists { - // from = fmt.Sprintf("%v", fromValue) - // } - // if toValue, exists := filter.TimeFilter["to"]; exists { - // to = fmt.Sprintf("%v", toValue) - // } - // filtering only SQL type filters.. **Filter_name is title and Stream Name is desc - //if string(queryBytes) != "null" { userSavedQuery := Item{ id: filter.FilterID, title: filter.FilterName, @@ -453,7 +351,7 @@ func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { to: filter.TimeFilter.To, } userSavedQueries = append(userSavedQueries, userSavedQuery) - //} + } return userSavedQueries } From a191b064286f9141b15c7cf48f86b306dfbf6f0b Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Mon, 4 Nov 2024 22:53:02 +0530 Subject: [PATCH 4/4] handle null --- pkg/model/savedQueries.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/model/savedQueries.go b/pkg/model/savedQueries.go index 8e26a40..d87cc22 100644 --- a/pkg/model/savedQueries.go +++ b/pkg/model/savedQueries.go @@ -339,7 +339,9 @@ func fetchFilters(client *http.Client, profile *config.Profile) []list.Item { // This returns only the SQL type filters var userSavedQueries []list.Item for _, filter := range filters { - + if filter.Query.FilterQuery == nil { + continue // Skip this filter if FilterQuery is null + } queryBytes, _ := json.Marshal(filter.Query.FilterQuery) userSavedQuery := Item{