mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-22 21:42:49 +01:00
single-thread DB access. send selectedline updates for run/comment commands
This commit is contained in:
parent
43cf55b25e
commit
d19f29c467
@ -217,7 +217,7 @@ func resolveNonNegInt(arg string, def int) (int, error) {
|
||||
}
|
||||
|
||||
func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Window|R_RemoteConnected)
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen|R_Window|R_RemoteConnected)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/run error: %w", err)
|
||||
}
|
||||
@ -252,7 +252,26 @@ func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.U
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
update := sstore.ModelUpdate{Line: rtnLine, Cmd: cmd, Interactive: pk.Interactive}
|
||||
sw, err := sstore.GetScreenWindowByIds(ctx, ids.SessionId, ids.ScreenId, ids.WindowId)
|
||||
if err != nil {
|
||||
// ignore error here, because the command has already run (nothing to do)
|
||||
fmt.Printf("/run error getting screen-window: %v\n", err)
|
||||
}
|
||||
if sw != nil {
|
||||
updateMap := make(map[string]interface{})
|
||||
updateMap[sstore.SWField_SelectedLine] = rtnLine.LineNum
|
||||
sw, err = sstore.UpdateScreenWindow(ctx, ids.SessionId, ids.ScreenId, ids.WindowId, updateMap)
|
||||
if err != nil {
|
||||
// ignore error again (nothing to do)
|
||||
fmt.Printf("/run error updating screen-window selected line: %v\n", err)
|
||||
}
|
||||
}
|
||||
update := sstore.ModelUpdate{
|
||||
Line: rtnLine,
|
||||
Cmd: cmd,
|
||||
ScreenWindow: sw,
|
||||
Interactive: pk.Interactive,
|
||||
}
|
||||
sstore.MainBus.SendUpdate(ids.SessionId, update)
|
||||
ctxVal := ctx.Value(historyContextKey)
|
||||
if ctxVal != nil {
|
||||
@ -1237,7 +1256,15 @@ func CommentCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sstore.ModelUpdate{Line: rtnLine}, nil
|
||||
updateMap := make(map[string]interface{})
|
||||
updateMap[sstore.SWField_SelectedLine] = rtnLine.LineNum
|
||||
sw, err := sstore.UpdateScreenWindow(ctx, ids.SessionId, ids.ScreenId, ids.WindowId, updateMap)
|
||||
if err != nil {
|
||||
// ignore error again (nothing to do)
|
||||
fmt.Printf("/comment error updating screen-window selected line: %v\n", err)
|
||||
}
|
||||
update := sstore.ModelUpdate{Line: rtnLine, ScreenWindow: sw}
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func maybeQuote(s string, quote bool) string {
|
||||
|
@ -2,7 +2,6 @@ package sstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -16,17 +15,13 @@ const HistoryCols = "historyid, ts, userid, sessionid, screenid, windowid, linei
|
||||
const DefaultMaxHistoryItems = 1000
|
||||
|
||||
func NumSessions(ctx context.Context) (int, error) {
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
query := "SELECT count(*) FROM session"
|
||||
var count int
|
||||
err = db.GetContext(ctx, &count, query)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
var numSessions int
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := "SELECT count(*) FROM session"
|
||||
numSessions = tx.GetInt(query)
|
||||
return nil
|
||||
})
|
||||
return numSessions, txErr
|
||||
}
|
||||
|
||||
func GetAllRemotes(ctx context.Context) ([]*RemoteType, error) {
|
||||
@ -157,17 +152,14 @@ func InsertHistoryItem(ctx context.Context, hitem *HistoryItemType) error {
|
||||
if hitem == nil {
|
||||
return fmt.Errorf("cannot insert nil history item")
|
||||
}
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
query := `INSERT INTO history ( historyid, ts, userid, sessionid, screenid, windowid, lineid, cmdid, haderror, cmdstr, remoteownerid, remoteid, remotename, ismetacmd) VALUES
|
||||
(:historyid,:ts,:userid,:sessionid,:screenid,:windowid,:lineid,:cmdid,:haderror,:cmdstr,:remoteownerid,:remoteid,:remotename,:ismetacmd)`
|
||||
_, err = db.NamedExec(query, hitem.ToMap())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `INSERT INTO history
|
||||
( historyid, ts, userid, sessionid, screenid, windowid, lineid, cmdid, haderror, cmdstr, remoteownerid, remoteid, remotename, ismetacmd) VALUES
|
||||
(:historyid,:ts,:userid,:sessionid,:screenid,:windowid,:lineid,:cmdid,:haderror,:cmdstr,:remoteownerid,:remoteid,:remotename,:ismetacmd)`
|
||||
tx.NamedExecWrap(query, hitem.ToMap())
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
||||
func runHistoryQuery(tx *TxWrap, sessionId string, windowId string, opts HistoryQueryOpts) ([]*HistoryItemType, error) {
|
||||
@ -372,20 +364,24 @@ func GetSessionById(ctx context.Context, id string) (*SessionType, error) {
|
||||
}
|
||||
|
||||
func GetSessionByName(ctx context.Context, name string) (*SessionType, error) {
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var sessionId string
|
||||
query := `SELECT sessionid FROM session WHERE name = ?`
|
||||
err = db.GetContext(ctx, &sessionId, query, name)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
var session *SessionType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT sessionid FROM session WHERE name = ?`
|
||||
sessionId := tx.GetString(query, name)
|
||||
if sessionId == "" {
|
||||
return nil
|
||||
}
|
||||
return nil, err
|
||||
var err error
|
||||
session, err = GetSessionById(tx.Context(), sessionId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
return nil, txErr
|
||||
}
|
||||
return GetSessionById(ctx, sessionId)
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// also creates default window, returns sessionId
|
||||
|
@ -3,6 +3,7 @@ package sstore
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"sync"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
@ -15,6 +16,9 @@ type TxWrap struct {
|
||||
|
||||
type txWrapKey struct{}
|
||||
|
||||
// single-threaded access to DB
|
||||
var globalNestingLock = &sync.Mutex{}
|
||||
|
||||
func IsTxWrapContext(ctx context.Context) bool {
|
||||
ctxVal := ctx.Value(txWrapKey{})
|
||||
return ctxVal != nil
|
||||
@ -30,6 +34,9 @@ func WithTx(ctx context.Context, fn func(tx *TxWrap) error) (rtnErr error) {
|
||||
}
|
||||
}
|
||||
if txWrap == nil {
|
||||
globalNestingLock.Lock()
|
||||
defer globalNestingLock.Unlock()
|
||||
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user