Skip to content

Commit

Permalink
Merge branch 'release/0.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
takama committed Apr 9, 2018
2 parents 7bbf04d + 3ec48e1 commit 03374a4
Show file tree
Hide file tree
Showing 9 changed files with 1,023 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
PROJECT=github.com/takama/backer

# Use the 0.0.0 tag for testing, it shouldn't clobber any release builds
RELEASE?=0.0.2
RELEASE?=0.1.0

BUILDTAGS=

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Backer

[![Build Status](https://travis-ci.org/takama/backer.svg?branch=master)](https://travis-ci.org/takama/backer)
[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/takama/backer/issues)
[![Go Report Card](https://goreportcard.com/badge/github.com/takama/backer)](https://goreportcard.com/report/github.com/takama/backer)

Backer service which is allowed players to back each other and get a part the prize in case of a win.

## Logic description
Expand Down
7 changes: 7 additions & 0 deletions db/transact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package db

// Transact contains transaction control methods
type Transact interface {
Commit() error
Rollback() error
}
14 changes: 14 additions & 0 deletions player/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package player

import (
"github.com/takama/backer/db"
"github.com/takama/backer/model"
)

// Controller defines DB interface for Player Entry
type Controller interface {
Transaction() (db.Transact, error)
NewPlayer(ID string, tx db.Transact) error
FindPlayer(ID string, tx db.Transact) (*model.Player, error)
SavePlayer(player *model.Player, tx db.Transact) error
}
141 changes: 141 additions & 0 deletions player/player.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package player

import (
"errors"
"sync"

"github.com/takama/backer"
"github.com/takama/backer/helper"
"github.com/takama/backer/model"
)

var (
// ErrInsufficientPoints appears if player has not enough points
ErrInsufficientPoints = errors.New("Insufficient points")
)

// Entry implements Player interface
type Entry struct {
Controller
mutex sync.RWMutex
model.Player
}

// New returns new Entry which implement Player interface
func New(id string, ctrl Controller) (*Entry, error) {
tx, err := ctrl.Transaction()
if err != nil {
return nil, err
}

entry := &Entry{Controller: ctrl}

player, err := ctrl.FindPlayer(id, tx)
if err != nil {
err = ctrl.NewPlayer(id, tx)
if err != nil {
tx.Rollback()
return nil, err
}
player = &model.Player{ID: id}
}
entry.Player = *player

err = tx.Commit()
if err != nil {
return nil, err
}

return entry, nil
}

// Fund funds (add to balance) player with amount
func (entry *Entry) Fund(amount backer.Points) error {
tx, err := entry.Controller.Transaction()
if err != nil {
return err
}

player, err := entry.Controller.FindPlayer(entry.Player.ID, tx)
if err != nil {
tx.Rollback()
return err
}

player.Balance = backer.Points(
helper.RoundPrice(float32(player.Balance) + helper.TruncatePrice(float32(amount))))
err = entry.Controller.SavePlayer(player, tx)
if err != nil {
tx.Rollback()
return err
}

err = tx.Commit()
if err != nil {
return err
}

entry.mutex.Lock()
defer entry.mutex.Unlock()
entry.Player.Balance = player.Balance

return nil
}

// Take takes points from player account
func (entry *Entry) Take(amount backer.Points) error {
tx, err := entry.Controller.Transaction()
if err != nil {
return err
}

player, err := entry.Controller.FindPlayer(entry.Player.ID, tx)
if err != nil {
tx.Rollback()
return err
}

if player.Balance < amount {
return ErrInsufficientPoints
}

player.Balance = backer.Points(
helper.RoundPrice(float32(player.Balance) - helper.TruncatePrice(float32(amount))))
err = entry.Controller.SavePlayer(player, tx)
if err != nil {
tx.Rollback()
return err
}

err = tx.Commit()
if err != nil {
return err
}

entry.mutex.Lock()
defer entry.mutex.Unlock()
entry.Player.Balance = player.Balance

return nil
}

// Balance gets current points
func (entry *Entry) Balance() (backer.Points, error) {
player, err := entry.Controller.FindPlayer(entry.Player.ID, nil)
if err != nil {
return 0, err
}

entry.mutex.Lock()
defer entry.mutex.Unlock()
entry.Player.Balance = player.Balance

return player.Balance, nil
}

// ID returns player ID
func (entry *Entry) ID() string {
entry.mutex.RLock()
defer entry.mutex.RUnlock()
return entry.Player.ID
}
Loading

0 comments on commit 03374a4

Please sign in to comment.