@@ -33,8 +33,8 @@ type SQLBackend interface {
3333}
3434
3535type Backend interface {
36- sqlbuilder.SQLBuilder
3736 db.Database
37+ sqlbuilder.SQLBuilder
3838
3939 SetTxOptions (sql.TxOptions )
4040 TxOptions () * sql.TxOptions
@@ -43,6 +43,8 @@ type Backend interface {
4343type Session interface {
4444 Backend
4545
46+ Conn () sqlbuilder.Database
47+
4648 Store (collectionName string ) Store
4749 ResolveStore (interface {}) Store
4850
@@ -53,13 +55,18 @@ type Session interface {
5355 Context () context.Context
5456
5557 SessionTx (context.Context , func (tx Session ) error ) error
58+ NewTx (context.Context ) (sqlbuilder.Tx , error )
59+ NewSessionTx (context.Context ) (Session , error )
60+
61+ TxCommit () error
62+ TxRollback () error
5663}
5764
5865type session struct {
5966 Backend
6067
61- stores map [string ]* store
62- storesLock sync.Mutex
68+ stores map [string ]* store
69+ mu sync.Mutex
6370}
6471
6572// Open connects to a database.
@@ -68,14 +75,20 @@ func Open(adapter string, url db.ConnectionURL) (Session, error) {
6875 if err != nil {
6976 return nil , err
7077 }
71- return New (conn ), nil
78+
79+ sess := New (conn )
80+ return sess , nil
7281}
7382
7483// New returns a new session.
7584func New (conn Backend ) Session {
7685 return & session {Backend : conn , stores : make (map [string ]* store )}
7786}
7887
88+ func (s * session ) Conn () sqlbuilder.Database {
89+ return s .Backend .(sqlbuilder.Database )
90+ }
91+
7992func (s * session ) WithContext (ctx context.Context ) Session {
8093 var backendCtx Backend
8194 switch t := s .Backend .(type ) {
@@ -122,6 +135,39 @@ func Bind(adapter string, backend SQLBackend) (Session, error) {
122135 return & session {Backend : conn , stores : make (map [string ]* store )}, nil
123136}
124137
138+ func (s * session ) NewTx (ctx context.Context ) (sqlbuilder.Tx , error ) {
139+ return s .Conn ().NewTx (ctx )
140+ }
141+
142+ func (s * session ) NewSessionTx (ctx context.Context ) (Session , error ) {
143+ tx , err := s .NewTx (ctx )
144+ if err != nil {
145+ return nil , err
146+ }
147+ return & session {
148+ Backend : tx ,
149+ stores : make (map [string ]* store ),
150+ }, nil
151+ }
152+
153+ func (s * session ) TxCommit () error {
154+ tx , ok := s .Backend .(sqlbuilder.Tx )
155+ if ! ok {
156+ return errors .Errorf ("bond: session is not a tx" )
157+ }
158+ defer tx .Close ()
159+ return tx .Commit ()
160+ }
161+
162+ func (s * session ) TxRollback () error {
163+ tx , ok := s .Backend .(sqlbuilder.Tx )
164+ if ! ok {
165+ return errors .Errorf ("bond: session is not a tx" )
166+ }
167+ defer tx .Close ()
168+ return tx .Rollback ()
169+ }
170+
125171func (s * session ) SessionTx (ctx context.Context , fn func (sess Session ) error ) error {
126172 txFn := func (sess sqlbuilder.Tx ) error {
127173 return fn (& session {
@@ -177,8 +223,8 @@ func (s *session) Store(collectionName string) Store {
177223 return & store {session : s }
178224 }
179225
180- s .storesLock .Lock ()
181- defer s .storesLock .Unlock ()
226+ s .mu .Lock ()
227+ defer s .mu .Unlock ()
182228
183229 if store , ok := s .stores [collectionName ]; ok {
184230 return store
0 commit comments