Documentation
¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Retry ¶
Retry calls fn for retries times until it returns nil. If retries is zero fn would not be called. It delays and retries if the function returns any errors or panics. The fn function receives the current iteration as its argument.
Example ¶
package main
import (
"fmt"
"time"
"github.com/arsham/dbtools"
"github.com/pkg/errors"
)
func main() {
err := dbtools.Retry(100, time.Nanosecond, func(i int) error {
fmt.Printf("Running iteration %d.\n", i+1)
if i < 1 {
return errors.New("ignored error")
}
return nil
})
fmt.Println("Error:", err)
}
Output: Running iteration 1. Running iteration 2. Error: <nil>
Example (Two) ¶
package main
import (
"fmt"
"time"
"github.com/arsham/dbtools"
"github.com/pkg/errors"
)
func main() {
err := dbtools.Retry(2, time.Nanosecond, func(i int) error {
fmt.Printf("Running iteration %d.\n", i+1)
return errors.New("some error")
})
fmt.Println("Error:", err)
}
Output: Running iteration 1. Running iteration 2. Error: some error
func RetryTransaction ¶
func RetryTransaction(ctx context.Context, db *sql.DB, retries int, delay time.Duration, fn ...func(*sql.Tx) error) error
RetryTransaction combines WithTransaction and Retry calls. It stops the call if context is times out or cancelled.
Example ¶
// For this example we are using sqlmock, but you can use an actual
// connection with this function.
db, mock, err := sqlmock.New()
if err != nil {
panic(err)
}
defer db.Close()
defer func() {
if err := mock.ExpectationsWereMet(); err != nil {
fmt.Printf("there were unfulfilled expectations: %s\n", err)
}
}()
mock.ExpectBegin()
mock.ExpectRollback()
mock.ExpectBegin()
mock.ExpectRollback()
mock.ExpectBegin()
mock.ExpectCommit()
calls := 0
ctx := context.Background()
err = dbtools.RetryTransaction(ctx, db, 100, time.Millisecond*100, func(*sql.Tx) error {
calls++
fmt.Printf("Running iteration %d.\n", calls)
if calls < 3 {
return errors.New("some error")
}
return nil
})
fmt.Println("Error:", err)
Output: Running iteration 1. Running iteration 2. Running iteration 3. Error: <nil>
func WithTransaction ¶
WithTransaction creates a transaction on db and uses it to call fn functions one by one. The first function that returns an error or panics will cause the loop to stop and transaction to be rolled back.
Example ¶
// For this example we are using sqlmock, but you can use an actual
// connection with this function.
db, mock, err := sqlmock.New()
if err != nil {
panic(err)
}
defer db.Close()
defer func() {
if err := mock.ExpectationsWereMet(); err != nil {
fmt.Printf("there were unfulfilled expectations: %s\n", err)
}
}()
mock.ExpectBegin()
mock.ExpectCommit()
err = dbtools.WithTransaction(db, func(*sql.Tx) error {
fmt.Println("Running first query.")
return nil
}, func(*sql.Tx) error {
fmt.Println("Running second query.")
return nil
})
fmt.Println("Transaction has an error:", err != nil)
Output: Running first query. Running second query. Transaction has an error: false
Example (Two) ¶
// For this example we are using sqlmock, but you can use an actual
// connection with this function.
db, mock, err := sqlmock.New()
if err != nil {
panic(err)
}
defer db.Close()
defer func() {
if err := mock.ExpectationsWereMet(); err != nil {
fmt.Printf("there were unfulfilled expectations: %s\n", err)
}
}()
mock.ExpectBegin()
mock.ExpectRollback()
err = dbtools.WithTransaction(db, func(*sql.Tx) error {
fmt.Println("Running first query.")
return nil
}, func(*sql.Tx) error {
fmt.Println("Running second query.")
return errors.New("something happened")
}, func(*sql.Tx) error {
fmt.Println("Running third query.")
return nil
})
fmt.Println("Transaction has an error:", err != nil)
Output: Running first query. Running second query. Transaction has an error: true
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.