stardb/tx.go

157 lines
3.9 KiB
Go
Raw Permalink Normal View History

2026-03-07 19:27:44 +08:00
package stardb
import (
"context"
"database/sql"
"errors"
)
// StarTx represents a database transaction
type StarTx struct {
tx *sql.Tx
db *StarDB
}
// Query executes a query within the transaction
func (t *StarTx) Query(query string, args ...interface{}) (*StarRows, error) {
return t.query(nil, query, args...)
}
// QueryContext executes a query with context within the transaction
func (t *StarTx) QueryContext(ctx context.Context, query string, args ...interface{}) (*StarRows, error) {
return t.query(ctx, query, args...)
}
// query is the internal query implementation
func (t *StarTx) query(ctx context.Context, query string, args ...interface{}) (*StarRows, error) {
if err := t.db.Ping(); err != nil {
return nil, err
}
var rows *sql.Rows
var err error
if ctx == nil {
rows, err = t.tx.Query(query, args...)
} else {
rows, err = t.tx.QueryContext(ctx, query, args...)
}
if err != nil {
return nil, err
}
starRows := &StarRows{
rows: rows,
db: t.db,
}
if !t.db.ManualScan {
err = starRows.parse()
}
return starRows, err
}
// Exec executes a query within the transaction
func (t *StarTx) Exec(query string, args ...interface{}) (sql.Result, error) {
return t.exec(nil, query, args...)
}
// ExecContext executes a query with context within the transaction
func (t *StarTx) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
return t.exec(ctx, query, args...)
}
// exec is the internal exec implementation
func (t *StarTx) exec(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
if err := t.db.Ping(); err != nil {
return nil, err
}
if ctx == nil {
return t.tx.Exec(query, args...)
}
return t.tx.ExecContext(ctx, query, args...)
}
// Prepare creates a prepared statement within the transaction
func (t *StarTx) Prepare(query string) (*StarStmt, error) {
stmt, err := t.tx.Prepare(query)
if err != nil {
return nil, err
}
return &StarStmt{stmt: stmt, db: t.db}, nil
}
// PrepareContext creates a prepared statement with context
func (t *StarTx) PrepareContext(ctx context.Context, query string) (*StarStmt, error) {
stmt, err := t.tx.PrepareContext(ctx, query)
if err != nil {
return nil, err
}
return &StarStmt{stmt: stmt, db: t.db}, nil
}
// QueryStmt executes a prepared statement query within the transaction
func (t *StarTx) QueryStmt(query string, args ...interface{}) (*StarRows, error) {
if query == "" {
return nil, errors.New("query string cannot be empty")
}
stmt, err := t.Prepare(query)
if err != nil {
return nil, err
}
defer stmt.Close()
return stmt.Query(args...)
}
// QueryStmtContext executes a prepared statement query with context
func (t *StarTx) QueryStmtContext(ctx context.Context, query string, args ...interface{}) (*StarRows, error) {
if query == "" {
return nil, errors.New("query string cannot be empty")
}
stmt, err := t.PrepareContext(ctx, query)
if err != nil {
return nil, err
}
defer stmt.Close()
return stmt.QueryContext(ctx, args...)
}
// ExecStmt executes a prepared statement within the transaction
func (t *StarTx) ExecStmt(query string, args ...interface{}) (sql.Result, error) {
if query == "" {
return nil, errors.New("query string cannot be empty")
}
stmt, err := t.Prepare(query)
if err != nil {
return nil, err
}
defer stmt.Close()
return stmt.Exec(args...)
}
// ExecStmtContext executes a prepared statement with context
func (t *StarTx) ExecStmtContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
if query == "" {
return nil, errors.New("query string cannot be empty")
}
stmt, err := t.PrepareContext(ctx, query)
if err != nil {
return nil, err
}
defer stmt.Close()
return stmt.ExecContext(ctx, args...)
}
// Commit commits the transaction
func (t *StarTx) Commit() error {
return t.tx.Commit()
}
// Rollback rolls back the transaction
func (t *StarTx) Rollback() error {
return t.tx.Rollback()
}