Users: NullTime, removing transaction from insert.

This commit is contained in:
Matthew Dillon 2014-12-17 15:29:13 -09:00
parent 950b15a117
commit f912a434b5
4 changed files with 12 additions and 42 deletions

View file

@ -2,11 +2,9 @@ package datastore
import ( import (
"fmt" "fmt"
"math/rand"
"strings" "strings"
"time" "time"
"github.com/jmoiron/modl"
"github.com/thermokarst/bactdb/models" "github.com/thermokarst/bactdb/models"
) )
@ -30,46 +28,16 @@ func (s *usersStore) Get(id int64) (*models.User, error) {
} }
func (s *usersStore) Create(user *models.User) (bool, error) { func (s *usersStore) Create(user *models.User) (bool, error) {
retries := 3
var wantRetry bool
currentTime := time.Now() currentTime := time.Now()
user.CreatedAt = currentTime user.CreatedAt = currentTime
user.UpdatedAt = currentTime user.UpdatedAt = currentTime
fmt.Println(user)
retry: if err := s.dbh.Insert(user); err != nil {
retries--
wantRetry = false
if retries == 0 {
return false, fmt.Errorf("failed to create user with username %q after retrying", user.UserName)
}
var created bool
err := transact(s.dbh, func(tx modl.SqlExecutor) error {
var existing []*models.User
if err := tx.Select(&existing, `SELECT * FROM users WHERE username=$1 LIMIT 1;`, user.UserName); err != nil {
return err
}
if len(existing) > 0 {
*user = *existing[0]
return nil
}
if err := tx.Insert(user); err != nil {
if strings.Contains(err.Error(), `violates unique constraint "username_idx"`) { if strings.Contains(err.Error(), `violates unique constraint "username_idx"`) {
time.Sleep(time.Duration(rand.Intn(75)) * time.Millisecond) return false, err
wantRetry = true
return err
} }
return err
} }
return true, nil
created = true
return nil
})
if wantRetry {
goto retry
}
return created, err
} }
func (s *usersStore) List(opt *models.UserListOptions) ([]*models.User, error) { func (s *usersStore) List(opt *models.UserListOptions) ([]*models.User, error) {

View file

@ -37,6 +37,7 @@ func TestUsersStore_Get_db(t *testing.T) {
} }
normalizeTime(&want.CreatedAt, &want.UpdatedAt, &want.DeletedAt) normalizeTime(&want.CreatedAt, &want.UpdatedAt, &want.DeletedAt)
normalizeTime(&user.CreatedAt, &user.UpdatedAt, &user.DeletedAt)
if !reflect.DeepEqual(user, want) { if !reflect.DeepEqual(user, want) {
t.Errorf("got user %+v, want %+v", user, want) t.Errorf("got user %+v, want %+v", user, want)
} }
@ -77,8 +78,9 @@ func TestUsersStore_List_db(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
for _, u := range want { for i := range want {
normalizeTime(&u.CreatedAt, &u.UpdatedAt, &u.DeletedAt) normalizeTime(&want[i].CreatedAt, &want[i].UpdatedAt, &want[i].DeletedAt)
normalizeTime(&users[i].CreatedAt, &users[i].UpdatedAt, &users[i].DeletedAt)
} }
if !reflect.DeepEqual(users, want) { if !reflect.DeepEqual(users, want) {
t.Errorf("got users %+v, want %+v", users, want) t.Errorf("got users %+v, want %+v", users, want)

View file

@ -15,7 +15,7 @@ type User struct {
UserName string `json:"userName"` UserName string `json:"userName"`
CreatedAt time.Time `db:"created_at" json:"createdAt"` CreatedAt time.Time `db:"created_at" json:"createdAt"`
UpdatedAt time.Time `db:"updated_at" json:"updatedAt"` UpdatedAt time.Time `db:"updated_at" json:"updatedAt"`
DeletedAt time.Time `db:"deleted_at" json:"deletedAt"` DeletedAt NullTime `db:"deleted_at" json:"deletedAt"`
} }
func NewUser() *User { func NewUser() *User {

View file

@ -54,7 +54,7 @@ func TestUsersService_Create(t *testing.T) {
mux.HandleFunc(urlPath(t, router.CreateUser, nil), func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc(urlPath(t, router.CreateUser, nil), func(w http.ResponseWriter, r *http.Request) {
called = true called = true
testMethod(t, r, "POST") testMethod(t, r, "POST")
testBody(t, r, `{"id":1,"userName":"Test User","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":"0001-01-01T00:00:00Z"}`+"\n") testBody(t, r, `{"id":1,"userName":"Test User","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n")
w.WriteHeader(http.StatusCreated) w.WriteHeader(http.StatusCreated)
writeJSON(w, want) writeJSON(w, want)