mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-03-13 13:39:48 +01:00
updates for /screen:close
This commit is contained in:
parent
d2530339e4
commit
962261ec35
@ -123,9 +123,11 @@ func init() {
|
||||
|
||||
registerCmdFn("screen", ScreenCommand)
|
||||
registerCmdFn("screen:close", ScreenCloseCommand)
|
||||
registerCmdFn("screen:purge", ScreenPurgeCommand)
|
||||
registerCmdFn("screen:open", ScreenOpenCommand)
|
||||
registerCmdAlias("screen:new", ScreenOpenCommand)
|
||||
registerCmdFn("screen:set", ScreenSetCommand)
|
||||
registerCmdFn("screen:showall", ScreenShowAllCommand)
|
||||
|
||||
registerCmdAlias("remote", RemoteCommand)
|
||||
registerCmdFn("remote:show", RemoteShowCommand)
|
||||
@ -378,10 +380,53 @@ func EvalCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.
|
||||
}
|
||||
|
||||
func ScreenCloseCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen)
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session) // don't force R_Screen
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot close screen: %w", err)
|
||||
}
|
||||
screenId := ids.ScreenId
|
||||
if len(pk.Args) > 0 {
|
||||
ri, err := resolveSessionScreen(ctx, ids.SessionId, pk.Args[0], ids.ScreenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot resolve screen arg: %v", err)
|
||||
}
|
||||
screenId = ri.Id
|
||||
}
|
||||
if screenId == "" {
|
||||
return nil, fmt.Errorf("/screen:close no active screen or screen arg passed")
|
||||
}
|
||||
closeVal := true
|
||||
if len(pk.Args) > 1 {
|
||||
closeVal = resolveBool(pk.Args[1], true)
|
||||
}
|
||||
var update sstore.UpdatePacket
|
||||
if closeVal {
|
||||
update, err = sstore.CloseScreen(ctx, ids.SessionId, screenId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return update, nil
|
||||
} else {
|
||||
fmt.Printf("unclose screen %s\n", screenId)
|
||||
err = sstore.UnCloseScreen(ctx, ids.SessionId, screenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot re-open screen: %v", err)
|
||||
}
|
||||
screen, err := sstore.GetScreenById(ctx, ids.SessionId, screenId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:close cannot get updated screen obj: %v", err)
|
||||
}
|
||||
update, session := sstore.MakeSingleSessionUpdate(ids.SessionId)
|
||||
session.Screens = append(session.Screens, screen)
|
||||
return update, nil
|
||||
}
|
||||
}
|
||||
|
||||
func ScreenPurgeCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:purge cannot close screen: %w", err)
|
||||
}
|
||||
update, err := sstore.DeleteScreen(ctx, ids.SessionId, ids.ScreenId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -900,6 +945,33 @@ func RemoteShowAllCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ScreenShowAllCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session)
|
||||
screenArr, err := sstore.GetAllSessionScreens(ctx, ids.SessionId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("/screen:showall error getting screen list: %v", err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
for _, screen := range screenArr {
|
||||
var closedStr string
|
||||
if screen.Closed {
|
||||
closedStr = " (closed)"
|
||||
}
|
||||
screenIdxStr := "-"
|
||||
if screen.ScreenIdx != 0 {
|
||||
screenIdxStr = strconv.Itoa(int(screen.ScreenIdx))
|
||||
}
|
||||
outStr := fmt.Sprintf("%s %-30s %s\n", screen.ScreenId, screen.Name+closedStr, screenIdxStr)
|
||||
buf.WriteString(outStr)
|
||||
}
|
||||
return sstore.ModelUpdate{
|
||||
Info: &sstore.InfoMsgType{
|
||||
InfoTitle: fmt.Sprintf("all screens for session"),
|
||||
InfoLines: splitLinesForInfo(buf.String()),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func RemoteArchiveCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Window|R_Remote)
|
||||
if err != nil {
|
||||
@ -1309,13 +1381,19 @@ func SessionDeleteCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot delete session: %v", err)
|
||||
}
|
||||
sessionIds, _ := sstore.GetAllSessionIds(ctx) // ignore error, session is already deleted so that's the main return value
|
||||
delSession := &sstore.SessionType{SessionId: ids.SessionId, Remove: true}
|
||||
update := sstore.ModelUpdate{
|
||||
Sessions: []*sstore.SessionType{delSession},
|
||||
}
|
||||
if len(sessionIds) > 0 {
|
||||
update.ActiveSessionId = sessionIds[0]
|
||||
activeSessionId, _ := sstore.GetActiveSessionId(ctx) // ignore error
|
||||
if activeSessionId == "" {
|
||||
sessionIds, _ := sstore.GetAllSessionIds(ctx) // ignore error, session is already deleted so that's the main return value
|
||||
if len(sessionIds) > 0 {
|
||||
err = sstore.SetActiveSessionId(ctx, sessionIds[0])
|
||||
if err != nil {
|
||||
update.ActiveSessionId = sessionIds[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
return update, nil
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func sessionsToResolveItems(sessions []*sstore.SessionType) []ResolveItem {
|
||||
}
|
||||
rtn := make([]ResolveItem, len(sessions))
|
||||
for idx, session := range sessions {
|
||||
rtn[idx] = ResolveItem{Name: session.Name, Id: session.SessionId}
|
||||
rtn[idx] = ResolveItem{Name: session.Name, Id: session.SessionId, Hidden: session.Closed}
|
||||
}
|
||||
return rtn
|
||||
}
|
||||
@ -69,7 +69,7 @@ func screensToResolveItems(screens []*sstore.ScreenType) []ResolveItem {
|
||||
}
|
||||
rtn := make([]ResolveItem, len(screens))
|
||||
for idx, screen := range screens {
|
||||
rtn[idx] = ResolveItem{Name: screen.Name, Id: screen.ScreenId}
|
||||
rtn[idx] = ResolveItem{Name: screen.Name, Id: screen.ScreenId, Hidden: screen.Closed}
|
||||
}
|
||||
return rtn
|
||||
}
|
||||
@ -133,7 +133,13 @@ func parsePosArg(posStr string) *posArgType {
|
||||
return &posArgType{Pos: pos}
|
||||
}
|
||||
|
||||
func resolveByPosition(isNumeric bool, items []ResolveItem, curId string, posStr string) *ResolveItem {
|
||||
func resolveByPosition(isNumeric bool, allItems []ResolveItem, curId string, posStr string) *ResolveItem {
|
||||
items := make([]ResolveItem, 0, len(allItems))
|
||||
for _, item := range allItems {
|
||||
if !item.Hidden {
|
||||
items = append(items, item)
|
||||
}
|
||||
}
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -160,7 +166,8 @@ func resolveByPosition(isNumeric bool, items []ResolveItem, curId string, posStr
|
||||
finalPos = curIdx + posArg.Pos
|
||||
} else if isNumeric {
|
||||
// these resolve items have a "Num" set that should be used to look up non-relative positions
|
||||
for _, item := range items {
|
||||
// use allItems for numeric resolve
|
||||
for _, item := range allItems {
|
||||
if item.Num == posArg.Pos {
|
||||
return &item
|
||||
}
|
||||
@ -342,7 +349,7 @@ func genericResolve(arg string, curArg string, items []ResolveItem, isNumeric bo
|
||||
if (isUuid && item.Id == arg) || (tryPuid && strings.HasPrefix(item.Id, arg)) {
|
||||
return &item, nil
|
||||
}
|
||||
if item.Name != "" {
|
||||
if !item.Hidden && item.Name != "" {
|
||||
if item.Name == arg {
|
||||
return &item, nil
|
||||
}
|
||||
@ -396,7 +403,7 @@ func resolveScreenArg(sessionId string, screenArg string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
if _, err := uuid.Parse(screenArg); err != nil {
|
||||
return "", fmt.Errorf("invalid screen arg specified (must be sessionid) '%s'", screenArg)
|
||||
return "", fmt.Errorf("invalid screen arg specified (must be screenid) '%s'", screenArg)
|
||||
}
|
||||
return screenArg, nil
|
||||
}
|
||||
|
@ -233,6 +233,7 @@ func GetHistoryItems(ctx context.Context, sessionId string, windowId string, opt
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
// includes closed sessions
|
||||
func GetBareSessions(ctx context.Context) ([]*SessionType, error) {
|
||||
var rtn []*SessionType
|
||||
err := WithTx(ctx, func(tx *TxWrap) error {
|
||||
@ -249,7 +250,7 @@ func GetBareSessions(ctx context.Context) ([]*SessionType, error) {
|
||||
func GetAllSessionIds(ctx context.Context) ([]string, error) {
|
||||
var rtn []string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT sessionid from session ORDER by sessionidx`
|
||||
query := `SELECT sessionid from session WHERE NOT closed ORDER by sessionidx`
|
||||
rtn = tx.SelectStrings(query)
|
||||
return nil
|
||||
})
|
||||
@ -287,7 +288,7 @@ func GetAllSessions(ctx context.Context) (*ModelUpdate, error) {
|
||||
session.Full = true
|
||||
}
|
||||
var screens []*ScreenType
|
||||
query = `SELECT * FROM screen ORDER BY screenidx`
|
||||
query = `SELECT * FROM screen WHERE NOT closed ORDER BY screenidx`
|
||||
tx.SelectWrap(&screens, query)
|
||||
screenMap := make(map[string][]*ScreenType)
|
||||
for _, screen := range screens {
|
||||
@ -352,6 +353,7 @@ func GetWindowById(ctx context.Context, sessionId string, windowId string) (*Win
|
||||
return rtnWindow, err
|
||||
}
|
||||
|
||||
// includes closed screens
|
||||
func GetSessionScreens(ctx context.Context, sessionId string) ([]*ScreenType, error) {
|
||||
var rtn []*ScreenType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
@ -362,6 +364,16 @@ func GetSessionScreens(ctx context.Context, sessionId string) ([]*ScreenType, er
|
||||
return rtn, txErr
|
||||
}
|
||||
|
||||
func GetAllSessionScreens(ctx context.Context, sessionId string) ([]*ScreenType, error) {
|
||||
var rtn []*ScreenType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT * FROM screen WHERE sessionid = ? ORDER BY closed, screenidx`
|
||||
tx.SelectWrap(&rtn, query, sessionId)
|
||||
return nil
|
||||
})
|
||||
return rtn, txErr
|
||||
}
|
||||
|
||||
func GetSessionById(ctx context.Context, id string) (*SessionType, error) {
|
||||
allSessionsUpdate, err := GetAllSessions(ctx)
|
||||
if err != nil {
|
||||
@ -436,7 +448,7 @@ func InsertSessionWithName(ctx context.Context, sessionName string, activate boo
|
||||
|
||||
func SetActiveSessionId(ctx context.Context, sessionId string) error {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT sessionid FROM session WHERE sessionid = ?`
|
||||
query := `SELECT sessionid FROM session WHERE sessionid = ? AND NOT closed`
|
||||
if !tx.Exists(query, sessionId) {
|
||||
return fmt.Errorf("cannot switch to session, not found")
|
||||
}
|
||||
@ -447,6 +459,16 @@ func SetActiveSessionId(ctx context.Context, sessionId string) error {
|
||||
return txErr
|
||||
}
|
||||
|
||||
func GetActiveSessionId(ctx context.Context) (string, error) {
|
||||
var rtnId string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT activesessionid FROM client`
|
||||
rtnId = tx.GetString(query)
|
||||
return nil
|
||||
})
|
||||
return rtnId, txErr
|
||||
}
|
||||
|
||||
func SetWinSize(ctx context.Context, winSize ClientWinSizeType) error {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `UPDATE client SET winsize = ?`
|
||||
@ -492,7 +514,7 @@ func fmtUniqueName(name string, defaultFmtStr string, startIdx int, strs []strin
|
||||
func InsertScreen(ctx context.Context, sessionId string, origScreenName string, activate bool) (UpdatePacket, error) {
|
||||
var newScreenId string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT sessionid FROM session WHERE sessionid = ?`
|
||||
query := `SELECT sessionid FROM session WHERE sessionid = ? AND NOT closed`
|
||||
if !tx.Exists(query, sessionId) {
|
||||
return fmt.Errorf("cannot create screen, no session found")
|
||||
}
|
||||
@ -501,8 +523,8 @@ func InsertScreen(ctx context.Context, sessionId string, origScreenName string,
|
||||
return fmt.Errorf("cannot create screen, no local remote found")
|
||||
}
|
||||
newWindowId := txCreateWindow(tx, sessionId, RemotePtrType{RemoteId: remoteId})
|
||||
maxScreenIdx := tx.GetInt(`SELECT COALESCE(max(screenidx), 0) FROM screen WHERE sessionid = ?`, sessionId)
|
||||
screenNames := tx.SelectStrings(`SELECT name FROM screen WHERE sessionid = ?`, sessionId)
|
||||
maxScreenIdx := tx.GetInt(`SELECT COALESCE(max(screenidx), 0) FROM screen WHERE sessionid = ? AND NOT closed`, sessionId)
|
||||
screenNames := tx.SelectStrings(`SELECT name FROM screen WHERE sessionid = ? AND NOT closed`, sessionId)
|
||||
screenName := fmtUniqueName(origScreenName, "s%d", maxScreenIdx+1, screenNames)
|
||||
newScreenId = scbase.GenPromptUUID()
|
||||
query = `INSERT INTO screen (sessionid, screenid, name, activewindowid, screenidx, screenopts, ownerid, sharemode, incognito, closed) VALUES (?, ?, ?, ?, ?, ?, '', 'local', 0, 0)`
|
||||
@ -810,7 +832,7 @@ func getNextId(ids []string, delId string) string {
|
||||
|
||||
func SwitchScreenById(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?`
|
||||
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ? AND NOT closed`
|
||||
if !tx.Exists(query, sessionId, screenId) {
|
||||
return fmt.Errorf("cannot switch to screen, screen=%s does not exist in session=%s", screenId, sessionId)
|
||||
}
|
||||
@ -826,12 +848,66 @@ func SwitchScreenById(ctx context.Context, sessionId string, screenId string) (U
|
||||
func CleanWindows() {
|
||||
}
|
||||
|
||||
func CloseScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) {
|
||||
var newActiveScreenId string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?`
|
||||
if !tx.Exists(query, sessionId, screenId) {
|
||||
return fmt.Errorf("cannot close screen (not found)")
|
||||
}
|
||||
query = `SELECT closed FROM screen WHERE sessionid = ? AND screenid = ?`
|
||||
closeVal := tx.GetBool(query, sessionId, screenId)
|
||||
if closeVal {
|
||||
return nil
|
||||
}
|
||||
query = `SELECT count(*) FROM screen WHERE sessionid = ? AND NOT closed`
|
||||
numScreens := tx.GetInt(query, sessionId)
|
||||
if numScreens <= 1 {
|
||||
return fmt.Errorf("cannot close the last screen in a session")
|
||||
}
|
||||
query = `UPDATE screen SET closed = 1, screenidx = 0 WHERE sessionid = ? AND screenid = ?`
|
||||
tx.ExecWrap(query, sessionId, screenId)
|
||||
isActive := tx.Exists(`SELECT sessionid FROM session WHERE sessionid = ? AND activescreenid = ?`, sessionId, screenId)
|
||||
if isActive {
|
||||
screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT closed ORDER BY screenidx`, sessionId)
|
||||
nextId := getNextId(screenIds, screenId)
|
||||
tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId)
|
||||
newActiveScreenId = nextId
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if txErr != nil {
|
||||
return nil, txErr
|
||||
}
|
||||
update, session := MakeSingleSessionUpdate(sessionId)
|
||||
session.ActiveScreenId = newActiveScreenId
|
||||
session.Screens = append(session.Screens, &ScreenType{SessionId: sessionId, ScreenId: screenId, Remove: true})
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func UnCloseScreen(ctx context.Context, sessionId string, screenId string) error {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ? AND closed`
|
||||
if !tx.Exists(query, sessionId, screenId) {
|
||||
return fmt.Errorf("cannot re-open screen (not found or not closed)")
|
||||
}
|
||||
origScreenName := tx.GetString(`SELECT name FROM screen WHERE sessionid = ? AND screenid = ?`, sessionId, screenId)
|
||||
maxScreenIdx := tx.GetInt(`SELECT COALESCE(max(screenidx), 0) FROM screen WHERE sessionid = ? AND NOT closed`, sessionId)
|
||||
screenNames := tx.SelectStrings(`SELECT name FROM screen WHERE sessionid = ? AND NOT closed`, sessionId)
|
||||
newScreenName := fmtUniqueName(origScreenName, "s-%d", 2, screenNames)
|
||||
query = `UPDATE screen SET closed = 0, screenidx = ?, name = ? WHERE sessionid = ? AND screenid = ?`
|
||||
tx.ExecWrap(query, maxScreenIdx+1, newScreenName, sessionId, screenId)
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
||||
func DeleteScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) {
|
||||
var newActiveScreenId string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
isActive := tx.Exists(`SELECT sessionid FROM session WHERE sessionid = ? AND activescreenid = ?`, sessionId, screenId)
|
||||
if isActive {
|
||||
screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? ORDER BY screenidx`, sessionId)
|
||||
screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT closed ORDER BY screenidx`, sessionId)
|
||||
nextId := getNextId(screenIds, screenId)
|
||||
tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId)
|
||||
newActiveScreenId = nextId
|
||||
@ -1068,7 +1144,7 @@ func SetScreenName(ctx context.Context, sessionId string, screenId string, name
|
||||
if !tx.Exists(query, sessionId, screenId) {
|
||||
return fmt.Errorf("screen does not exist")
|
||||
}
|
||||
query = `SELECT screenid FROM screen WHERE sessionid = ? AND name = ?`
|
||||
query = `SELECT screenid FROM screen WHERE sessionid = ? AND name = ? AND NOT closed`
|
||||
dupScreenId := tx.GetString(query, sessionId, name)
|
||||
if dupScreenId == screenId {
|
||||
return nil
|
||||
@ -1169,8 +1245,10 @@ func GetSessionStats(ctx context.Context, sessionId string) (*SessionStatsType,
|
||||
if !tx.Exists(query, sessionId) {
|
||||
return fmt.Errorf("not found")
|
||||
}
|
||||
query = `SELECT count(*) FROM screen WHERE sessionid = ?`
|
||||
query = `SELECT count(*) FROM screen WHERE sessionid = ? AND NOT closed`
|
||||
rtn.NumScreens = tx.GetInt(query, sessionId)
|
||||
query = `SELECT count(*) FROM screen WHERE sessionid = ? AND closed`
|
||||
rtn.NumClosedScreens = tx.GetInt(query, sessionId)
|
||||
query = `SELECT count(*) FROM window WHERE sessionid = ?`
|
||||
rtn.NumWindows = tx.GetInt(query, sessionId)
|
||||
query = `SELECT count(*) FROM line WHERE sessionid = ?`
|
||||
|
@ -162,12 +162,13 @@ type SessionType struct {
|
||||
}
|
||||
|
||||
type SessionStatsType struct {
|
||||
SessionId string `json:"sessionid"`
|
||||
NumScreens int `json:"numscreens"`
|
||||
NumWindows int `json:"numwindows"`
|
||||
NumLines int `json:"numlines"`
|
||||
NumCmds int `json:"numcmds"`
|
||||
DiskStats SessionDiskSizeType `json:"diskstats"`
|
||||
SessionId string `json:"sessionid"`
|
||||
NumScreens int `json:"numscreens"`
|
||||
NumClosedScreens int `json:"numclosedscreens"`
|
||||
NumWindows int `json:"numwindows"`
|
||||
NumLines int `json:"numlines"`
|
||||
NumCmds int `json:"numcmds"`
|
||||
DiskStats SessionDiskSizeType `json:"diskstats"`
|
||||
}
|
||||
|
||||
type WindowOptsType struct {
|
||||
@ -592,9 +593,10 @@ type LineType struct {
|
||||
}
|
||||
|
||||
type ResolveItem struct {
|
||||
Name string
|
||||
Num int
|
||||
Id string
|
||||
Name string
|
||||
Num int
|
||||
Id string
|
||||
Hidden bool
|
||||
}
|
||||
|
||||
type SSHOpts struct {
|
||||
|
@ -105,6 +105,12 @@ func (tx *TxWrap) GetString(query string, args ...interface{}) string {
|
||||
return rtnStr
|
||||
}
|
||||
|
||||
func (tx *TxWrap) GetBool(query string, args ...interface{}) bool {
|
||||
var rtnBool bool
|
||||
tx.GetWrap(&rtnBool, query, args...)
|
||||
return rtnBool
|
||||
}
|
||||
|
||||
func (tx *TxWrap) SelectStrings(query string, args ...interface{}) []string {
|
||||
var rtnArr []string
|
||||
tx.SelectWrap(&rtnArr, query, args...)
|
||||
|
Loading…
Reference in New Issue
Block a user