feat: updated cache implementation and fixed bugs

This commit is contained in:
David Allen 2025-06-20 14:14:38 -06:00
parent 8b859ff3fb
commit a9d59ee50d
Signed by: towk
GPG key ID: 0430CDBE22619155
7 changed files with 550 additions and 97 deletions

176
internal/cache/edit.go vendored Normal file
View file

@ -0,0 +1,176 @@
package cache
import (
"fmt"
"os"
"slices"
"strconv"
"strings"
"time"
"github.com/araddon/dateparse"
"github.com/charmbracelet/bubbles/table"
tea "github.com/charmbracelet/bubbletea"
"github.com/cznic/mathutil"
"github.com/davidallendj/magellan/internal/cache/sqlite"
magellan "github.com/davidallendj/magellan/pkg"
"github.com/rs/zerolog/log"
)
func (m *Model) editSelectedRow(value bool) tea.Cmd {
if value {
row := m.Table.SelectedRow()
for i := range m.inputs {
m.inputs[i].SetValue(row[i])
}
m.Editor.StartEditting()
} else {
m.Editor.StopEditting()
}
return nil
}
func (m *Model) updateRow() tea.Cmd {
// get updated values from inputs
updated := make(table.Row, len(m.inputs))
for i, input := range m.inputs {
updated[i] = input.Value()
}
// update table for selected row
rows := m.Table.Rows()
rows[m.Table.Cursor()] = updated
m.Table.SetRows(rows)
// go back to selecting view
m.Editor.StopEditting()
m.displayMessage(fmt.Sprintf("updated row at index %d", m.Table.Cursor()), 3)
return nil
}
func (m *Model) addRowAfterCursor() tea.Cmd {
position := mathutil.Clamp(m.Table.Cursor()+1, 0, len(m.Table.Rows())-1)
rows := slices.Insert(m.Table.Rows(), position, table.Row{
"https://127.0.0.1",
"443",
"tcp",
fmt.Sprintf("%d", time.Now().Unix()),
})
m.Table.SetRows(rows)
m.displayMessage(fmt.Sprintf("add new row at index %d", m.Table.Cursor()+1), 3)
return nil
}
func (m *Model) addRowAtEnd() tea.Cmd {
rows := append(m.Table.Rows(), table.Row{
"https://127.0.0.1",
"443",
"tcp",
fmt.Sprintf("%d", time.Now().Unix()),
})
m.Table.SetRows(rows)
m.displayMessage(fmt.Sprintf("add new row at index %d", len(m.Table.Rows())), 3)
return nil
}
func (m *Model) deleteSelectedRow() tea.Cmd {
if len(m.Table.Rows()) == 0 {
m.displayMessage("nothing to delete...", 3)
return nil
}
m.Table.SetRows(slices.Delete(m.Table.Rows(), m.Table.Cursor(), m.Table.Cursor()+1))
m.displayMessage(fmt.Sprintf("deleted row at index %d", m.Table.Cursor()), 3)
return nil
}
func (m *Model) updateInputs(msg tea.Msg) tea.Cmd {
cmds := make([]tea.Cmd, len(m.inputs))
// Only text inputs with Focus() set will respond, so it's safe to simply
// update all of them here without any further logic.
for i := range m.inputs {
m.inputs[i], cmds[i] = m.inputs[i].Update(msg)
}
return tea.Batch(cmds...)
}
func (m *Model) editRowView() string {
display := fmt.Sprintf("Editting row %d...\n\n", m.Table.Cursor())
// update the values of each input
const lc = 9
for i := range m.inputs {
diff := lc - len(m.Table.Columns()[i].Title)
spacing := strings.Repeat(" ", diff)
// m.inputs[i].SetValue(row[i])
display += fmt.Sprintf("%d: ", i)
display += m.Table.Columns()[i].Title + ": "
display += spacing + m.inputs[i].View() + "\n"
}
// submit button
// button := &blurredButton
// if m.focusIndex == len(m.inputs) {
// button = &focusedButton
// }
// display += fmt.Sprintf("\n\n%s\n\n", *button)
// add helper info in footer
display += footerStyle.Render(`
/: move cursor;
w, enter: save edit; esc: cancel; ctrl+c: quit w/o saving;
`)
return display
}
func (m *Model) updateCacheData() tea.Cmd {
// create assets from table data
assets := []magellan.RemoteAsset{}
for _, row := range m.Table.Rows() {
// convert port
port, err := strconv.ParseInt(row[1], 10, 32)
if err != nil {
log.Error().Err(err).Str("host", row[0]).Msg("failed to parse port value")
return nil
}
// parse timestamp
timestamp, err := dateparse.ParseAny(row[3])
if err != nil {
log.Error().Err(err).Str("host", row[0]).Msg("failed to parse date/time")
return nil
}
assets = append(assets, magellan.RemoteAsset{
Host: row[0],
Port: int(port),
Protocol: row[2],
Timestamp: timestamp,
})
}
// remove current database file
err := os.Remove(m.CachePath)
if err != nil {
log.Error().Err(err).Str("path", m.CachePath).Msg("failed to remove old cache")
return nil
}
// create the file again...
_, err = sqlite.CreateRemoteAssetsIfNotExists(m.CachePath)
if err != nil {
log.Error().Err(err).Str("path", m.CachePath).Msg("failed to create new cache")
return nil
}
// write assets to database
err = sqlite.InsertRemoteAssets(m.CachePath, assets...)
if err != nil {
log.Error().Err(err).Str("path", m.CachePath).Msg("failed to insert data into cache")
return nil
}
return nil
}