mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
insert bookmark
This commit is contained in:
parent
37ffcd03c8
commit
3845429fd2
@ -1,3 +1,6 @@
|
||||
DROP TABLE bookmark;
|
||||
DROP TABLE bookmark_order;
|
||||
DROP TABLE bookmark_cmd;
|
||||
|
||||
ALTER TABLE line DROP COLUMN bookmarked;
|
||||
ALTER TABLE line DROP COLUMN pinned;
|
||||
|
@ -16,6 +16,11 @@ CREATE TABLE bookmark_order (
|
||||
|
||||
CREATE TABLE bookmark_cmd (
|
||||
bookmarkid varchar(36) NOT NULL,
|
||||
sessionid varchar(36) NOT NULL,
|
||||
cmdid varchar(36) NOT NULL,
|
||||
PRIMARY KEY (bookmarkid, cmdid)
|
||||
PRIMARY KEY (bookmarkid, sessionid, cmdid)
|
||||
);
|
||||
|
||||
ALTER TABLE line ADD COLUMN bookmarked boolean NOT NULL DEFAULT 0;
|
||||
ALTER TABLE line ADD COLUMN pinned boolean NOT NULL DEFAULT 0;
|
||||
|
||||
|
@ -97,7 +97,7 @@ CREATE TABLE line (
|
||||
ephemeral boolean NOT NULL,
|
||||
contentheight int NOT NULL,
|
||||
star int NOT NULL,
|
||||
archived boolean NOT NULL, renderer varchar(50) NOT NULL DEFAULT '',
|
||||
archived boolean NOT NULL, renderer varchar(50) NOT NULL DEFAULT '', bookmarked boolean NOT NULL DEFAULT 0, pinned boolean NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (sessionid, windowid, lineid)
|
||||
);
|
||||
CREATE TABLE remote (
|
||||
@ -181,6 +181,7 @@ CREATE TABLE bookmark_order (
|
||||
);
|
||||
CREATE TABLE bookmark_cmd (
|
||||
bookmarkid varchar(36) NOT NULL,
|
||||
sessionid varchar(36) NOT NULL,
|
||||
cmdid varchar(36) NOT NULL,
|
||||
PRIMARY KEY (bookmarkid, cmdid)
|
||||
PRIMARY KEY (bookmarkid, sessionid, cmdid)
|
||||
);
|
||||
|
@ -157,6 +157,8 @@ func init() {
|
||||
registerCmdFn("line", LineCommand)
|
||||
registerCmdFn("line:show", LineShowCommand)
|
||||
registerCmdFn("line:star", LineStarCommand)
|
||||
registerCmdFn("line:bookmark", LineBookmarkCommand)
|
||||
registerCmdFn("line:pin", LinePinCommand)
|
||||
registerCmdFn("line:archive", LineArchiveCommand)
|
||||
registerCmdFn("line:purge", LinePurgeCommand)
|
||||
registerCmdFn("line:setheight", LineSetHeightCommand)
|
||||
@ -1900,6 +1902,58 @@ func LineSetHeightCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
return nil, 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 {
|
||||
return nil, err
|
||||
}
|
||||
if len(pk.Args) == 0 {
|
||||
return nil, fmt.Errorf("/line:bookmark requires an argument (line number or id)")
|
||||
}
|
||||
lineArg := pk.Args[0]
|
||||
lineId, err := sstore.FindLineIdByArg(ctx, ids.SessionId, ids.WindowId, lineArg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error looking up lineid: %v", err)
|
||||
}
|
||||
if lineId == "" {
|
||||
return nil, fmt.Errorf("line %q not found", lineArg)
|
||||
}
|
||||
lineObj, cmdObj, err := sstore.GetLineCmdByLineId(ctx, ids.SessionId, ids.WindowId, lineId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:bookmark error getting line: %v", err)
|
||||
}
|
||||
if cmdObj == nil {
|
||||
return nil, fmt.Errorf("cannot bookmark non-cmd line")
|
||||
}
|
||||
ck := base.MakeCommandKey(lineObj.SessionId, cmdObj.CmdId)
|
||||
bm := &sstore.BookmarkType{
|
||||
BookmarkId: uuid.New().String(),
|
||||
CreatedTs: time.Now().UnixMilli(),
|
||||
CmdStr: cmdObj.CmdStr,
|
||||
Alias: "",
|
||||
Tags: nil,
|
||||
Description: "",
|
||||
CmdIds: []base.CommandKey{ck},
|
||||
}
|
||||
err = sstore.InsertBookmark(ctx, bm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot insert bookmark: %v", err)
|
||||
}
|
||||
newLineObj, err := sstore.GetLineById(ctx, ids.SessionId, ids.WindowId, lineId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:bookmark error getting line: %v", err)
|
||||
}
|
||||
if newLineObj == nil {
|
||||
// no line (which is strange given we checked for it above). just return a nop.
|
||||
return nil, nil
|
||||
}
|
||||
return sstore.ModelUpdate{Line: newLineObj}, nil
|
||||
}
|
||||
|
||||
func LinePinCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func LineStarCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen|R_Window)
|
||||
if err != nil {
|
||||
@ -1930,7 +1984,7 @@ func LineStarCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sst
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:star error updating star value: %v", err)
|
||||
}
|
||||
lineObj, err := sstore.GetLineById(ctx, lineId)
|
||||
lineObj, err := sstore.GetLineById(ctx, ids.SessionId, ids.WindowId, lineId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:star error getting line: %v", err)
|
||||
}
|
||||
@ -1965,7 +2019,7 @@ func LineArchiveCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:archive error updating hidden status: %v", err)
|
||||
}
|
||||
lineObj, err := sstore.GetLineById(ctx, lineId)
|
||||
lineObj, err := sstore.GetLineById(ctx, ids.SessionId, ids.WindowId, lineId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/line:archive error getting line: %v", err)
|
||||
}
|
||||
|
@ -719,8 +719,8 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error {
|
||||
query = `SELECT nextlinenum FROM window WHERE sessionid = ? AND windowid = ?`
|
||||
nextLineNum := tx.GetInt(query, line.SessionId, line.WindowId)
|
||||
line.LineNum = int64(nextLineNum)
|
||||
query = `INSERT INTO line ( sessionid, windowid, userid, lineid, ts, linenum, linenumtemp, linelocal, linetype, text, cmdid, renderer, ephemeral, contentheight, star, archived)
|
||||
VALUES (:sessionid,:windowid,:userid,:lineid,:ts,:linenum,:linenumtemp,:linelocal,:linetype,:text,:cmdid,:renderer,:ephemeral,:contentheight,:star,:archived)`
|
||||
query = `INSERT INTO line ( sessionid, windowid, userid, lineid, ts, linenum, linenumtemp, linelocal, linetype, text, cmdid, renderer, ephemeral, contentheight, star, archived, bookmarked, pinned)
|
||||
VALUES (:sessionid,:windowid,:userid,:lineid,:ts,:linenum,:linenumtemp,:linelocal,:linetype,:text,:cmdid,:renderer,:ephemeral,:contentheight,:star,:archived,:bookmarked,:pinned)`
|
||||
tx.NamedExec(query, line)
|
||||
query = `UPDATE window SET nextlinenum = ? WHERE sessionid = ? AND windowid = ?`
|
||||
tx.Exec(query, nextLineNum+1, line.SessionId, line.WindowId)
|
||||
@ -899,6 +899,8 @@ func cleanSessionCmds(ctx context.Context, sessionId string) error {
|
||||
removedCmds = tx.SelectStrings(query, sessionId, sessionId)
|
||||
query = `DELETE FROM cmd WHERE sessionid = ? AND cmdid NOT IN (SELECT cmdid FROM line WHERE sessionid = ?)`
|
||||
tx.Exec(query, sessionId, sessionId)
|
||||
query = `DELETE FROM bookmark_cmd WHERE sessionid = ? AND cmdid NOT IN (SELECT cmdid FROM cmd WHERE sessionid = ?)`
|
||||
tx.Exec(query, sessionId, sessionId)
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
@ -1391,6 +1393,8 @@ func DeleteSession(ctx context.Context, sessionId string) (UpdatePacket, error)
|
||||
tx.Exec(query, sessionId)
|
||||
query = `DELETE FROM cmd WHERE sessionid = ?`
|
||||
tx.Exec(query, sessionId)
|
||||
query = `DELETE FROM bookmark_cmd WHERE sessionid = ?`
|
||||
tx.Exec(query, sessionId)
|
||||
newActiveSessionId, _ = fixActiveSessionId(tx.Context())
|
||||
return nil
|
||||
})
|
||||
@ -1825,12 +1829,12 @@ func UpdateLineHeight(ctx context.Context, lineId string, heightVal int) error {
|
||||
}
|
||||
|
||||
// can return nil, nil if line is not found
|
||||
func GetLineById(ctx context.Context, lineId string) (*LineType, error) {
|
||||
func GetLineById(ctx context.Context, sessionId string, windowId string, lineId string) (*LineType, error) {
|
||||
var rtn *LineType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
var line LineType
|
||||
query := `SELECT * FROM line WHERE lineid = ?`
|
||||
found := tx.Get(&line, query, lineId)
|
||||
query := `SELECT * FROM line WHERE sessionid = ? AND windowid = ? AND lineid = ?`
|
||||
found := tx.Get(&line, query, sessionId, windowId, lineId)
|
||||
if found {
|
||||
rtn = &line
|
||||
}
|
||||
@ -2033,3 +2037,67 @@ func GetDBVersion(ctx context.Context) (int, error) {
|
||||
})
|
||||
return version, txErr
|
||||
}
|
||||
|
||||
func InsertBookmark(ctx context.Context, bm *BookmarkType) error {
|
||||
if bm == nil || bm.BookmarkId == "" {
|
||||
return fmt.Errorf("invalid empty bookmark id")
|
||||
}
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT bookmarkid FROM bookmark WHERE bookmarkid = ?`
|
||||
if tx.Exists(query, bm.BookmarkId) {
|
||||
return fmt.Errorf("bookmarkid already exists")
|
||||
}
|
||||
query = `INSERT INTO bookmark ( bookmarkid, createdts, cmdstr, alias, tags, description)
|
||||
VALUES (:bookmarkid,:createdts,:cmdstr,:alias,:tags,:description)`
|
||||
tx.NamedExec(query, bm.ToMap())
|
||||
for _, tag := range append(bm.Tags, "") {
|
||||
query = `SELECT COALESCE(max(orderidx), 0) FROM bookmark_order WHERE tag = ?`
|
||||
maxOrder := tx.GetInt(query, tag)
|
||||
query = `INSERT INTO bookmark_order (tag, bookmarkid, orderidx) VALUES (?, ?, ?)`
|
||||
tx.Exec(query, tag, bm.BookmarkId, maxOrder+1)
|
||||
}
|
||||
query = `INSERT INTO bookmark_cmd (bookmarkid, sessionid, cmdid) VALUES (?, ?, ?)`
|
||||
for _, ck := range bm.CmdIds {
|
||||
tx.Exec(query, bm.BookmarkId, ck.GetSessionId(), ck.GetCmdId())
|
||||
}
|
||||
query = `UPDATE line SET bookmarked = 1 WHERE sessionid = ? AND cmdid = ?`
|
||||
for _, ck := range bm.CmdIds {
|
||||
tx.Exec(query, ck.GetSessionId(), ck.GetCmdId())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
||||
func fixupBookmarkOrder(tx *TxWrap) {
|
||||
query := `
|
||||
WITH new_order AS (
|
||||
SELECT tag, bookmarkid, row_number() OVER (PARTITION BY tag ORDER BY orderidx) AS newidx FROM bookmark_order
|
||||
)
|
||||
UPDATE bookmark_order
|
||||
SET orderidx = new_order.newidx
|
||||
FROM new_order
|
||||
WHERE bookmark_order.tag = new_order.tag AND bookmark_order.bookmarkid = new_order.bookmarkid
|
||||
`
|
||||
tx.Exec(query)
|
||||
}
|
||||
|
||||
func DeleteBookmark(ctx context.Context, bookmarkId string) 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")
|
||||
}
|
||||
query = `DELETE FROM bookmark WHERE bookmarkid = ?`
|
||||
tx.Exec(query, bookmarkId)
|
||||
query = `DELETE FROM bookmark_order WHERE bookmarkid = ?`
|
||||
tx.Exec(query, bookmarkId)
|
||||
query = `UPDATE line SET bookmarked = 0 WHERE bookmarked AND cmdid <> '' AND (sessionid||cmdid) IN (SELECT sessionid||cmdid FROM bookmark_cmd WHERE bookmarkid = ?) `
|
||||
tx.Exec(query, bookmarkId)
|
||||
query = `DELETE FROM bookmark_cmd WHERE bookmarkid = ?`
|
||||
tx.Exec(query, bookmarkId)
|
||||
fixupBookmarkOrder(tx)
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
@ -650,10 +650,47 @@ type LineType struct {
|
||||
Ephemeral bool `json:"ephemeral,omitempty"`
|
||||
ContentHeight int64 `json:"contentheight,omitempty"`
|
||||
Star bool `json:"star,omitempty"`
|
||||
Bookmarked bool `json:"bookmarked,omitempty"`
|
||||
Pinned bool `json:"pinned,omitempty"`
|
||||
Archived bool `json:"archived,omitempty"`
|
||||
Remove bool `json:"remove,omitempty"`
|
||||
}
|
||||
|
||||
type BookmarkType struct {
|
||||
BookmarkId string `json:"bookmarkid"`
|
||||
CreatedTs int64 `json:"createdts"`
|
||||
CmdStr string `json:"cmdstr"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
Description string `json:"description"`
|
||||
CmdIds []base.CommandKey `json:"cmdids"`
|
||||
}
|
||||
|
||||
func (bm *BookmarkType) ToMap() map[string]interface{} {
|
||||
rtn := make(map[string]interface{})
|
||||
rtn["bookmarkid"] = bm.BookmarkId
|
||||
rtn["createdts"] = bm.CreatedTs
|
||||
rtn["cmdstr"] = bm.CmdStr
|
||||
rtn["alias"] = bm.Alias
|
||||
rtn["description"] = bm.Description
|
||||
rtn["tags"] = quickJsonArr(bm.Tags)
|
||||
return rtn
|
||||
}
|
||||
|
||||
func BookmarkFromMap(m map[string]interface{}) *BookmarkType {
|
||||
if len(m) == 0 {
|
||||
return nil
|
||||
}
|
||||
var bm BookmarkType
|
||||
quickSetStr(&bm.BookmarkId, m, "bookmarkid")
|
||||
quickSetInt64(&bm.CreatedTs, m, "createdts")
|
||||
quickSetStr(&bm.Alias, m, "alias")
|
||||
quickSetStr(&bm.CmdStr, m, "cmdstr")
|
||||
quickSetStr(&bm.Description, m, "description")
|
||||
quickSetJsonArr(&bm.Tags, m, "tags")
|
||||
return &bm
|
||||
}
|
||||
|
||||
type ResolveItem struct {
|
||||
Name string
|
||||
Num int
|
||||
|
Loading…
Reference in New Issue
Block a user