mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
working on history queries
This commit is contained in:
+1
-1
@@ -183,7 +183,7 @@ func HandleGetHistory(w http.ResponseWriter, r *http.Request) {
|
||||
numItems = parsedNum
|
||||
}
|
||||
}
|
||||
hitems, err := sstore.GetSessionHistoryItems(r.Context(), sessionId, numItems)
|
||||
hitems, err := sstore.GetHistoryItems(r.Context(), sessionId, "", sstore.HistoryQueryOpts{MaxItems: numItems})
|
||||
if err != nil {
|
||||
WriteJsonError(w, err)
|
||||
return
|
||||
|
||||
@@ -927,13 +927,13 @@ func HistoryCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto
|
||||
if maxItems == 0 {
|
||||
maxItems = DefaultMaxHistoryItems
|
||||
}
|
||||
hitems, err := sstore.GetSessionHistoryItems(ctx, ids.SessionId, maxItems)
|
||||
hitems, err := sstore.GetHistoryItems(ctx, ids.SessionId, ids.WindowId, sstore.HistoryQueryOpts{MaxItems: maxItems})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var filteredItems []*sstore.HistoryItemType
|
||||
for _, hitem := range hitems {
|
||||
if hitem.ScreenId == ids.ScreenId && hitem.WindowId == ids.WindowId && (hitem.Remote == ids.Remote.RemotePtr || hitem.IsMetaCmd) {
|
||||
if hitem.Remote == ids.Remote.RemotePtr || hitem.IsMetaCmd {
|
||||
filteredItems = append(filteredItems, hitem)
|
||||
}
|
||||
}
|
||||
@@ -952,10 +952,6 @@ func HistoryCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto
|
||||
}
|
||||
}
|
||||
update := &sstore.ModelUpdate{}
|
||||
update.Info = &sstore.InfoMsgType{
|
||||
InfoMsg: fmt.Sprintf("history, limited to current session, screen, window, and remote (maxitems=%d)", maxItems),
|
||||
InfoLines: splitLinesForInfo(buf.String()),
|
||||
}
|
||||
update.History = &sstore.HistoryInfoType{
|
||||
Items: filteredItems,
|
||||
}
|
||||
|
||||
@@ -119,7 +119,6 @@ func resolveByPosition(items []ResolveItem, curId string, posStr string) *Resolv
|
||||
}
|
||||
|
||||
func resolveUiIds(ctx context.Context, pk *scpacket.FeCommandPacketType, rtype int) (resolvedIds, error) {
|
||||
fmt.Printf("resolve-ui-ids: %#v\n", pk)
|
||||
rtn := resolvedIds{}
|
||||
uictx := pk.UIContext
|
||||
if uictx != nil {
|
||||
|
||||
+53
-14
@@ -4,13 +4,15 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/scripthaus-dev/mshell/pkg/packet"
|
||||
)
|
||||
|
||||
const HistoryCols = "historyid, ts, userid, sessionid, screenid, windowid, lineid, cmdid, haderror, cmdstr, remoteownerid, remoteid, remotename, ismetacmd"
|
||||
const DefaultMaxHistoryItems = 1000
|
||||
|
||||
func NumSessions(ctx context.Context) (int, error) {
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
@@ -117,23 +119,60 @@ func InsertHistoryItem(ctx context.Context, hitem *HistoryItemType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetSessionHistoryItems(ctx context.Context, sessionId string, maxItems int) ([]*HistoryItemType, error) {
|
||||
func runHistoryQuery(tx *TxWrap, sessionId string, windowId string, opts HistoryQueryOpts) ([]*HistoryItemType, error) {
|
||||
// check sessionid/windowid format because we are directly inserting them into the SQL
|
||||
if sessionId != "" {
|
||||
_, err := uuid.Parse(sessionId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("malformed sessionid")
|
||||
}
|
||||
}
|
||||
if windowId != "" {
|
||||
_, err := uuid.Parse(windowId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("malformed windowid")
|
||||
}
|
||||
}
|
||||
hnumStr := ""
|
||||
whereClause := ""
|
||||
if sessionId != "" && windowId != "" {
|
||||
whereClause = fmt.Sprintf("WHERE sessionid = '%s' AND windowid = '%s'", sessionId, windowId)
|
||||
hnumStr = "w"
|
||||
} else if sessionId != "" {
|
||||
whereClause = fmt.Sprintf("WHERE sessionid = '%s'", sessionId)
|
||||
hnumStr = "s"
|
||||
} else {
|
||||
hnumStr = "g"
|
||||
}
|
||||
maxItems := opts.MaxItems
|
||||
if maxItems == 0 {
|
||||
maxItems = DefaultMaxHistoryItems
|
||||
}
|
||||
query := fmt.Sprintf("SELECT %s, '%s' || row_number() OVER win AS historynum FROM history %s WINDOW win AS (ORDER BY ts, historyid) ORDER BY ts DESC, historyid DESC LIMIT %d", HistoryCols, hnumStr, whereClause, maxItems)
|
||||
if opts.FromTs > 0 {
|
||||
query = fmt.Sprintf("SELECT * FROM (%s) WHERE ts >= %d", query, opts.FromTs)
|
||||
}
|
||||
marr := tx.SelectMaps(query)
|
||||
rtn := make([]*HistoryItemType, len(marr))
|
||||
for idx, m := range marr {
|
||||
hitem := HistoryItemFromMap(m)
|
||||
rtn[idx] = hitem
|
||||
}
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
func GetHistoryItems(ctx context.Context, sessionId string, windowId string, opts HistoryQueryOpts) ([]*HistoryItemType, error) {
|
||||
var rtn []*HistoryItemType
|
||||
err := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT count(*) FROM history WHERE sessionid = ?`
|
||||
totalNum := tx.GetInt(query, sessionId)
|
||||
query = `SELECT * FROM history WHERE sessionid = ? ORDER BY ts DESC, historyid LIMIT ?`
|
||||
marr := tx.SelectMaps(query, sessionId, maxItems)
|
||||
for idx, m := range marr {
|
||||
hnum := totalNum - idx
|
||||
hitem := HistoryItemFromMap(m)
|
||||
hitem.HistoryNum = strconv.Itoa(hnum)
|
||||
rtn = append(rtn, hitem)
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
var err error
|
||||
rtn, err = runHistoryQuery(tx, sessionId, windowId, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if txErr != nil {
|
||||
return nil, txErr
|
||||
}
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func quickSetStr(strVal *string, m map[string]interface{}, name string) {
|
||||
@@ -11,6 +12,11 @@ func quickSetStr(strVal *string, m map[string]interface{}, name string) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
ival, ok := v.(int64)
|
||||
if ok {
|
||||
*strVal = strconv.FormatInt(ival, 10)
|
||||
return
|
||||
}
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return
|
||||
|
||||
@@ -244,6 +244,7 @@ func HistoryItemFromMap(m map[string]interface{}) *HistoryItemType {
|
||||
quickSetStr(&h.Remote.RemoteId, m, "remoteid")
|
||||
quickSetStr(&h.Remote.Name, m, "remotename")
|
||||
quickSetBool(&h.IsMetaCmd, m, "ismetacmd")
|
||||
quickSetStr(&h.HistoryNum, m, "historynum")
|
||||
return &h
|
||||
}
|
||||
|
||||
@@ -332,6 +333,11 @@ type HistoryItemType struct {
|
||||
HistoryNum string `json:"historynum"`
|
||||
}
|
||||
|
||||
type HistoryQueryOpts struct {
|
||||
MaxItems int
|
||||
FromTs int64
|
||||
}
|
||||
|
||||
type RemoteState struct {
|
||||
Cwd string `json:"cwd"`
|
||||
Env0 []byte `json:"env0"` // "env -0" format
|
||||
|
||||
Reference in New Issue
Block a user