From 6351082900fbc8e8e446a45cab5e6b23b8adc515 Mon Sep 17 00:00:00 2001 From: sawka Date: Tue, 12 Jul 2022 14:27:16 -0700 Subject: [PATCH] checkpoint --- db/migrations/000001_init.down.sql | 2 + db/migrations/000001_init.up.sql | 23 +++++++- pkg/sstore/dbops.go | 14 +++-- pkg/sstore/quick.go | 24 ++++++++- pkg/sstore/sstore.go | 87 +++++++++++++++++++----------- 5 files changed, 111 insertions(+), 39 deletions(-) diff --git a/db/migrations/000001_init.down.sql b/db/migrations/000001_init.down.sql index f523b435..fcb93770 100644 --- a/db/migrations/000001_init.down.sql +++ b/db/migrations/000001_init.down.sql @@ -1,5 +1,7 @@ DROP TABLE session; DROP TABLE window; +DROP TABLE screen; +DROP TABLE screen_window; DROP TABLE remote_instance; DROP TABLE line; DROP TABLE remote; diff --git a/db/migrations/000001_init.up.sql b/db/migrations/000001_init.up.sql index 8796f302..5c3e48e5 100644 --- a/db/migrations/000001_init.up.sql +++ b/db/migrations/000001_init.up.sql @@ -1,6 +1,8 @@ CREATE TABLE session ( sessionid varchar(36) PRIMARY KEY, - name varchar(50) NOT NULL + name varchar(50) NOT NULL, + sessionidx int NOT NULL, + notifynum int NOT NULL ); CREATE UNIQUE INDEX session_name_unique ON session(name); @@ -9,11 +11,27 @@ CREATE TABLE window ( windowid varchar(36) NOT NULL, name varchar(50) NOT NULL, curremote varchar(50) NOT NULL, - version int NOT NULL, + winopts json NOT NULL, PRIMARY KEY (sessionid, windowid) ); CREATE UNIQUE INDEX window_name_unique ON window(sessionid, name); +CREATE TABLE screen ( + sessionid varchar(36) NOT NULL, + screenid varchar(36) NOT NULL, + name varchar(50) NOT NULL, + screenidx int NOT NULL, + PRIMARY KEY (sessionid, screenid) +); + +CREATE TABLE screen_window ( + sessionid varchar(36) NOT NULL, + screenid varchar(36) NOT NULL, + windowid varchar(36) NOT NULL, + layout json NOT NULL, + PRIMARY KEY (sessionid, screenid, windowid) +); + CREATE TABLE remote_instance ( riid varchar(36) PRIMARY KEY, name varchar(50) NOT NULL, @@ -57,6 +75,7 @@ CREATE TABLE cmd ( startpk json NOT NULL, donepk json NOT NULL, runout json NOT NULL, + usedrows int NOT NULL, PRIMARY KEY (sessionid, cmdid) ); diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index fc22df08..3355d698 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -138,7 +138,7 @@ func GetSessionById(ctx context.Context, id string) (*SessionType, error) { return nil } rtnSession = &session - query = `SELECT sessionid, windowid, name, curremote FROM window WHERE sessionid = ?` + query = `SELECT * 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) @@ -197,11 +197,15 @@ func InsertSessionWithName(ctx context.Context, sessionName string) (string, err return fmt.Errorf("cannot create session with duplicate name") } } + var maxSessionIdx int64 + query := `SELECT COALESCE(max(sessionidx), 0) FROM session` + tx.GetWrap(&maxSessionIdx, query) newSession := &SessionType{ - SessionId: newSessionId, - Name: sessionName, + SessionId: newSessionId, + Name: sessionName, + SessionIdx: maxSessionIdx + 1, } - query := `INSERT INTO session (sessionid, name, notifynum) VALUES (:sessionid, :name, :notifynum)` + query = `INSERT INTO session (sessionid, name, sessionidx, notifynum) VALUES (:sessionid, :name, :sessionidx, :notifynum)` tx.NamedExecWrap(query, newSession) window := &WindowType{ SessionId: newSessionId, @@ -269,7 +273,7 @@ func InsertWindow(ctx context.Context, sessionId string, windowName string) (str } func txInsertWindow(tx *TxWrap, window *WindowType) { - query := `INSERT INTO window (sessionid, windowid, name, curremote) VALUES (:sessionid, :windowid, :name, :curremote)` + query := `INSERT INTO window (sessionid, windowid, name, curremote, winopts) VALUES (:sessionid, :windowid, :name, :curremote, :winopts)` tx.NamedExecWrap(query, window) } diff --git a/pkg/sstore/quick.go b/pkg/sstore/quick.go index a4b8aaef..c111b71a 100644 --- a/pkg/sstore/quick.go +++ b/pkg/sstore/quick.go @@ -1,6 +1,10 @@ package sstore -import "encoding/json" +import ( + "database/sql/driver" + "encoding/json" + "fmt" +) func quickSetStr(strVal *string, m map[string]interface{}, name string) { v, ok := m[name] @@ -66,3 +70,21 @@ func quickJson(v interface{}) string { barr, _ := json.Marshal(v) return string(barr) } + +func quickScanJson(ptr interface{}, val interface{}) error { + strVal, ok := val.(string) + if !ok { + return fmt.Errorf("cannot scan '%T' into '%T'", val, ptr) + } + if strVal == "" { + return nil + } + return json.Unmarshal([]byte(strVal), ptr) +} + +func quickValueJson(v interface{}) (driver.Value, error) { + if v == nil { + return "", nil + } + return json.Marshal(v) +} diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index b4009e20..aa0b97ee 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -3,7 +3,6 @@ package sstore import ( "context" "database/sql/driver" - "encoding/json" "fmt" "log" "path" @@ -54,12 +53,24 @@ 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"` + SessionId string `json:"sessionid"` + Name string `json:"name"` + SessionIdx int64 `json:"sessionidx"` + NotifyNum int64 `json:"notifynum"` + Windows []*WindowType `json:"windows"` + Cmds []*CmdType `json:"cmds"` + Remotes []*RemoteInstance `json:"remotes"` +} + +type WindowOptsType struct { +} + +func (opts *WindowOptsType) Scan(val interface{}) error { + return quickScanJson(opts, val) +} + +func (opts *WindowOptsType) Value() (driver.Value, error) { + return quickValueJson(opts) } type WindowType struct { @@ -71,6 +82,40 @@ type WindowType struct { Cmds []*CmdType `json:"cmds"` History []*HistoryItemType `json:"history"` Remotes []*RemoteInstance `json:"remotes"` + WinOpts WindowOptsType `json:"winopts"` +} + +type ScreenType struct { + SessionId string `json:"sessionid"` + ScreenId string `json:"screenid"` + ScreenIdx int64 `json:"screenidx"` + Name string `json:"name"` +} + +type LayoutType struct { + ZIndex int64 `json:"zindex"` + Float bool `json:"float"` + Top string `json:"top"` + Bottom string `json:"bottom"` + Left string `json:"left"` + Right string `json:"right"` + Width string `json:"width"` + Height string `json:"height"` +} + +func (l *LayoutType) Scan(val interface{}) error { + return quickScanJson(l, val) +} + +func (l *LayoutType) Value() (driver.Value, error) { + return quickValueJson(l) +} + +type ScreenWindowType struct { + SessionId string `json:"sessionid"` + ScreenId string `json:"screenid"` + WindowId string `json:"windowid"` + Layout LayoutType `json:"layout"` } type HistoryItemType struct { @@ -82,21 +127,11 @@ type RemoteState struct { } func (s *RemoteState) Scan(val interface{}) error { - if strVal, ok := val.(string); ok { - if strVal == "" { - return nil - } - err := json.Unmarshal([]byte(strVal), s) - if err != nil { - return err - } - return nil - } - return fmt.Errorf("cannot scan '%T' into RemoteState", val) + return quickScanJson(s, val) } func (s *RemoteState) Value() (driver.Value, error) { - return json.Marshal(s) + return quickValueJson(s) } type TermOpts struct { @@ -106,21 +141,11 @@ type TermOpts struct { } func (opts *TermOpts) Scan(val interface{}) error { - if strVal, ok := val.(string); ok { - if strVal == "" { - return nil - } - err := json.Unmarshal([]byte(strVal), opts) - if err != nil { - return err - } - return nil - } - return fmt.Errorf("cannot scan '%T' into TermOpts", val) + return quickScanJson(opts, val) } func (opts *TermOpts) Value() (driver.Value, error) { - return json.Marshal(opts) + return quickValueJson(opts) } type RemoteInstance struct {