working on history queries

This commit is contained in:
sawka
2022-08-29 19:18:02 -07:00
parent 03dd6b1a7e
commit c03bbe8715
6 changed files with 68 additions and 22 deletions
+1 -1
View File
@@ -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
+2 -6
View File
@@ -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,
}
-1
View File
@@ -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
View File
@@ -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
}
+6
View File
@@ -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
+6
View File
@@ -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