From e4113b5f51114fae9c1c5dff2834212152465c15 Mon Sep 17 00:00:00 2001 From: sawka Date: Tue, 21 Feb 2023 18:03:13 -0800 Subject: [PATCH] bookmark edit, delete, getbyid --- pkg/cmdrunner/cmdrunner.go | 73 +++++++++++++++++++++++++++++++++++--- pkg/sstore/dbops.go | 68 +++++++++++++++++++++++++++++++++++ pkg/sstore/sstore.go | 1 + pkg/sstore/updatebus.go | 3 +- 4 files changed, 140 insertions(+), 5 deletions(-) diff --git a/pkg/cmdrunner/cmdrunner.go b/pkg/cmdrunner/cmdrunner.go index 1e76825f..ff09bfc9 100644 --- a/pkg/cmdrunner/cmdrunner.go +++ b/pkg/cmdrunner/cmdrunner.go @@ -53,7 +53,7 @@ var RemoteSetArgs = []string{"alias", "connectmode", "key", "password", "autoins var WindowCmds = []string{"run", "comment", "cd", "cr", "clear", "sw", "reset", "signal"} var NoHistCmds = []string{"_compgen", "line", "history", "_killserver"} -var GlobalCmds = []string{"session", "screen", "remote", "set", "client", "telemetry"} +var GlobalCmds = []string{"session", "screen", "remote", "set", "client", "telemetry", "bookmark", "bookmarks"} var SetVarNameMap map[string]string = map[string]string{ "tabcolor": "screen.tabcolor", @@ -176,6 +176,9 @@ func init() { registerCmdFn("bookmarks:show", BookmarksShowCommand) + registerCmdFn("bookmark:edit", BookmarkEditCommand) + registerCmdFn("bookmark:delete", BookmarkDeleteCommand) + registerCmdFn("_killserver", KillServerCommand) registerCmdFn("set", SetCommand) @@ -1915,13 +1918,75 @@ func BookmarksShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) return nil, fmt.Errorf("cannot retrieve bookmarks: %v", err) } update := sstore.ModelUpdate{ - BookmarksView: &sstore.BookmarksViewType{ - Bookmarks: bms, - }, + BookmarksView: true, + Bookmarks: bms, } return update, nil } +func BookmarkEditCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) { + if len(pk.Args) == 0 { + return nil, fmt.Errorf("/bookmark:delete requires one argument (bookmark id)") + } + bookmarkArg := pk.Args[0] + bookmarkId, err := sstore.GetBookmarkIdByArg(ctx, bookmarkArg) + if err != nil { + return nil, fmt.Errorf("error trying to resolve bookmark: %v", err) + } + if bookmarkId == "" { + return nil, fmt.Errorf("bookmark not found") + } + editMap := make(map[string]interface{}) + if descStr, found := pk.Kwargs["desc"]; found { + editMap[sstore.BookmarkField_Desc] = descStr + } + if cmdStr, found := pk.Kwargs["cmdstr"]; found { + editMap[sstore.BookmarkField_CmdStr] = cmdStr + } + if len(editMap) == 0 { + return nil, fmt.Errorf("no fields set, can set %s", formatStrs([]string{"desc", "cmdstr"}, "or", false)) + } + err = sstore.EditBookmark(ctx, bookmarkId, editMap) + if err != nil { + return nil, fmt.Errorf("error trying to edit bookmark: %v", err) + } + bm, err := sstore.GetBookmarkById(ctx, bookmarkId, "") + if err != nil { + return nil, fmt.Errorf("error retrieving edited bookmark: %v", err) + } + return sstore.ModelUpdate{ + Info: &sstore.InfoMsgType{ + InfoMsg: "bookmark edited", + }, + Bookmarks: []*sstore.BookmarkType{bm}, + }, nil +} + +func BookmarkDeleteCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) { + if len(pk.Args) == 0 { + return nil, fmt.Errorf("/bookmark:delete requires one argument (bookmark id)") + } + bookmarkArg := pk.Args[0] + bookmarkId, err := sstore.GetBookmarkIdByArg(ctx, bookmarkArg) + if err != nil { + return nil, fmt.Errorf("error trying to resolve bookmark: %v", err) + } + if bookmarkId == "" { + return nil, fmt.Errorf("bookmark not found") + } + err = sstore.DeleteBookmark(ctx, bookmarkId) + if err != nil { + return nil, fmt.Errorf("error deleting bookmark: %v", err) + } + bm := &sstore.BookmarkType{BookmarkId: bookmarkId, Remove: true} + return sstore.ModelUpdate{ + Info: &sstore.InfoMsgType{ + InfoMsg: "bookmark deleted", + }, + Bookmarks: []*sstore.BookmarkType{bm}, + }, nil +} + func LineBookmarkCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) { ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen|R_Window) if err != nil { diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index 634108f9..06cce739 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -2093,6 +2093,50 @@ func GetBookmarks(ctx context.Context, tag string) ([]*BookmarkType, error) { return bms, nil } +func GetBookmarkById(ctx context.Context, bookmarkId string, tag string) (*BookmarkType, error) { + var rtn *BookmarkType + txErr := WithTx(ctx, func(tx *TxWrap) error { + query := `SELECT * FROM bookmark WHERE bookmarkid = ?` + m := tx.GetMap(query, bookmarkId) + rtn = BookmarkFromMap(m) + if rtn == nil { + return nil + } + query = `SELECT orderidx FROM bookmark_order WHERE bookmarkid = ? AND tag = ?` + orderIdx := tx.GetInt(query, bookmarkId, tag) + rtn.OrderIdx = int64(orderIdx) + query = `SELECT bookmarkid, sessionid, cmdid FROM bookmark_cmd WHERE bookmarkid = ?` + var cmds []bookmarkCmdType + tx.Select(&cmds, query, bookmarkId) + for _, cmd := range cmds { + rtn.Cmds = append(rtn.Cmds, base.MakeCommandKey(cmd.SessionId, cmd.CmdId)) + } + return nil + }) + if txErr != nil { + return nil, txErr + } + return rtn, nil +} + +func GetBookmarkIdByArg(ctx context.Context, bookmarkArg string) (string, error) { + var rtnId string + txErr := WithTx(ctx, func(tx *TxWrap) error { + if len(bookmarkArg) == 8 { + query := `SELECT bookmarkid FROM bookmark WHERE bookmarkid LIKE (? || '%')` + rtnId = tx.GetString(query, bookmarkArg) + return nil + } + query := `SELECT bookmarkid FROM bookmark WHERE bookmarkid = ?` + rtnId = tx.GetString(query, bookmarkArg) + return nil + }) + if txErr != nil { + return "", txErr + } + return rtnId, nil +} + // ignores OrderIdx field func InsertBookmark(ctx context.Context, bm *BookmarkType) error { if bm == nil || bm.BookmarkId == "" { @@ -2125,6 +2169,30 @@ func InsertBookmark(ctx context.Context, bm *BookmarkType) error { return txErr } +const ( + BookmarkField_Desc = "desc" + BookmarkField_CmdStr = "cmdstr" +) + +func EditBookmark(ctx context.Context, bookmarkId string, editMap map[string]interface{}) error { + txErr := WithTx(ctx, func(tx *TxWrap) error { + query := `SELECT bookmarkid FROM bookmark WHERE bookmarkid = ?` + if !tx.Exists(query, bookmarkId) { + return fmt.Errorf("bookmark not found") + } + if desc, found := editMap[BookmarkField_Desc]; found { + query = `UPDATE bookmark SET description = ? WHERE bookmarkid = ?` + tx.Exec(query, desc, bookmarkId) + } + if cmdStr, found := editMap[BookmarkField_CmdStr]; found { + query = `UPDATE bookmark SET cmdstr = ? WHERE bookmarkid = ?` + tx.Exec(query, cmdStr, bookmarkId) + } + return nil + }) + return txErr +} + func fixupBookmarkOrder(tx *TxWrap) { query := ` WITH new_order AS ( diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index 0a07b24e..808f49ea 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -665,6 +665,7 @@ type BookmarkType struct { Description string `json:"description"` Cmds []base.CommandKey `json:"cmds"` OrderIdx int64 `json:"orderidx"` + Remove bool `json:"remove,omitempty"` } func (bm *BookmarkType) ToMap() map[string]interface{} { diff --git a/pkg/sstore/updatebus.go b/pkg/sstore/updatebus.go index 19fd668d..115eb9ee 100644 --- a/pkg/sstore/updatebus.go +++ b/pkg/sstore/updatebus.go @@ -43,7 +43,8 @@ type ModelUpdate struct { History *HistoryInfoType `json:"history,omitempty"` Interactive bool `json:"interactive"` Connect bool `json:"connect,omitempty"` - BookmarksView *BookmarksViewType `json:"bookmarksview,omitempty"` + BookmarksView bool `json:"bookmarksview,omitempty"` + Bookmarks []*BookmarkType `json:"bookmarks,omitempty"` } func (ModelUpdate) UpdateType() string {