From 2957a03864a112126c4d7774380742aaf7d1bce4 Mon Sep 17 00:00:00 2001 From: sawka Date: Tue, 12 Jul 2022 13:50:44 -0700 Subject: [PATCH] checkpoint --- pkg/sstore/dbops.go | 88 ++++++++++++++++++++++++++------------------ pkg/sstore/sstore.go | 43 +++++++++++----------- 2 files changed, 73 insertions(+), 58 deletions(-) diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index 17af26f5..fc22df08 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -85,17 +85,47 @@ func InsertRemote(ctx context.Context, remote *RemoteType) error { } func GetAllSessions(ctx context.Context) ([]*SessionType, error) { - db, err := GetDB() - if err != nil { - return nil, err - } var rtn []*SessionType - query := `SELECT * FROM session` - err = db.SelectContext(ctx, &rtn, query) - if err != nil { - return nil, err - } - return rtn, nil + err := WithTx(ctx, func(tx *TxWrap) error { + query := `SELECT * FROM session` + tx.SelectWrap(&rtn, query) + var windows []*WindowType + query = `SELECT * FROM window` + tx.SelectWrap(&windows, query) + winMap := make(map[string][]*WindowType) + for _, win := range windows { + winArr := winMap[win.SessionId] + winArr = append(winArr, win) + winMap[win.SessionId] = winArr + } + for _, session := range rtn { + session.Windows = winMap[session.SessionId] + } + return nil + }) + return rtn, err +} + +func GetWindowById(ctx context.Context, sessionId string, windowId string) (*WindowType, error) { + var rtnWindow *WindowType + err := WithTx(ctx, func(tx *TxWrap) error { + var window WindowType + query := `SELECT * FROM window WHERE sessionid = ? AND windowid = ?` + found := tx.GetWrap(&window, query, sessionId, windowId) + if !found { + return nil + } + rtnWindow = &window + query = `SELECT * FROM line WHERE sessionid = ? AND windowid = ?` + tx.SelectWrap(&window.Lines, query, sessionId, windowId) + query = `SELECT * FROM cmd WHERE cmdid IN (SELECT cmdid FROM line WHERE sessionid = ? AND windowid = ?)` + cmdMaps := tx.SelectMaps(query, sessionId, windowId) + for _, m := range cmdMaps { + window.Cmds = append(window.Cmds, CmdFromMap(m)) + } + return nil + }) + return rtnWindow, err } func GetSessionById(ctx context.Context, id string) (*SessionType, error) { @@ -108,7 +138,7 @@ func GetSessionById(ctx context.Context, id string) (*SessionType, error) { return nil } rtnSession = &session - query = `SELECT sessionid, windowid, name, curremote, version FROM window WHERE sessionid = ?` + query = `SELECT sessionid, windowid, name, curremote FROM window WHERE sessionid = ?` tx.SelectWrap(&session.Windows, query, session.SessionId) query = `SELECT * FROM remote_instance WHERE sessionid = ?` tx.SelectWrap(&session.Remotes, query, session.SessionId) @@ -142,23 +172,6 @@ func GetSessionByName(ctx context.Context, name string) (*SessionType, error) { return GetSessionById(ctx, sessionId) } -func GetWindowById(ctx context.Context, sessionId string, windowId string) (*WindowType, error) { - var rtnWindow *WindowType - txErr := WithTx(ctx, func(tx *TxWrap) error { - var window WindowType - query := `SELECT * FROM window WHERE sessionid = ? AND windowid = ?` - found := tx.GetWrap(&window, query, sessionId, windowId) - if !found { - return nil - } - rtnWindow = &window - query = `SELECT * FROM line WHERE sessionid = ? AND windowid = ?` - tx.SelectWrap(&window.Lines, query, sessionId, windowId) - return nil - }) - return rtnWindow, txErr -} - // also creates default window, returns sessionId // if sessionName == "", it will be generated func InsertSessionWithName(ctx context.Context, sessionName string) (string, error) { @@ -188,7 +201,7 @@ func InsertSessionWithName(ctx context.Context, sessionName string) (string, err SessionId: newSessionId, Name: sessionName, } - query := `INSERT INTO session (sessionid, name) VALUES (:sessionid, :name)` + query := `INSERT INTO session (sessionid, name, notifynum) VALUES (:sessionid, :name, :notifynum)` tx.NamedExecWrap(query, newSession) window := &WindowType{ SessionId: newSessionId, @@ -196,8 +209,7 @@ func InsertSessionWithName(ctx context.Context, sessionName string) (string, err Name: DefaultWindowName, CurRemote: LocalRemoteName, } - query = `INSERT INTO window (sessionid, windowid, name, curremote, version) VALUES (:sessionid, :windowid, :name, :curremote, :version)` - tx.NamedExecWrap(query, window) + txInsertWindow(tx, window) return nil }) return newSessionId, txErr @@ -250,13 +262,17 @@ func InsertWindow(ctx context.Context, sessionId string, windowName string) (str Name: windowName, CurRemote: LocalRemoteName, } - query = `INSERT INTO window (sessionid, windowid, name, curremote, version) VALUES (:sessionid, :windowid, :name, :curremote, :version)` - tx.NamedExecWrap(query, window) + txInsertWindow(tx, window) return nil }) return newWindowId, txErr } +func txInsertWindow(tx *TxWrap, window *WindowType) { + query := `INSERT INTO window (sessionid, windowid, name, curremote) VALUES (:sessionid, :windowid, :name, :curremote)` + tx.NamedExecWrap(query, window) +} + func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { if line == nil { return fmt.Errorf("line cannot be nil") @@ -271,7 +287,7 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { if !hasWindow { return fmt.Errorf("window not found, cannot insert line[%s/%s]", line.SessionId, line.WindowId) } - var maxLineId int + var maxLineId int64 query = `SELECT COALESCE(max(lineid), 0) FROM line WHERE sessionid = ? AND windowid = ?` tx.GetWrap(&maxLineId, query, line.SessionId, line.WindowId) line.LineId = maxLineId + 1 @@ -281,8 +297,8 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { if cmd != nil { cmdMap := cmd.ToMap() query = ` -INSERT INTO cmd ( sessionid, cmdid, remoteid, cmdstr, remotestate, termopts, status, startpk, donepk, runout) - VALUES (:sessionid,:cmdid,:remoteid,:cmdstr,:remotestate,:termopts,:status,:startpk,:donepk,:runout) +INSERT INTO cmd ( sessionid, cmdid, remoteid, cmdstr, remotestate, termopts, status, startpk, donepk, runout, usedrows) + VALUES (:sessionid,:cmdid,:remoteid,:cmdstr,:remotestate,:termopts,:status,:startpk,:donepk,:runout,:usedrows) ` tx.NamedExecWrap(query, cmdMap) } diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index 9e665f5b..b4009e20 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -19,9 +19,6 @@ import ( _ "github.com/mattn/go-sqlite3" ) -var NextLineId = 10 -var NextLineLock = &sync.Mutex{} - const LineTypeCmd = "cmd" const LineTypeText = "text" const DBFileName = "sh2.db" @@ -51,7 +48,7 @@ func GetDB() (*sqlx.DB, error) { globalDBLock.Lock() defer globalDBLock.Unlock() if globalDB == nil && globalDBErr == nil { - globalDB, globalDBErr = sqlx.Open("sqlite3", GetSessionDBName()) + globalDB, globalDBErr = sqlx.Open("sqlite3", fmt.Sprintf("file:%s?cache=shared&mode=rwc&_journal_mode=WAL&_busy_timeout=5000", GetSessionDBName())) } return globalDB, globalDBErr } @@ -59,18 +56,25 @@ func GetDB() (*sqlx.DB, error) { type SessionType struct { SessionId string `json:"sessionid"` Name string `json:"name"` + NotifyNum int64 `json:"notifynum"` Windows []*WindowType `json:"windows"` Cmds []*CmdType `json:"cmds"` Remotes []*RemoteInstance `json:"remotes"` } type WindowType struct { - SessionId string `json:"sessionid"` - WindowId string `json:"windowid"` - Name string `json:"name"` - CurRemote string `json:"curremote"` - Lines []*LineType `json:"lines"` - Version int `json:"version"` + SessionId string `json:"sessionid"` + WindowId string `json:"windowid"` + Name string `json:"name"` + CurRemote string `json:"curremote"` + Lines []*LineType `json:"lines"` + Cmds []*CmdType `json:"cmds"` + History []*HistoryItemType `json:"history"` + Remotes []*RemoteInstance `json:"remotes"` +} + +type HistoryItemType struct { + CmdStr string `json:"cmdstr"` } type RemoteState struct { @@ -96,9 +100,9 @@ func (s *RemoteState) Value() (driver.Value, error) { } type TermOpts struct { - Rows int `json:"rows"` - Cols int `json:"cols"` - FlexRows bool `json:"flexrows,omitempty"` + Rows int64 `json:"rows"` + Cols int64 `json:"cols"` + FlexRows bool `json:"flexrows,omitempty"` } func (opts *TermOpts) Scan(val interface{}) error { @@ -132,7 +136,7 @@ type RemoteInstance struct { type LineType struct { SessionId string `json:"sessionid"` WindowId string `json:"windowid"` - LineId int `json:"lineid"` + LineId int64 `json:"lineid"` Ts int64 `json:"ts"` UserId string `json:"userid"` LineType string `json:"linetype"` @@ -181,6 +185,7 @@ type CmdType struct { Status string `json:"status"` StartPk *packet.CmdStartPacketType `json:"startpk"` DonePk *packet.CmdDonePacketType `json:"donepk"` + UsedRows int64 `json:"usedrows"` RunOut []packet.PacketType `json:"runout"` } @@ -223,6 +228,7 @@ func (cmd *CmdType) ToMap() map[string]interface{} { rtn["startpk"] = quickJson(cmd.StartPk) rtn["donepk"] = quickJson(cmd.DonePk) rtn["runout"] = quickJson(cmd.RunOut) + rtn["usedrows"] = cmd.UsedRows return rtn } @@ -241,6 +247,7 @@ func CmdFromMap(m map[string]interface{}) *CmdType { quickSetJson(&cmd.StartPk, m, "startpk") quickSetJson(&cmd.DonePk, m, "donepk") quickSetJson(&cmd.RunOut, m, "runout") + quickSetInt64(&cmd.UsedRows, m, "usedrows") return &cmd } @@ -284,14 +291,6 @@ func AddCmdLine(ctx context.Context, sessionId string, windowId string, userId s return rtnLine, nil } -func GetNextLine() int { - NextLineLock.Lock() - defer NextLineLock.Unlock() - rtn := NextLineId - NextLineId++ - return rtn -} - func EnsureLocalRemote(ctx context.Context) error { remoteId, err := base.GetRemoteId() if err != nil {