mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
txwrap can now be properly nested. add json conversion functions to quick
This commit is contained in:
+11
-3
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func NumSessions(ctx context.Context) (int, error) {
|
||||
db, err := GetDB()
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func InsertRemote(ctx context.Context, remote *RemoteType) error {
|
||||
if remote == nil {
|
||||
return fmt.Errorf("cannot insert nil remote")
|
||||
}
|
||||
db, err := GetDB()
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -156,7 +156,7 @@ func GetSessionById(ctx context.Context, id string) (*SessionType, error) {
|
||||
}
|
||||
|
||||
func GetSessionByName(ctx context.Context, name string) (*SessionType, error) {
|
||||
db, err := GetDB()
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -228,6 +228,14 @@ func containsStr(strs []string, testStr string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func InsertScreen(ctx context.Context, sessionId string, screenName string) (string, error) {
|
||||
var newScreenId string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
return nil
|
||||
})
|
||||
return newScreenId, txErr
|
||||
}
|
||||
|
||||
// if windowName == "", it will be generated
|
||||
// returns (windowid, err)
|
||||
func InsertWindow(ctx context.Context, sessionId string, windowName string) (string, error) {
|
||||
|
||||
+13
-5
@@ -72,19 +72,27 @@ func quickJson(v interface{}) string {
|
||||
}
|
||||
|
||||
func quickScanJson(ptr interface{}, val interface{}) error {
|
||||
strVal, ok := val.(string)
|
||||
barrVal, ok := val.([]byte)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot scan '%T' into '%T'", val, ptr)
|
||||
strVal, ok := val.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot scan '%T' into '%T'", val, ptr)
|
||||
}
|
||||
barrVal = []byte(strVal)
|
||||
}
|
||||
if strVal == "" {
|
||||
if len(barrVal) == 0 {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal([]byte(strVal), ptr)
|
||||
return json.Unmarshal(barrVal, ptr)
|
||||
}
|
||||
|
||||
func quickValueJson(v interface{}) (driver.Value, error) {
|
||||
if v == nil {
|
||||
return "", nil
|
||||
}
|
||||
return json.Marshal(v)
|
||||
barr, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return string(barr), nil
|
||||
}
|
||||
|
||||
@@ -43,7 +43,10 @@ func GetSessionDBName() string {
|
||||
return path.Join(scHome, DBFileName)
|
||||
}
|
||||
|
||||
func GetDB() (*sqlx.DB, error) {
|
||||
func GetDB(ctx context.Context) (*sqlx.DB, error) {
|
||||
if IsTxWrapContext(ctx) {
|
||||
return nil, fmt.Errorf("cannot call GetDB from within a running transaction")
|
||||
}
|
||||
globalDBLock.Lock()
|
||||
defer globalDBLock.Unlock()
|
||||
if globalDB == nil && globalDBErr == nil {
|
||||
@@ -69,7 +72,7 @@ func (opts *WindowOptsType) Scan(val interface{}) error {
|
||||
return quickScanJson(opts, val)
|
||||
}
|
||||
|
||||
func (opts *WindowOptsType) Value() (driver.Value, error) {
|
||||
func (opts WindowOptsType) Value() (driver.Value, error) {
|
||||
return quickValueJson(opts)
|
||||
}
|
||||
|
||||
@@ -107,7 +110,7 @@ func (l *LayoutType) Scan(val interface{}) error {
|
||||
return quickScanJson(l, val)
|
||||
}
|
||||
|
||||
func (l *LayoutType) Value() (driver.Value, error) {
|
||||
func (l LayoutType) Value() (driver.Value, error) {
|
||||
return quickValueJson(l)
|
||||
}
|
||||
|
||||
@@ -130,7 +133,7 @@ func (s *RemoteState) Scan(val interface{}) error {
|
||||
return quickScanJson(s, val)
|
||||
}
|
||||
|
||||
func (s *RemoteState) Value() (driver.Value, error) {
|
||||
func (s RemoteState) Value() (driver.Value, error) {
|
||||
return quickValueJson(s)
|
||||
}
|
||||
|
||||
@@ -144,7 +147,7 @@ func (opts *TermOpts) Scan(val interface{}) error {
|
||||
return quickScanJson(opts, val)
|
||||
}
|
||||
|
||||
func (opts *TermOpts) Value() (driver.Value, error) {
|
||||
func (opts TermOpts) Value() (driver.Value, error) {
|
||||
return quickValueJson(opts)
|
||||
}
|
||||
|
||||
|
||||
+39
-20
@@ -10,32 +10,47 @@ import (
|
||||
type TxWrap struct {
|
||||
Txx *sqlx.Tx
|
||||
Err error
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
type txWrapKey struct{}
|
||||
|
||||
func IsTxWrapContext(ctx context.Context) bool {
|
||||
ctxVal := ctx.Value(txWrapKey{})
|
||||
return ctxVal != nil
|
||||
}
|
||||
|
||||
func WithTx(ctx context.Context, fn func(tx *TxWrap) error) (rtnErr error) {
|
||||
db, err := GetDB()
|
||||
if err != nil {
|
||||
return err
|
||||
var txWrap *TxWrap
|
||||
ctxVal := ctx.Value(txWrapKey{})
|
||||
if ctxVal != nil {
|
||||
txWrap = ctxVal.(*TxWrap)
|
||||
}
|
||||
tx, beginErr := db.BeginTxx(ctx, nil)
|
||||
if beginErr != nil {
|
||||
return beginErr
|
||||
if txWrap == nil {
|
||||
db, err := GetDB(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx, beginErr := db.BeginTxx(ctx, nil)
|
||||
if beginErr != nil {
|
||||
return beginErr
|
||||
}
|
||||
txWrap = &TxWrap{Txx: tx, Ctx: ctx}
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
txWrap.Txx.Rollback()
|
||||
panic(p)
|
||||
}
|
||||
if rtnErr != nil {
|
||||
txWrap.Txx.Rollback()
|
||||
} else {
|
||||
rtnErr = txWrap.Txx.Commit()
|
||||
}
|
||||
}()
|
||||
}
|
||||
txWrap := &TxWrap{Txx: tx}
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
tx.Rollback()
|
||||
panic(p)
|
||||
}
|
||||
if rtnErr != nil {
|
||||
tx.Rollback()
|
||||
} else {
|
||||
rtnErr = tx.Commit()
|
||||
}
|
||||
}()
|
||||
fnErr := fn(txWrap)
|
||||
if fnErr != nil {
|
||||
return fnErr
|
||||
if txWrap.Err == nil && fnErr != nil {
|
||||
txWrap.Err = fnErr
|
||||
}
|
||||
if txWrap.Err != nil {
|
||||
return txWrap.Err
|
||||
@@ -43,6 +58,10 @@ func WithTx(ctx context.Context, fn func(tx *TxWrap) error) (rtnErr error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx *TxWrap) Context() context.Context {
|
||||
return context.WithValue(tx.Ctx, txWrapKey{}, tx)
|
||||
}
|
||||
|
||||
func (tx *TxWrap) NamedExecWrap(query string, arg interface{}) sql.Result {
|
||||
if tx.Err != nil {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user