Instantly share code, notes, and snippets.

Embed
What would you like to do?
package main
import (
"fmt"
)
const prompt = `Please enter number of operation:
1. Create new account
2. Show detail of account
3. Deposit
4. Withdraw
5. Make transfer
6. List exist accounts by Id
7. List exist accounts by balance
8. Delete account
9. Exit`
func main() {
fmt.Println("Welcome bank of xorm!")
Exit:
for {
fmt.Println(prompt)
var num int
fmt.Scanf("%d\n", &num)
switch num {
case 1:
fmt.Println("Please enter <name> <balance>:")
var name string
var balance float64
fmt.Scanf("%s %f\n", &name, &balance)
if err := newAccount(name, balance); err != nil {
fmt.Println("Fail to create new account:", err)
} else {
fmt.Println("New account has been created")
}
case 2:
fmt.Println("Please enter <id>:")
var id int64
fmt.Scanf("%d\n", &id)
a, err := getAccount(id)
if err != nil {
fmt.Println("Fail to get account:", err)
} else {
fmt.Printf("%#v\n", a)
}
case 3:
fmt.Println("Please enter <id> <deposit>:")
var id int64
var deposit float64
fmt.Scanf("%d %f\n", &id, &deposit)
a, err := makeDeposit(id, deposit)
if err != nil {
fmt.Println("Fail to deposit:", err)
} else {
fmt.Printf("%#v\n", a)
}
case 4:
fmt.Println("Please enter <id> <withdraw>:")
var id int64
var withdraw float64
fmt.Scanf("%d %f\n", &id, &withdraw)
a, err := makeWithdraw(id, withdraw)
if err != nil {
fmt.Println("Fail to withdraw:", err)
} else {
fmt.Printf("%#v\n", a)
}
case 5:
fmt.Println("Please enter <id> <balance> <id>:")
var id1, id2 int64
var balance float64
fmt.Scanf("%d %f %d\n", &id1, &balance, &id2)
if err := makeTransfer(id1, id2, balance); err != nil {
fmt.Println("Fail to transfer:", err)
} else {
fmt.Println("Transfer has been made")
}
case 6:
as, err := getAccountsAscId()
if err != nil {
fmt.Println("Fail to get accounts:", err)
} else {
for i, a := range as {
fmt.Printf("%d: %#v\n", i+1, a)
}
}
case 7:
as, err := getAccountsDescBalance()
if err != nil {
fmt.Println("Fail to get accounts:", err)
} else {
for i, a := range as {
fmt.Printf("%d: %#v\n", i+1, a)
}
}
case 8:
fmt.Println("Please enter <id>:")
var id int64
fmt.Scanf("%d\n", &id)
if err := deleteAccount(id); err != nil {
fmt.Println("Fail to delete account:", err)
} else {
fmt.Println("Account has been deleted")
}
case 9:
fmt.Println("Thank you! Hope see you again soon!")
break Exit
default:
fmt.Println("Unknown operation number:", num)
}
fmt.Println()
}
}
package main
import (
"errors"
"log"
"github.com/go-xorm/xorm"
_ "github.com/mattn/go-sqlite3"
)
// Bank account
type Account struct {
Id int64
Name string `xorm:"unique"`
Balance float64
Version int `xorm:"version"` // Optimistic Locking
}
// ORM engine
var x *xorm.Engine
func init() {
// Create ORM engine and database
var err error
x, err = xorm.NewEngine("sqlite3", "./bank.db")
if err != nil {
log.Fatalf("Fail to create engine: %v\n", err)
}
// Sync tables
if err = x.Sync(new(Account)); err != nil {
log.Fatalf("Fail to sync database: %v\n", err)
}
}
func newAccount(name string, balance float64) error {
_, err := x.Insert(&Account{Name: name, Balance: balance})
return err
}
func getAccount(id int64) (*Account, error) {
a := &Account{}
has, err := x.Id(id).Get(a)
if err != nil {
return nil, err
} else if !has {
return nil, errors.New("Account does not exist")
}
return a, nil
}
func makeDeposit(id int64, deposit float64) (*Account, error) {
a, err := getAccount(id)
if err != nil {
return nil, err
}
a.Balance += deposit
_, err = x.Update(a)
return a, err
}
func makeWithdraw(id int64, withdraw float64) (*Account, error) {
a, err := getAccount(id)
if err != nil {
return nil, err
}
if a.Balance < withdraw {
return nil, errors.New("Not enough balance")
}
a.Balance -= withdraw
_, err = x.Update(a)
return a, err
}
func makeTransfer(id1, id2 int64, balance float64) error {
a1, err := getAccount(id1)
if err != nil {
return err
}
a2, err := getAccount(id2)
if err != nil {
return err
}
if a1.Balance < balance {
return errors.New("Not enough balance")
}
a1.Balance -= balance
a2.Balance += balance
// Create Session object.
sess := x.NewSession()
defer sess.Close()
// Start transcation.
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Update(a1); err != nil {
// Roll back when error occurs.
sess.Rollback()
return err
} else if _, err = sess.Update(a2); err != nil {
sess.Rollback()
return err
}
// Commit transcation.
return sess.Commit()
}
func getAccountsAscId() (as []Account, err error) {
// Find returns all results
err = x.Find(&as)
return as, err
}
func getAccountsDescBalance() (as []Account, err error) {
err = x.Desc("balance").Find(&as)
return as, err
}
func deleteAccount(id int64) error {
_, err := x.Delete(&Account{Id: id})
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment