mirror of
https://github.com/chaisql/chai.git
synced 2025-10-08 17:10:08 +08:00
102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
package query
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/genjidb/genji/internal/database"
|
|
"github.com/genjidb/genji/internal/errors"
|
|
"github.com/genjidb/genji/internal/query/statement"
|
|
)
|
|
|
|
// BeginStmt is a statement that creates a new transaction.
|
|
type BeginStmt struct {
|
|
Writable bool
|
|
}
|
|
|
|
// Prepare implements the Preparer interface.
|
|
func (stmt BeginStmt) Prepare(*statement.Context) (statement.Statement, error) {
|
|
return stmt, nil
|
|
}
|
|
|
|
func (stmt BeginStmt) alterQuery(ctx context.Context, db *database.Database, q *Query) error {
|
|
if q.tx != nil {
|
|
return errors.New("cannot begin a transaction within a transaction")
|
|
}
|
|
|
|
var err error
|
|
q.tx, err = db.BeginTx(ctx, &database.TxOptions{
|
|
ReadOnly: !stmt.Writable,
|
|
Attached: true,
|
|
})
|
|
q.autoCommit = false
|
|
return err
|
|
}
|
|
|
|
func (stmt BeginStmt) IsReadOnly() bool {
|
|
return !stmt.Writable
|
|
}
|
|
|
|
func (stmt BeginStmt) Run(ctx *statement.Context) (statement.Result, error) {
|
|
return statement.Result{}, errors.New("cannot begin a transaction within a transaction")
|
|
}
|
|
|
|
// RollbackStmt is a statement that rollbacks the current active transaction.
|
|
type RollbackStmt struct{}
|
|
|
|
// Prepare implements the Preparer interface.
|
|
func (stmt RollbackStmt) Prepare(*statement.Context) (statement.Statement, error) {
|
|
return stmt, nil
|
|
}
|
|
|
|
func (stmt RollbackStmt) alterQuery(ctx context.Context, db *database.Database, q *Query) error {
|
|
if q.tx == nil || q.autoCommit {
|
|
return errors.New("cannot rollback with no active transaction")
|
|
}
|
|
|
|
err := q.tx.Rollback()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
q.tx = nil
|
|
q.autoCommit = true
|
|
return nil
|
|
}
|
|
|
|
func (stmt RollbackStmt) IsReadOnly() bool {
|
|
return false
|
|
}
|
|
|
|
func (stmt RollbackStmt) Run(ctx *statement.Context) (statement.Result, error) {
|
|
return statement.Result{}, errors.New("cannot rollback with no active transaction")
|
|
}
|
|
|
|
// CommitStmt is a statement that commits the current active transaction.
|
|
type CommitStmt struct{}
|
|
|
|
// Prepare implements the Preparer interface.
|
|
func (stmt CommitStmt) Prepare(*statement.Context) (statement.Statement, error) {
|
|
return stmt, nil
|
|
}
|
|
|
|
func (stmt CommitStmt) alterQuery(ctx context.Context, db *database.Database, q *Query) error {
|
|
if q.tx == nil || q.autoCommit {
|
|
return errors.New("cannot commit with no active transaction")
|
|
}
|
|
|
|
err := q.tx.Commit()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
q.tx = nil
|
|
q.autoCommit = true
|
|
return nil
|
|
}
|
|
|
|
func (stmt CommitStmt) IsReadOnly() bool {
|
|
return false
|
|
}
|
|
|
|
func (stmt CommitStmt) Run(ctx *statement.Context) (statement.Result, error) {
|
|
return statement.Result{}, errors.New("cannot commit with no active transaction")
|
|
}
|