Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ sqlc:
sqlc generate

test:
go test -v -cover ./...
go test -cover ./...

server:
go run main.go
Expand Down
7 changes: 4 additions & 3 deletions api/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,9 @@ func TestCreateAccountAPI(t *testing.T) {
Owner: account.Owner,
Currency: account.Currency,
Balance: 0,
AccType: db.AccountTypeBank,
}
store.EXPECT().CreateAccount(gomock.Any(), arg).Times(1).Return(account, nil)
store.EXPECT().CreateAccountTx(gomock.Any(), arg).Times(1).Return(account, nil)
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusOK, recorder.Code)
Expand All @@ -191,7 +192,7 @@ func TestCreateAccountAPI(t *testing.T) {
addAuth(t, request, tokenMaker, constants.AuthTypeBearer, user.Username, time.Minute)
},
buildStubs: func(store *mockdb.MockStore) {
store.EXPECT().CreateAccount(gomock.Any(), gomock.Any()).Times(1).Return(db.Account{}, sql.ErrConnDone)
store.EXPECT().CreateAccountTx(gomock.Any(), gomock.Any()).Times(1).Return(db.Account{}, sql.ErrConnDone)
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusBadRequest, recorder.Code)
Expand All @@ -207,7 +208,7 @@ func TestCreateAccountAPI(t *testing.T) {
addAuth(t, request, tokenMaker, constants.AuthTypeBearer, user.Username, time.Minute)
},
buildStubs: func(store *mockdb.MockStore) {
store.EXPECT().CreateAccount(gomock.Any(), gomock.Any()).Times(0)
store.EXPECT().CreateAccountTx(gomock.Any(), gomock.Any()).Times(0)
},
checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) {
require.Equal(t, http.StatusBadRequest, recorder.Code)
Expand Down
3 changes: 2 additions & 1 deletion api/controllers/account_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ func (c *AccountController) CreateAccount(ctx *gin.Context) {
Owner: authPayload.Username,
Currency: req.Currency,
Balance: 0,
AccType: db.AccountTypeBank,
}

account, err := c.store.CreateAccount(ctx, arg)
account, err := c.store.CreateAccountTx(ctx, arg)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
switch pqErr.Code.Name() {
Expand Down
44 changes: 44 additions & 0 deletions api/services/deposit_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package services

import (
"context"
"database/sql"
"errors"

db "github.com/hhow09/simple_bank/db/sqlc"
"github.com/hhow09/simple_bank/util"
)

type DepositService struct {
store db.Store
}

func NewDepositService(store db.Store) DepositService {
return DepositService{
store: store,
}
}

type DepositParams struct {
User db.User
Currency string
Amount int64
}

func (dc *DepositService) Deposit(ctx context.Context, params DepositParams) (db.Transfer, error) {
var transfer db.Transfer
if !util.IsSupportedCurrency(params.Currency) {
return transfer, errors.New("currency not supportted")
}
if params.Amount <= 0 {
return transfer, errors.New("deposit should be more than 0")
}
user, err := dc.store.GetUser(ctx, params.User.Username)
if err != nil {
if err == sql.ErrNoRows {
return transfer, errors.New("user not found")
}
return transfer, errors.New("internal server error")
}
return dc.store.CreateDepositTx(ctx, db.CreateDepositTxParams{User: user, Amount: params.Amount, Currency: params.Currency})
}
8 changes: 8 additions & 0 deletions api/services/services.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package services

import "go.uber.org/fx"

// Module exported for initializing application
var Module = fx.Options(
fx.Provide(NewDepositService),
)
7 changes: 7 additions & 0 deletions db/migration/000003_add_account_type.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ALTER TABLE "accounts" DROP CONSTRAINT "uq_owner_currency_type";

ALTER TABLE "accounts" DROP COLUMN acc_type

ALTER TABLE "accounts" ADD CONSTRAINT "owner_currency_key" UNIQUE ("owner", "currency");

DROP TYPE ACCOUNT_TYPE;
7 changes: 7 additions & 0 deletions db/migration/000003_add_account_type.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TYPE ACCOUNT_TYPE AS ENUM ('bank', 'external', 'credit_card');

ALTER TABLE "accounts" DROP CONSTRAINT "owner_currency_key";

ALTER TABLE "accounts" ADD acc_type ACCOUNT_TYPE NOT NULL DEFAULT('bank');

ALTER TABLE "accounts" ADD CONSTRAINT "uq_owner_currency_type" UNIQUE ("owner", "currency", "acc_type");
75 changes: 75 additions & 0 deletions db/mock/store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 30 additions & 5 deletions db/query/account.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,48 @@
INSERT INTO accounts (
owner,
balance,
currency
currency,
acc_type
) VALUES (
$1, $2, $3
$1, $2, $3, $4
) RETURNING *;

-- name: GetAccount :one
SELECT * FROM accounts
WHERE id = $1 LIMIT 1;
WHERE id = $1 AND acc_type = 'bank'
LIMIT 1;

-- name: GetAccountForUpdate :one
SELECT * FROM accounts
WHERE id = $1 LIMIT 1
WHERE id = $1
AND acc_type = 'bank'
LIMIT 1
FOR NO KEY UPDATE;

-- name: GetAccountByCurrencyForUpdate :one
SELECT * FROM accounts
WHERE currency = $1 AND owner = $2
AND acc_type = 'bank'
LIMIT 1
FOR NO KEY UPDATE;

-- name: GetExtAccount :one
-- for deposit use
SELECT * FROM accounts
WHERE owner = $1 AND currency = $2 AND acc_type = 'external'
LIMIT 1;

-- name: GetExtAccountForUpdate :one
-- for deposit use
SELECT * FROM accounts
WHERE owner = $1 AND currency = $2 AND acc_type = 'external'
LIMIT 1
FOR NO KEY UPDATE;

-- name: ListAccounts :many
SELECT * FROM accounts
WHERE owner = $1
WHERE owner = $1
AND acc_type = 'bank'
ORDER BY id
LIMIT $2
OFFSET $3;
Expand Down
Loading