diff --git a/go.mod b/go.mod index 9efde4020..c4ed9eb89 100644 --- a/go.mod +++ b/go.mod @@ -3,27 +3,26 @@ module github.com/scripthaus-dev/sh2-server go 1.17 require ( + github.com/alessio/shellescape v1.4.1 + github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 + github.com/creack/pty v1.1.18 github.com/golang-migrate/migrate/v4 v4.15.2 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.5.0 github.com/jmoiron/sqlx v1.3.5 github.com/mattn/go-sqlite3 v1.14.14 + github.com/sawka/txwrap v0.1.0 github.com/scripthaus-dev/mshell v0.0.0 + golang.org/x/mod v0.5.1 + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad + mvdan.cc/sh/v3 v3.5.1 ) require ( - github.com/alessio/shellescape v1.4.1 // indirect - github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect - github.com/creack/pty v1.1.18 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/mattn/go-shellwords v1.0.12 // indirect go.uber.org/atomic v1.7.0 // indirect - golang.org/x/mod v0.5.1 // indirect - golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect - mvdan.cc/sh/v3 v3.5.1 // indirect ) replace github.com/scripthaus-dev/mshell v0.0.0 => ../mshell/ diff --git a/go.sum b/go.sum index 97dd6f71f..e47f8fcbf 100644 --- a/go.sum +++ b/go.sum @@ -74,6 +74,7 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= @@ -332,6 +333,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= @@ -395,9 +397,10 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= +github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= @@ -551,6 +554,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE= @@ -578,6 +582,7 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -748,10 +753,13 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -789,7 +797,6 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -906,6 +913,7 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -955,6 +963,9 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -964,6 +975,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sawka/txwrap v0.1.0 h1:uWGplmEJUEd9WGYZy9fU+hoC2Z6Yal4NMH5DbKsUTdo= +github.com/sawka/txwrap v0.1.0/go.mod h1:T3nlw2gVpuolo6/XEetvBbk1oMXnY978YmBFy1UyHvw= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -1518,6 +1531,7 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= @@ -1802,6 +1816,7 @@ modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4= +mvdan.cc/editorconfig v0.2.0/go.mod h1:lvnnD3BNdBYkhq+B4uBuFFKatfp02eB6HixDvEz91C0= mvdan.cc/sh/v3 v3.5.1 h1:hmP3UOw4f+EYexsJjFxvU38+kn+V/s2CclXHanIBkmQ= mvdan.cc/sh/v3 v3.5.1/go.mod h1:1JcoyAKm1lZw/2bZje/iYKWicU/KMd0rsyJeKHnsK4E= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index 5bf2bee78..77d9d7792 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -5,9 +5,12 @@ import ( "fmt" "strconv" "strings" + "sync" "time" "github.com/google/uuid" + "github.com/jmoiron/sqlx" + "github.com/sawka/txwrap" "github.com/scripthaus-dev/mshell/pkg/base" "github.com/scripthaus-dev/mshell/pkg/packet" "github.com/scripthaus-dev/mshell/pkg/shexec" @@ -17,6 +20,35 @@ import ( const HistoryCols = "historyid, ts, userid, sessionid, screenid, windowid, lineid, cmdid, haderror, cmdstr, remoteownerid, remoteid, remotename, ismetacmd, incognito" const DefaultMaxHistoryItems = 1000 +type SingleConnDBGetter struct { + SingleConnLock *sync.Mutex +} + +type TxWrap = txwrap.TxWrap + +var dbWrap *SingleConnDBGetter + +func init() { + dbWrap = &SingleConnDBGetter{SingleConnLock: &sync.Mutex{}} +} + +func (dbg *SingleConnDBGetter) GetDB(ctx context.Context) (*sqlx.DB, error) { + db, err := GetDB(ctx) + if err != nil { + return nil, err + } + dbg.SingleConnLock.Lock() + return db, nil +} + +func (dbg *SingleConnDBGetter) ReleaseDB(db *sqlx.DB) { + dbg.SingleConnLock.Unlock() +} + +func WithTx(ctx context.Context, fn func(tx *TxWrap) error) error { + return txwrap.DBGWithTx(ctx, dbWrap, fn) +} + func NumSessions(ctx context.Context) (int, error) { var numSessions int txErr := WithTx(ctx, func(tx *TxWrap) error { @@ -129,7 +161,7 @@ func UpsertRemote(ctx context.Context, r *RemoteType) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT remoteid FROM remote WHERE remoteid = ?` if tx.Exists(query, r.RemoteId) { - tx.ExecWrap(`DELETE FROM remote WHERE remoteid = ?`, r.RemoteId) + tx.Exec(`DELETE FROM remote WHERE remoteid = ?`, r.RemoteId) } query = `SELECT remoteid FROM remote WHERE remotecanonicalname = ?` if tx.Exists(query, r.RemoteCanonicalName) { @@ -145,7 +177,7 @@ func UpsertRemote(ctx context.Context, r *RemoteType) error { query = `INSERT INTO remote ( remoteid, physicalid, remotetype, remotealias, remotecanonicalname, remotesudo, remoteuser, remotehost, connectmode, autoinstall, sshopts, remoteopts, lastconnectts, archived, remoteidx, local) VALUES (:remoteid,:physicalid,:remotetype,:remotealias,:remotecanonicalname,:remotesudo,:remoteuser,:remotehost,:connectmode,:autoinstall,:sshopts,:remoteopts,:lastconnectts,:archived,:remoteidx,:local)` - tx.NamedExecWrap(query, r.ToMap()) + tx.NamedExec(query, r.ToMap()) return nil }) return txErr @@ -159,7 +191,7 @@ func InsertHistoryItem(ctx context.Context, hitem *HistoryItemType) error { query := `INSERT INTO history ( historyid, ts, userid, sessionid, screenid, windowid, lineid, cmdid, haderror, cmdstr, remoteownerid, remoteid, remotename, ismetacmd, incognito) VALUES (:historyid,:ts,:userid,:sessionid,:screenid,:windowid,:lineid,:cmdid,:haderror,:cmdstr,:remoteownerid,:remoteid,:remotename,:ismetacmd,:incognito)` - tx.NamedExecWrap(query, hitem.ToMap()) + tx.NamedExec(query, hitem.ToMap()) return nil }) return txErr @@ -169,7 +201,7 @@ func IsIncognitoScreen(ctx context.Context, sessionId string, screenId string) ( var rtn bool txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT incognito FROM screen WHERE sessionid = ? AND screenid = ?` - tx.GetWrap(&rtn, query, sessionId, screenId) + tx.Get(&rtn, query, sessionId, screenId) return nil }) return rtn, txErr @@ -238,7 +270,7 @@ func GetBareSessions(ctx context.Context) ([]*SessionType, error) { var rtn []*SessionType err := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT * FROM session ORDER BY archived, sessionidx, archivedts` - tx.SelectWrap(&rtn, query) + tx.Select(&rtn, query) return nil }) if err != nil { @@ -268,7 +300,7 @@ func GetBareSessionById(ctx context.Context, sessionId string) (*SessionType, er var rtn SessionType txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT * FROM session WHERE sessionid = ?` - tx.GetWrap(&rtn, query, sessionId) + tx.Get(&rtn, query, sessionId) return nil }) if txErr != nil { @@ -285,7 +317,7 @@ func GetAllSessions(ctx context.Context) (*ModelUpdate, error) { var activeSessionId string txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT * FROM session ORDER BY archived, sessionidx, archivedts` - tx.SelectWrap(&rtn, query) + tx.Select(&rtn, query) sessionMap := make(map[string]*SessionType) for _, session := range rtn { sessionMap[session.SessionId] = session @@ -293,7 +325,7 @@ func GetAllSessions(ctx context.Context) (*ModelUpdate, error) { } var screens []*ScreenType query = `SELECT * FROM screen ORDER BY archived, screenidx, archivedts` - tx.SelectWrap(&screens, query) + tx.Select(&screens, query) screenMap := make(map[string][]*ScreenType) for _, screen := range screens { screenArr := screenMap[screen.SessionId] @@ -305,7 +337,7 @@ func GetAllSessions(ctx context.Context) (*ModelUpdate, error) { } var sws []*ScreenWindowType query = `SELECT * FROM screen_window` - tx.SelectWrap(&sws, query) + tx.Select(&sws, query) screenIdMap := make(map[string]*ScreenType) for _, screen := range screens { screenIdMap[screen.SessionId+screen.ScreenId] = screen @@ -346,7 +378,7 @@ func GetWindowById(ctx context.Context, sessionId string, windowId string) (*Win } rtnWindow = WindowFromMap(m) query = `SELECT * FROM line WHERE sessionid = ? AND windowid = ? ORDER BY linenum` - tx.SelectWrap(&rtnWindow.Lines, query, sessionId, windowId) + tx.Select(&rtnWindow.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 { @@ -362,7 +394,7 @@ func GetBareSessionScreens(ctx context.Context, sessionId string) ([]*ScreenType var rtn []*ScreenType txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT * FROM screen WHERE sessionid = ? ORDER BY archived, screenidx, archivedts` - tx.SelectWrap(&rtn, query, sessionId) + tx.Select(&rtn, query, sessionId) return nil }) return rtn, txErr @@ -413,14 +445,14 @@ func InsertSessionWithName(ctx context.Context, sessionName string, activate boo maxSessionIdx := tx.GetInt(`SELECT COALESCE(max(sessionidx), 0) FROM session`) query := `INSERT INTO session (sessionid, name, activescreenid, sessionidx, notifynum, archived, archivedts, ownerid, sharemode, accesskey) VALUES (?, ?, '', ?, ?, 0, 0, '', 'local', '')` - tx.ExecWrap(query, newSessionId, sessionName, maxSessionIdx+1, 0) + tx.Exec(query, newSessionId, sessionName, maxSessionIdx+1, 0) _, err := InsertScreen(tx.Context(), newSessionId, "", true) if err != nil { return err } if activate { query = `UPDATE client SET activesessionid = ?` - tx.ExecWrap(query, newSessionId) + tx.Exec(query, newSessionId) } return nil }) @@ -447,7 +479,7 @@ func SetActiveSessionId(ctx context.Context, sessionId string) error { return fmt.Errorf("cannot switch to session, not found") } query = `UPDATE client SET activesessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) return nil }) return txErr @@ -466,7 +498,7 @@ func GetActiveSessionId(ctx context.Context) (string, error) { func SetWinSize(ctx context.Context, winSize ClientWinSizeType) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE client SET winsize = ?` - tx.ExecWrap(query, quickJson(winSize)) + tx.Exec(query, quickJson(winSize)) return nil }) return txErr @@ -527,13 +559,13 @@ func InsertScreen(ctx context.Context, sessionId string, origScreenName string, } newScreenId = scbase.GenPromptUUID() query = `INSERT INTO screen (sessionid, screenid, name, activewindowid, screenidx, screenopts, ownerid, sharemode, incognito, archived, archivedts) VALUES (?, ?, ?, ?, ?, ?, '', 'local', 0, 0, 0)` - tx.ExecWrap(query, sessionId, newScreenId, screenName, newWindowId, maxScreenIdx+1, ScreenOptsType{}) + tx.Exec(query, sessionId, newScreenId, screenName, newWindowId, maxScreenIdx+1, ScreenOptsType{}) layout := LayoutType{Type: LayoutFull} query = `INSERT INTO screen_window (sessionid, screenid, windowid, name, layout, selectedline, anchor, focustype) VALUES (?, ?, ?, ?, ?, ?, ?, ?)` - tx.ExecWrap(query, sessionId, newScreenId, newWindowId, DefaultScreenWindowName, layout, 0, SWAnchorType{}, "input") + tx.Exec(query, sessionId, newScreenId, newWindowId, DefaultScreenWindowName, layout, 0, SWAnchorType{}, "input") if activate { query = `UPDATE session SET activescreenid = ? WHERE sessionid = ?` - tx.ExecWrap(query, newScreenId, sessionId) + tx.Exec(query, newScreenId, sessionId) } return nil }) @@ -557,13 +589,13 @@ func GetScreenById(ctx context.Context, sessionId string, screenId string) (*Scr txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT * FROM screen WHERE sessionid = ? AND screenid = ?` var screen ScreenType - found := tx.GetWrap(&screen, query, sessionId, screenId) + found := tx.Get(&screen, query, sessionId, screenId) if !found { return nil } rtnScreen = &screen query = `SELECT * FROM screen_window WHERE sessionid = ? AND screenid = ?` - tx.SelectWrap(&screen.Windows, query, sessionId, screenId) + tx.Select(&screen.Windows, query, sessionId, screenId) screen.Full = true return nil }) @@ -586,7 +618,7 @@ func txCreateWindow(tx *TxWrap, sessionId string, curRemote RemotePtrType) strin wmap := w.ToMap() query := `INSERT INTO window ( sessionid, windowid, curremoteownerid, curremoteid, curremotename, nextlinenum, winopts, ownerid, sharemode, shareopts) VALUES (:sessionid,:windowid,:curremoteownerid,:curremoteid,:curremotename,:nextlinenum,:winopts,:ownerid,:sharemode,:shareopts)` - tx.NamedExecWrap(query, wmap) + tx.NamedExec(query, wmap) return w.WindowId } @@ -625,7 +657,7 @@ func GetLineCmdByLineId(ctx context.Context, sessionId string, windowId string, } var lineVal LineType query = `SELECT * FROM line WHERE sessionid = ? AND windowid = ? AND lineid = ?` - found := tx.GetWrap(&lineVal, query, sessionId, windowId, lineId) + found := tx.Get(&lineVal, query, sessionId, windowId, lineId) if !found { return nil } @@ -653,7 +685,7 @@ func GetLineCmdByCmdId(ctx context.Context, sessionId string, windowId string, c } var lineVal LineType query = `SELECT * FROM line WHERE sessionid = ? AND windowid = ? AND cmdid = ?` - found := tx.GetWrap(&lineVal, query, sessionId, windowId, cmdId) + found := tx.Get(&lineVal, query, sessionId, windowId, cmdId) if !found { return nil } @@ -689,9 +721,9 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { line.LineNum = int64(nextLineNum) query = `INSERT INTO line ( sessionid, windowid, userid, lineid, ts, linenum, linenumtemp, linelocal, linetype, text, cmdid, renderer, ephemeral, contentheight, star, archived) VALUES (:sessionid,:windowid,:userid,:lineid,:ts,:linenum,:linenumtemp,:linelocal,:linetype,:text,:cmdid,:renderer,:ephemeral,:contentheight,:star,:archived)` - tx.NamedExecWrap(query, line) + tx.NamedExec(query, line) query = `UPDATE window SET nextlinenum = ? WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, nextLineNum+1, line.SessionId, line.WindowId) + tx.Exec(query, nextLineNum+1, line.SessionId, line.WindowId) if cmd != nil { cmd.OrigTermOpts = cmd.TermOpts cmdMap := cmd.ToMap() @@ -699,7 +731,7 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { INSERT INTO cmd ( sessionid, cmdid, remoteownerid, remoteid, remotename, cmdstr, festate, statebasehash, statediffhasharr, termopts, origtermopts, status, startpk, doneinfo, rtnstate, runout, rtnbasehash, rtndiffhasharr) VALUES (:sessionid,:cmdid,:remoteownerid,:remoteid,:remotename,:cmdstr,:festate,:statebasehash,:statediffhasharr,:termopts,:origtermopts,:status,:startpk,:doneinfo,:rtnstate,:runout,:rtnbasehash,:rtndiffhasharr) ` - tx.NamedExecWrap(query, cmdMap) + tx.NamedExec(query, cmdMap) } return nil }) @@ -741,7 +773,7 @@ func UpdateCmdDoneInfo(ctx context.Context, ck base.CommandKey, doneInfo *CmdDon var rtnCmd *CmdType txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE cmd SET status = ?, doneinfo = ? WHERE sessionid = ? AND cmdid = ?` - tx.ExecWrap(query, CmdStatusDone, quickJson(doneInfo), ck.GetSessionId(), ck.GetCmdId()) + tx.Exec(query, CmdStatusDone, quickJson(doneInfo), ck.GetSessionId(), ck.GetCmdId()) var err error rtnCmd, err = GetCmdById(tx.Context(), ck.GetSessionId(), ck.GetCmdId()) if err != nil { @@ -764,7 +796,7 @@ func UpdateCmdRtnState(ctx context.Context, ck base.CommandKey, statePtr ShellSt } txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE cmd SET rtnbasehash = ?, rtndiffhasharr = ? WHERE sessionid = ? AND cmdid = ?` - tx.ExecWrap(query, statePtr.BaseHash, quickJsonArr(statePtr.DiffHashArr), ck.GetSessionId(), ck.GetCmdId()) + tx.Exec(query, statePtr.BaseHash, quickJsonArr(statePtr.DiffHashArr), ck.GetSessionId(), ck.GetCmdId()) return nil }) if txErr != nil { @@ -779,7 +811,7 @@ func AppendCmdErrorPk(ctx context.Context, errPk *packet.CmdErrorPacketType) err } return WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE cmd SET runout = json_insert(runout, '$[#]', ?) WHERE sessionid = ? AND cmdid = ?` - tx.ExecWrap(query, quickJson(errPk), errPk.CK.GetSessionId(), errPk.CK.GetCmdId()) + tx.Exec(query, quickJson(errPk), errPk.CK.GetSessionId(), errPk.CK.GetCmdId()) return nil }) } @@ -787,7 +819,7 @@ func AppendCmdErrorPk(ctx context.Context, errPk *packet.CmdErrorPacketType) err func ReInitFocus(ctx context.Context) error { return WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE screen_window SET focustype = 'input'` - tx.ExecWrap(query) + tx.Exec(query) return nil }) } @@ -795,7 +827,7 @@ func ReInitFocus(ctx context.Context) error { func HangupAllRunningCmds(ctx context.Context) error { return WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE cmd SET status = ? WHERE status = ?` - tx.ExecWrap(query, CmdStatusHangup, CmdStatusRunning) + tx.Exec(query, CmdStatusHangup, CmdStatusRunning) return nil }) } @@ -803,7 +835,7 @@ func HangupAllRunningCmds(ctx context.Context) error { func HangupRunningCmdsByRemoteId(ctx context.Context, remoteId string) error { return WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE cmd SET status = ? WHERE status = ? AND remoteid = ?` - tx.ExecWrap(query, CmdStatusHangup, CmdStatusRunning, remoteId) + tx.Exec(query, CmdStatusHangup, CmdStatusRunning, remoteId) return nil }) } @@ -811,7 +843,7 @@ func HangupRunningCmdsByRemoteId(ctx context.Context, remoteId string) error { func HangupCmd(ctx context.Context, ck base.CommandKey) error { return WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE cmd SET status = ? WHERE sessionid = ? AND cmdid = ?` - tx.ExecWrap(query, CmdStatusHangup, ck.GetSessionId(), ck.GetCmdId()) + tx.Exec(query, CmdStatusHangup, ck.GetSessionId(), ck.GetCmdId()) return nil }) } @@ -847,7 +879,7 @@ func SwitchScreenById(ctx context.Context, sessionId string, screenId string) (U return fmt.Errorf("cannot switch to screen, screen=%s does not exist in session=%s", screenId, sessionId) } query = `UPDATE session SET activescreenid = ? WHERE sessionid = ?` - tx.ExecWrap(query, screenId, sessionId) + tx.Exec(query, screenId, sessionId) return nil }) if txErr != nil { @@ -866,7 +898,7 @@ func cleanSessionCmds(ctx context.Context, sessionId string) error { query := `SELECT cmdid FROM cmd WHERE sessionid = ? AND cmdid NOT IN (SELECT cmdid FROM line WHERE sessionid = ?)` removedCmds = tx.SelectStrings(query, sessionId, sessionId) query = `DELETE FROM cmd WHERE sessionid = ? AND cmdid NOT IN (SELECT cmdid FROM line WHERE sessionid = ?)` - tx.ExecWrap(query, sessionId, sessionId) + tx.Exec(query, sessionId, sessionId) return nil }) if txErr != nil { @@ -888,11 +920,11 @@ func CleanWindows(sessionId string) { } for _, windowId := range removedWindowIds { query = `DELETE FROM window WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) query = `DELETE FROM history WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) query = `DELETE FROM line WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) } return cleanSessionCmds(tx.Context(), sessionId) }) @@ -918,12 +950,12 @@ func ArchiveScreen(ctx context.Context, sessionId string, screenId string) (Upda return fmt.Errorf("cannot archive the last screen in a session") } query = `UPDATE screen SET archived = 1, archivedts = ?, screenidx = 0 WHERE sessionid = ? AND screenid = ?` - tx.ExecWrap(query, time.Now().UnixMilli(), sessionId, screenId) + tx.Exec(query, time.Now().UnixMilli(), 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 archived ORDER BY screenidx`, sessionId) nextId := getNextId(screenIds, screenId) - tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId) + tx.Exec(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId) } return nil }) @@ -950,7 +982,7 @@ func UnArchiveScreen(ctx context.Context, sessionId string, screenId string) err } maxScreenIdx := tx.GetInt(`SELECT COALESCE(max(screenidx), 0) FROM screen WHERE sessionid = ? AND NOT archived`, sessionId) query = `UPDATE screen SET archived = 0, screenidx = ? WHERE sessionid = ? AND screenid = ?` - tx.ExecWrap(query, maxScreenIdx+1, sessionId, screenId) + tx.Exec(query, maxScreenIdx+1, sessionId, screenId) return nil }) return txErr @@ -971,12 +1003,12 @@ func DeleteScreen(ctx context.Context, sessionId string, screenId string) (Updat if isActive { screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT archived ORDER BY screenidx`, sessionId) nextId := getNextId(screenIds, screenId) - tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId) + tx.Exec(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId) } query = `DELETE FROM screen_window WHERE sessionid = ? AND screenid = ?` - tx.ExecWrap(query, sessionId, screenId) + tx.Exec(query, sessionId, screenId) query = `DELETE FROM screen WHERE sessionid = ? AND screenid = ?` - tx.ExecWrap(query, sessionId, screenId) + tx.Exec(query, sessionId, screenId) return nil }) if txErr != nil { @@ -1114,7 +1146,7 @@ func UpdateRemoteState(ctx context.Context, sessionId string, windowId string, r } query = `INSERT INTO remote_instance ( riid, name, sessionid, windowid, remoteownerid, remoteid, festate, statebasehash, statediffhasharr) VALUES (:riid,:name,:sessionid,:windowid,:remoteownerid,:remoteid,:festate,:statebasehash,:statediffhasharr)` - tx.NamedExecWrap(query, ri.ToMap()) + tx.NamedExec(query, ri.ToMap()) return nil } else { query = `UPDATE remote_instance SET festate = ?, statebasehash = ?, statediffhasharr = ? WHERE riid = ?` @@ -1123,7 +1155,7 @@ func UpdateRemoteState(ctx context.Context, sessionId string, windowId string, r if err != nil { return err } - tx.ExecWrap(query, quickJson(ri.FeState), ri.StateBaseHash, quickJsonArr(ri.StateDiffHashArr), ri.RIId) + tx.Exec(query, quickJson(ri.FeState), ri.StateBaseHash, quickJsonArr(ri.StateDiffHashArr), ri.RIId) return nil } }) @@ -1137,7 +1169,7 @@ func UpdateCurRemote(ctx context.Context, sessionId string, windowId string, rem return fmt.Errorf("cannot update curremote: no window found") } query = `UPDATE window SET curremoteownerid = ?, curremoteid = ?, curremotename = ? WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name, sessionId, windowId) + tx.Exec(query, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name, sessionId, windowId) return nil }) return txErr @@ -1174,7 +1206,7 @@ func ReIndexSessions(ctx context.Context, sessionId string, newIndex int) error } query = `UPDATE session SET sessionid = ? WHERE sessionid = ?` for idx, id := range ids { - tx.ExecWrap(query, id, idx+1) + tx.Exec(query, id, idx+1) } return nil }) @@ -1200,7 +1232,7 @@ func SetSessionName(ctx context.Context, sessionId string, name string) error { } } query = `UPDATE session SET name = ? WHERE sessionid = ?` - tx.ExecWrap(query, name, sessionId) + tx.Exec(query, name, sessionId) return nil }) return txErr @@ -1213,7 +1245,7 @@ func SetScreenName(ctx context.Context, sessionId string, screenId string, name return fmt.Errorf("screen does not exist") } query = `UPDATE screen SET name = ? WHERE sessionid = ? AND screenid = ?` - tx.ExecWrap(query, name, sessionId, screenId) + tx.Exec(query, name, sessionId, screenId) return nil }) return txErr @@ -1229,7 +1261,7 @@ func SetScreenOpts(ctx context.Context, sessionId string, screenId string, opts return fmt.Errorf("screen does not exist") } query = `UPDATE screen SET screenopts = ? WHERE sessionid = ? AND screenid = ?` - tx.ExecWrap(query, opts, sessionId, screenId) + tx.Exec(query, opts, sessionId, screenId) return nil }) return txErr @@ -1242,7 +1274,7 @@ func ArchiveWindowLines(ctx context.Context, sessionId string, windowId string) return fmt.Errorf("window does not exist") } query = `UPDATE line SET archived = 1 WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) return nil }) if txErr != nil { @@ -1265,11 +1297,11 @@ func PurgeWindowLines(ctx context.Context, sessionId string, windowId string) (* query = `SELECT lineid FROM line WHERE sessionid = ? AND windowid = ?` lineIds = tx.SelectStrings(query, sessionId, windowId) query = `DELETE FROM line WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) query = `DELETE FROM history WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) query = `UPDATE window SET nextlinenum = 1 WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) return nil }) if txErr != nil { @@ -1311,7 +1343,7 @@ func GetRunningWindowCmds(ctx context.Context, sessionId string, windowId string func UpdateCmdTermOpts(ctx context.Context, sessionId string, cmdId string, termOpts TermOpts) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE cmd SET termopts = ? WHERE sessionid = ? AND cmdid = ?` - tx.ExecWrap(query, termOpts, sessionId, cmdId) + tx.Exec(query, termOpts, sessionId, cmdId) return nil }) return txErr @@ -1332,7 +1364,7 @@ func WindowReset(ctx context.Context, sessionId string, windowId string) ([]*Rem delRis = append(delRis, ri) } query = `DELETE FROM remote_instance WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, sessionId, windowId) + tx.Exec(query, sessionId, windowId) return nil }) return delRis, txErr @@ -1346,19 +1378,19 @@ func DeleteSession(ctx context.Context, sessionId string) (UpdatePacket, error) return fmt.Errorf("session does not exist") } query = `DELETE FROM session WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) query = `DELETE FROM screen WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) query = `DELETE FROM screen_window WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) query = `DELETE FROM window WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) query = `DELETE FROM history WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) query = `DELETE FROM line WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) query = `DELETE FROM cmd WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) newActiveSessionId, _ = fixActiveSessionId(tx.Context()) return nil }) @@ -1392,7 +1424,7 @@ func fixActiveSessionId(ctx context.Context) (string, error) { if err != nil { return err } - tx.ExecWrap("UPDATE client SET activesessionid = ?", newActiveSessionId) + tx.Exec("UPDATE client SET activesessionid = ?", newActiveSessionId) return nil }) if txErr != nil { @@ -1417,7 +1449,7 @@ func ArchiveSession(ctx context.Context, sessionId string) (*ModelUpdate, error) return nil } query = `UPDATE session SET archived = 1, archivedts = ? WHERE sessionid = ?` - tx.ExecWrap(query, time.Now().UnixMilli(), sessionId) + tx.Exec(query, time.Now().UnixMilli(), sessionId) newActiveSessionId, _ = fixActiveSessionId(tx.Context()) return nil }) @@ -1450,10 +1482,10 @@ func UnArchiveSession(ctx context.Context, sessionId string, activate bool) (*Mo return nil } query = `UPDATE session SET archived = 0, archivedts = 0 WHERE sessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) if activate { query = `UPDATE client SET activesessionid = ?` - tx.ExecWrap(query, sessionId) + tx.Exec(query, sessionId) } return nil }) @@ -1524,27 +1556,27 @@ func UpdateRemote(ctx context.Context, remoteId string, editMap map[string]inter return fmt.Errorf("remote has duplicate alias, cannot update") } query = `UPDATE remote SET remotealias = ? WHERE remoteid = ?` - tx.ExecWrap(query, alias, remoteId) + tx.Exec(query, alias, remoteId) } if mode, found := editMap[RemoteField_ConnectMode]; found { query = `UPDATE remote SET connectmode = ? WHERE remoteid = ?` - tx.ExecWrap(query, mode, remoteId) + tx.Exec(query, mode, remoteId) } if autoInstall, found := editMap[RemoteField_AutoInstall]; found { query = `UPDATE remote SET autoinstall = ? WHERE remoteid = ?` - tx.ExecWrap(query, autoInstall, remoteId) + tx.Exec(query, autoInstall, remoteId) } if sshKey, found := editMap[RemoteField_SSHKey]; found { query = `UPDATE remote SET sshopts = json_set(sshopts, '$.sshidentity', ?) WHERE remoteid = ?` - tx.ExecWrap(query, sshKey, remoteId) + tx.Exec(query, sshKey, remoteId) } if sshPassword, found := editMap[RemoteField_SSHPassword]; found { query = `UPDATE remote SET sshopts = json_set(sshopts, '$.sshpassword', ?) WHERE remoteid = ?` - tx.ExecWrap(query, sshPassword, remoteId) + tx.Exec(query, sshPassword, remoteId) } if color, found := editMap[RemoteField_Color]; found { query = `UPDATE remote SET remoteopts = json_set(remoteopts, '$.color', ?) WHERE remoteid = ?` - tx.ExecWrap(query, color, remoteId) + tx.Exec(query, color, remoteId) } var err error rtn, err = GetRemoteById(tx.Context(), remoteId) @@ -1575,23 +1607,23 @@ func UpdateScreenWindow(ctx context.Context, sessionId string, screenId string, } if anchorLine, found := editMap[SWField_AnchorLine]; found { query = `UPDATE screen_window SET anchor = json_set(anchor, '$.anchorline', ?) WHERE sessionid = ? AND screenid = ? AND windowid = ?` - tx.ExecWrap(query, anchorLine, sessionId, screenId, windowId) + tx.Exec(query, anchorLine, sessionId, screenId, windowId) } if anchorOffset, found := editMap[SWField_AnchorOffset]; found { query = `UPDATE screen_window SET anchor = json_set(anchor, '$.anchoroffset', ?) WHERE sessionid = ? AND screenid = ? AND windowid = ?` - tx.ExecWrap(query, anchorOffset, sessionId, screenId, windowId) + tx.Exec(query, anchorOffset, sessionId, screenId, windowId) } if sline, found := editMap[SWField_SelectedLine]; found { query = `UPDATE screen_window SET selectedline = ? WHERE sessionid = ? AND screenid = ? AND windowid = ?` - tx.ExecWrap(query, sline, sessionId, screenId, windowId) + tx.Exec(query, sline, sessionId, screenId, windowId) } if focusType, found := editMap[SWField_Focus]; found { query = `UPDATE screen_window SET focustype = ? WHERE sessionid = ? AND screenid = ? AND windowid = ?` - tx.ExecWrap(query, focusType, sessionId, screenId, windowId) + tx.Exec(query, focusType, sessionId, screenId, windowId) } var sw ScreenWindowType query = `SELECT * FROM screen_window WHERE sessionid = ? AND screenid = ? AND windowid = ?` - found := tx.GetWrap(&sw, query, sessionId, screenId, windowId) + found := tx.Get(&sw, query, sessionId, screenId, windowId) if found { rtn = &sw } @@ -1608,7 +1640,7 @@ func GetScreenWindowByIds(ctx context.Context, sessionId string, screenId string txErr := WithTx(ctx, func(tx *TxWrap) error { var sw ScreenWindowType query := `SELECT * FROM screen_window WHERE sessionid = ? AND screenid = ? AND windowid = ?` - found := tx.GetWrap(&sw, query, sessionId, screenId, windowId) + found := tx.Get(&sw, query, sessionId, screenId, windowId) if found { rtn = &sw } @@ -1624,7 +1656,7 @@ func GetLineResolveItems(ctx context.Context, sessionId string, windowId string) var rtn []ResolveItem txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT lineid as id, linenum as num FROM line WHERE sessionid = ? AND windowid = ? ORDER BY linenum` - tx.SelectWrap(&rtn, query, sessionId, windowId) + tx.Select(&rtn, query, sessionId, windowId) return nil }) if txErr != nil { @@ -1648,7 +1680,7 @@ func UpdateSWsWithCmdFg(ctx context.Context, sessionId string, cmdId string) ([] AND l.cmdid = ? )` var swKeys []SWKey - tx.SelectWrap(&swKeys, query, sessionId, cmdId) + tx.Select(&swKeys, query, sessionId, cmdId) if len(swKeys) == 0 { return nil } @@ -1681,7 +1713,7 @@ func StoreStateBase(ctx context.Context, state *packet.ShellState) error { return nil } query = `INSERT INTO state_base (basehash, ts, version, data) VALUES (:basehash,:ts,:version,:data)` - tx.NamedExecWrap(query, stateBase) + tx.NamedExec(query, stateBase) return nil }) if txErr != nil { @@ -1712,7 +1744,7 @@ func StoreStateDiff(ctx context.Context, diff *packet.ShellStateDiff) error { return nil } query = `INSERT INTO state_diff (diffhash, ts, basehash, diffhasharr, data) VALUES (:diffhash,:ts,:basehash,:diffhasharr,:data)` - tx.NamedExecWrap(query, stateDiff.ToMap()) + tx.NamedExec(query, stateDiff.ToMap()) return nil }) if txErr != nil { @@ -1730,7 +1762,7 @@ func GetFullState(ctx context.Context, ssPtr ShellStatePtr) (*packet.ShellState, txErr := WithTx(ctx, func(tx *TxWrap) error { var stateBase StateBase query := `SELECT * FROM state_base WHERE basehash = ?` - found := tx.GetWrap(&stateBase, query, ssPtr.BaseHash) + found := tx.Get(&stateBase, query, ssPtr.BaseHash) if !found { return fmt.Errorf("ShellState %s not found", ssPtr.BaseHash) } @@ -1771,7 +1803,7 @@ func GetFullState(ctx context.Context, ssPtr ShellStatePtr) (*packet.ShellState, func UpdateLineStar(ctx context.Context, lineId string, starVal int) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE line SET star = ? WHERE lineid = ?` - tx.ExecWrap(query, starVal, lineId) + tx.Exec(query, starVal, lineId) return nil }) if txErr != nil { @@ -1783,7 +1815,7 @@ func UpdateLineStar(ctx context.Context, lineId string, starVal int) error { func UpdateLineHeight(ctx context.Context, lineId string, heightVal int) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE line SET contentheight = ? WHERE lineid = ?` - tx.ExecWrap(query, heightVal, lineId) + tx.Exec(query, heightVal, lineId) return nil }) if txErr != nil { @@ -1798,7 +1830,7 @@ func GetLineById(ctx context.Context, lineId string) (*LineType, error) { txErr := WithTx(ctx, func(tx *TxWrap) error { var line LineType query := `SELECT * FROM line WHERE lineid = ?` - found := tx.GetWrap(&line, query, lineId) + found := tx.Get(&line, query, lineId) if found { rtn = &line } @@ -1813,7 +1845,7 @@ func GetLineById(ctx context.Context, lineId string) (*LineType, error) { func SetLineArchivedById(ctx context.Context, lineId string, archived bool) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE line SET archived = ? WHERE lineid = ?` - tx.ExecWrap(query, archived, lineId) + tx.Exec(query, archived, lineId) return nil }) return txErr @@ -1822,7 +1854,7 @@ func SetLineArchivedById(ctx context.Context, lineId string, archived bool) erro func purgeCmdById(ctx context.Context, sessionId string, cmdId string) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `DELETE FROM cmd WHERE sessionid = ? AND cmdid = ?` - tx.ExecWrap(query, sessionId, cmdId) + tx.Exec(query, sessionId, cmdId) return DeletePtyOutFile(tx.Context(), sessionId, cmdId) }) return txErr @@ -1833,9 +1865,9 @@ func PurgeLineById(ctx context.Context, sessionId string, lineId string) error { query := `SELECT cmdid FROM line WHERE sessionid = ? AND lineid = ?` cmdId := tx.GetString(query, sessionId, lineId) query = `DELETE FROM line WHERE sessionid = ? AND lineid = ?` - tx.ExecWrap(query, sessionId, lineId) + tx.Exec(query, sessionId, lineId) query = `DELETE FROM history WHERE sessionid = ? AND lineid = ?` - tx.ExecWrap(query, sessionId, lineId) + tx.Exec(query, sessionId, lineId) if cmdId != "" { query = `SELECT count(*) FROM line WHERE sessionid = ? AND cmdid = ?` cmdRefCount := tx.GetInt(query, sessionId, cmdId) @@ -1882,7 +1914,7 @@ func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error { txErr := WithTx(ctx, func(tx *TxWrap) error { var tdata TelemetryData query := `SELECT tdata FROM activity WHERE day = ?` - found := tx.GetWrap(&tdata, query, dayStr) + found := tx.Get(&tdata, query, dayStr) if !found { query = `INSERT INTO activity (day, uploaded, tdata, tzname, tzoffset, clientversion, clientarch) VALUES (?, 0, ?, ?, ?, ?, ?)` @@ -1890,7 +1922,7 @@ func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error { if len(tzName) > MaxTzNameLen { tzName = tzName[0:MaxTzNameLen] } - tx.ExecWrap(query, dayStr, tdata, tzName, tzOffset, scbase.PromptVersion, scbase.ClientArch()) + tx.Exec(query, dayStr, tdata, tzName, tzOffset, scbase.PromptVersion, scbase.ClientArch()) } tdata.NumCommands += update.NumCommands tdata.FgMinutes += update.FgMinutes @@ -1900,7 +1932,7 @@ func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error { SET tdata = ?, clientversion = ? WHERE day = ?` - tx.ExecWrap(query, tdata, scbase.PromptVersion, dayStr) + tx.Exec(query, tdata, scbase.PromptVersion, dayStr) return nil }) if txErr != nil { @@ -1913,7 +1945,7 @@ func GetNonUploadedActivity(ctx context.Context) ([]*ActivityType, error) { var rtn []*ActivityType txErr := WithTx(ctx, func(tx *TxWrap) error { query := `SELECT * FROM activity WHERE uploaded = 0 ORDER BY day DESC LIMIT 30` - tx.SelectWrap(&rtn, query) + tx.Select(&rtn, query) return nil }) if txErr != nil { @@ -1931,7 +1963,7 @@ func MarkActivityAsUploaded(ctx context.Context, activityArr []*ActivityType) er if activity.Day == dayStr { continue } - tx.ExecWrap(query, activity.Day) + tx.Exec(query, activity.Day) } return nil }) diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index 95ccafbba..5683b1683 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -19,6 +19,7 @@ import ( "github.com/google/uuid" "github.com/jmoiron/sqlx" + "github.com/sawka/txwrap" "github.com/scripthaus-dev/mshell/pkg/base" "github.com/scripthaus-dev/mshell/pkg/packet" "github.com/scripthaus-dev/sh2-server/pkg/scbase" @@ -86,7 +87,7 @@ func IsValidConnectMode(mode string) bool { } func GetDB(ctx context.Context) (*sqlx.DB, error) { - if IsTxWrapContext(ctx) { + if txwrap.IsTxWrapContext(ctx) { return nil, fmt.Errorf("cannot call GetDB from within a running transaction") } globalDBLock.Lock() @@ -975,7 +976,7 @@ func createClientData(tx *TxWrap) error { } query := `INSERT INTO client ( clientid, userid, activesessionid, userpublickeybytes, userprivatekeybytes, winsize) VALUES (:clientid,:userid,:activesessionid,:userpublickeybytes,:userprivatekeybytes,:winsize)` - tx.NamedExecWrap(query, c.ToMap()) + tx.NamedExec(query, c.ToMap()) log.Printf("create new clientid[%s] userid[%s] with public/private keypair\n", c.ClientId, c.UserId) return nil } @@ -1030,7 +1031,7 @@ func EnsureClientData(ctx context.Context) (*ClientData, error) { func SetClientOpts(ctx context.Context, clientOpts ClientOptsType) error { txErr := WithTx(ctx, func(tx *TxWrap) error { query := `UPDATE client SET clientopts = ?` - tx.ExecWrap(query, quickJson(clientOpts)) + tx.Exec(query, quickJson(clientOpts)) return nil }) return txErr diff --git a/pkg/sstore/txwrap.go b/pkg/sstore/txwrap.go deleted file mode 100644 index 67761950b..000000000 --- a/pkg/sstore/txwrap.go +++ /dev/null @@ -1,189 +0,0 @@ -package sstore - -import ( - "context" - "database/sql" - "sync" - - "github.com/jmoiron/sqlx" -) - -type TxWrap struct { - Txx *sqlx.Tx - Err error - Ctx context.Context -} - -type txWrapKey struct{} - -// single-threaded access to DB -var globalNestingLock = &sync.Mutex{} - -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) { - var txWrap *TxWrap - ctxVal := ctx.Value(txWrapKey{}) - if ctxVal != nil { - txWrap = ctxVal.(*TxWrap) - if txWrap.Err != nil { - return txWrap.Err - } - } - if txWrap == nil { - globalNestingLock.Lock() - defer globalNestingLock.Unlock() - - 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() - } - }() - } - fnErr := fn(txWrap) - if txWrap.Err == nil && fnErr != nil { - txWrap.Err = fnErr - } - if txWrap.Err != nil { - return txWrap.Err - } - 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 - } - result, err := tx.Txx.NamedExec(query, arg) - if err != nil { - tx.Err = err - } - return result -} - -func (tx *TxWrap) ExecWrap(query string, args ...interface{}) sql.Result { - if tx.Err != nil { - return nil - } - result, err := tx.Txx.Exec(query, args...) - if err != nil { - tx.Err = err - } - return result -} - -func (tx *TxWrap) Exists(query string, args ...interface{}) bool { - var dest interface{} - return tx.GetWrap(&dest, query, args...) -} - -func (tx *TxWrap) GetString(query string, args ...interface{}) string { - var rtnStr string - tx.GetWrap(&rtnStr, query, args...) - 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...) - return rtnArr -} - -func (tx *TxWrap) GetInt(query string, args ...interface{}) int { - var rtnInt int - tx.GetWrap(&rtnInt, query, args...) - return rtnInt -} - -func (tx *TxWrap) GetWrap(dest interface{}, query string, args ...interface{}) bool { - if tx.Err != nil { - return false - } - err := tx.Txx.Get(dest, query, args...) - if err != nil && err == sql.ErrNoRows { - return false - } - if err != nil { - tx.Err = err - return false - } - return true -} - -func (tx *TxWrap) SelectWrap(dest interface{}, query string, args ...interface{}) { - if tx.Err != nil { - return - } - err := tx.Txx.Select(dest, query, args...) - if err != nil { - tx.Err = err - } - return -} - -func (tx *TxWrap) SelectMaps(query string, args ...interface{}) []map[string]interface{} { - if tx.Err != nil { - return nil - } - rows, err := tx.Txx.Queryx(query, args...) - if err != nil { - tx.Err = err - return nil - } - var rtn []map[string]interface{} - for rows.Next() { - m := make(map[string]interface{}) - err = rows.MapScan(m) - if err != nil { - tx.Err = err - return nil - } - rtn = append(rtn, m) - } - return rtn -} - -func (tx *TxWrap) GetMap(query string, args ...interface{}) map[string]interface{} { - if tx.Err != nil { - return nil - } - row := tx.Txx.QueryRowx(query, args...) - m := make(map[string]interface{}) - err := row.MapScan(m) - if err != nil { - if err == sql.ErrNoRows { - return nil - } - tx.Err = err - return nil - } - return m -}