Add an example repository showing how to use transactions

new-query-chunks-api
Vinícius Garcia 2022-05-07 22:26:27 -03:00
parent af6ee27e3a
commit 527c79ad1c
2 changed files with 73 additions and 0 deletions

View File

@ -0,0 +1,10 @@
package repo
import "time"
type User struct {
ID int `ksql:"id"`
Name string `ksql:"name"`
Email string `ksql:"email"`
CreatedAt time.Time `ksql:"created_at"`
}

View File

@ -0,0 +1,63 @@
package repo
import (
"context"
"fmt"
"time"
"github.com/vingarcia/ksql"
)
var usersTable = ksql.NewTable("users", "id")
// This function doesn't care if db is a transaction or not:
func GetUser(ctx context.Context, db ksql.Provider, userId int) (User, error) {
var user User
err := db.QueryOne(ctx, &user, "FROM users WHERE id = ?", userId)
return user, err
}
// This function doesn't care if db is a transaction or not:
func GetUserByEmail(ctx context.Context, db ksql.Provider, email string) (User, error) {
var user User
err := db.QueryOne(ctx, &user, "FROM users WHERE email = ?", email)
return user, err
}
// This function doesn't care if db is a transaction or not:
func CreateUser(ctx context.Context, db ksql.Provider, user User) error {
user.CreatedAt = time.Now()
return db.Insert(ctx, usersTable, &user)
}
// This function doesn't care if db is a transaction or not:
func UpdateUser(ctx context.Context, db ksql.Provider, user User) error {
return db.Patch(ctx, usersTable, &user)
}
// This function creates a transaction from the input db, if db was already a transaction
// this operation will just keep working in the same transaction instead of creating a new one.
func ChangeUserEmail(ctx context.Context, db ksql.Provider, userID int, newEmail string) error {
return db.Transaction(ctx, func(db ksql.Provider) error {
user, err := GetUser(ctx, db, userID)
if err != nil {
return err
}
// If there is nothing to do, just return:
if user.Email == newEmail {
return nil
}
_, err = GetUserByEmail(ctx, db, newEmail)
if err != ksql.ErrRecordNotFound {
return fmt.Errorf("can't change user email to '%s': this email is already used by other user", newEmail)
}
if err != nil {
return err
}
user.Email = newEmail
return UpdateUser(ctx, db, user)
})
}