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) {
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("/run error: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
sstore.MainBus.SendUpdate(ids.SessionId, update)
|
||||||
ctxVal := ctx.Value(historyContextKey)
|
ctxVal := ctx.Value(historyContextKey)
|
||||||
if ctxVal != nil {
|
if ctxVal != nil {
|
||||||
@ -1237,7 +1256,15 @@ func CommentCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
func maybeQuote(s string, quote bool) string {
|
||||||
|
@ -2,7 +2,6 @@ package sstore
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -16,17 +15,13 @@ const HistoryCols = "historyid, ts, userid, sessionid, screenid, windowid, linei
|
|||||||
const DefaultMaxHistoryItems = 1000
|
const DefaultMaxHistoryItems = 1000
|
||||||
|
|
||||||
func NumSessions(ctx context.Context) (int, error) {
|
func NumSessions(ctx context.Context) (int, error) {
|
||||||
db, err := GetDB(ctx)
|
var numSessions int
|
||||||
if err != nil {
|
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||||
return 0, err
|
query := "SELECT count(*) FROM session"
|
||||||
}
|
numSessions = tx.GetInt(query)
|
||||||
query := "SELECT count(*) FROM session"
|
return nil
|
||||||
var count int
|
})
|
||||||
err = db.GetContext(ctx, &count, query)
|
return numSessions, txErr
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return count, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllRemotes(ctx context.Context) ([]*RemoteType, error) {
|
func GetAllRemotes(ctx context.Context) ([]*RemoteType, error) {
|
||||||
@ -157,17 +152,14 @@ func InsertHistoryItem(ctx context.Context, hitem *HistoryItemType) error {
|
|||||||
if hitem == nil {
|
if hitem == nil {
|
||||||
return fmt.Errorf("cannot insert nil history item")
|
return fmt.Errorf("cannot insert nil history item")
|
||||||
}
|
}
|
||||||
db, err := GetDB(ctx)
|
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||||
if err != nil {
|
query := `INSERT INTO history
|
||||||
return err
|
( 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)`
|
||||||
query := `INSERT INTO history ( historyid, ts, userid, sessionid, screenid, windowid, lineid, cmdid, haderror, cmdstr, remoteownerid, remoteid, remotename, ismetacmd) VALUES
|
tx.NamedExecWrap(query, hitem.ToMap())
|
||||||
(:historyid,:ts,:userid,:sessionid,:screenid,:windowid,:lineid,:cmdid,:haderror,:cmdstr,:remoteownerid,:remoteid,:remotename,:ismetacmd)`
|
return nil
|
||||||
_, err = db.NamedExec(query, hitem.ToMap())
|
})
|
||||||
if err != nil {
|
return txErr
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHistoryQuery(tx *TxWrap, sessionId string, windowId string, opts HistoryQueryOpts) ([]*HistoryItemType, error) {
|
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) {
|
func GetSessionByName(ctx context.Context, name string) (*SessionType, error) {
|
||||||
db, err := GetDB(ctx)
|
var session *SessionType
|
||||||
if err != nil {
|
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||||
return nil, err
|
query := `SELECT sessionid FROM session WHERE name = ?`
|
||||||
}
|
sessionId := tx.GetString(query, name)
|
||||||
var sessionId string
|
if sessionId == "" {
|
||||||
query := `SELECT sessionid FROM session WHERE name = ?`
|
return nil
|
||||||
err = db.GetContext(ctx, &sessionId, query, name)
|
|
||||||
if err != nil {
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return nil, 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
|
// also creates default window, returns sessionId
|
||||||
|
@ -3,6 +3,7 @@ package sstore
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
)
|
)
|
||||||
@ -15,6 +16,9 @@ type TxWrap struct {
|
|||||||
|
|
||||||
type txWrapKey struct{}
|
type txWrapKey struct{}
|
||||||
|
|
||||||
|
// single-threaded access to DB
|
||||||
|
var globalNestingLock = &sync.Mutex{}
|
||||||
|
|
||||||
func IsTxWrapContext(ctx context.Context) bool {
|
func IsTxWrapContext(ctx context.Context) bool {
|
||||||
ctxVal := ctx.Value(txWrapKey{})
|
ctxVal := ctx.Value(txWrapKey{})
|
||||||
return ctxVal != nil
|
return ctxVal != nil
|
||||||
@ -30,6 +34,9 @@ func WithTx(ctx context.Context, fn func(tx *TxWrap) error) (rtnErr error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if txWrap == nil {
|
if txWrap == nil {
|
||||||
|
globalNestingLock.Lock()
|
||||||
|
defer globalNestingLock.Unlock()
|
||||||
|
|
||||||
db, err := GetDB(ctx)
|
db, err := GetDB(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user