test: try to test user repo and event repo
All checks were successful
Build and test / Build (push) Successful in 2m27s

This commit is contained in:
Muyao CHEN 2024-10-23 09:54:00 +02:00
parent 304651e7ff
commit 0da8b29507
12 changed files with 63 additions and 380 deletions

View File

@ -546,3 +546,21 @@ I have to figure out how to use the generated mock files.
The goals for the next week is to finish the basic operations for each level The goals for the next week is to finish the basic operations for each level
and run some integration tests with `curl`. and run some integration tests with `curl`.
### 2024/10/22
I am facing come difficulties on testing of the `repo` functions.
First, I have to keep the business logic in the service layer. That means I
have to create the transaction at the service layer. I don't need to depend
on the implementation detail. So I have created a Transaction interface.
I don't care of the type of `tx` because I will pass it to repo layer and I
suppose that it knows what it is doing. Considering this, my repo `Create`
function will have to take an any and deduct the type of `tx`. So the layer
becomes untestable, because I have to pass a *sql.Tx into it and create a
querier.
Since this repo layer is just a wrapping layer between the `sqlc.models` and
my own models, I can extract the conversion part to functions and test them.
I'm not testing the whole thing but I test what I can.

1
go.mod
View File

@ -16,7 +16,6 @@ require (
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0 github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.5.0
go.uber.org/zap v1.27.0 go.uber.org/zap v1.27.0
golang.org/x/crypto v0.27.0 golang.org/x/crypto v0.27.0
golang.org/x/net v0.26.0 golang.org/x/net v0.26.0

2
go.sum
View File

@ -142,8 +142,6 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=

View File

@ -35,12 +35,12 @@ import (
) )
type eventRepository struct { type eventRepository struct {
db *sql.DB queries sqlc.Querier
} }
func NewEventRepository(db *sql.DB) repo.EventRepository { func NewEventRepository(db *sql.DB) repo.EventRepository {
return &eventRepository{ return &eventRepository{
db: db, queries: sqlc.New(db),
} }
} }
@ -52,18 +52,10 @@ func (e *eventRepository) Create(
panic("unimplemented") panic("unimplemented")
} }
// GetByID implements repo.EventRepository. func convToEventRetrieved(eventDTO *sqlc.GetEventByIDRow) (*model.EventRetrieved, error) {
func (e *eventRepository) GetByID(ctx context.Context, eventID int) (*model.EventRetrieved, error) {
queries := sqlc.New(e.db)
eventDTO, err := queries.GetEventByID(ctx, int32(eventID))
if err != nil {
log.ErrorLog("query error", "err", err)
return nil, err
}
// marshal owner and users // marshal owner and users
var owner model.UserBaseRetrieved var owner model.UserBaseRetrieved
err = json.Unmarshal(eventDTO.Owner, &owner) err := json.Unmarshal(eventDTO.Owner, &owner)
if err != nil { if err != nil {
// Unexpected // Unexpected
log.ErrorLog("json unmarshal error", "err", err) log.ErrorLog("json unmarshal error", "err", err)
@ -71,7 +63,7 @@ func (e *eventRepository) GetByID(ctx context.Context, eventID int) (*model.Even
} }
var users []*model.UserBaseRetrieved var users []*model.UserBaseRetrieved
err = json.Unmarshal(eventDTO.Owner, &users) err = json.Unmarshal(eventDTO.Users, &users)
if err != nil { if err != nil {
// Unexpected // Unexpected
log.ErrorLog("json unmarshal error", "err", err) log.ErrorLog("json unmarshal error", "err", err)
@ -96,18 +88,18 @@ func (e *eventRepository) GetByID(ctx context.Context, eventID int) (*model.Even
return eventRetrieved, nil return eventRetrieved, nil
} }
// ListEventsByUserID implements repo.EventRepository. // GetByID implements repo.EventRepository.
func (e *eventRepository) ListEventsByUserID( func (e *eventRepository) GetByID(ctx context.Context, eventID int) (*model.EventRetrieved, error) {
ctx context.Context, eventDTO, err := e.queries.GetEventByID(ctx, int32(eventID))
userID int,
) ([]*model.EventListRetrieved, error) {
queries := sqlc.New(e.db)
eventsDTO, err := queries.ListEventsByUserID(ctx, int32(userID))
if err != nil { if err != nil {
log.ErrorLog("query error", "err", err) log.ErrorLog("query error", "err", err)
return nil, err return nil, err
} }
return convToEventRetrieved(&eventDTO)
}
func convToEventList(eventsDTO []sqlc.ListEventsByUserIDRow) ([]*model.EventListRetrieved, error) {
var events []*model.EventListRetrieved var events []*model.EventListRetrieved
for _, evDTO := range eventsDTO { for _, evDTO := range eventsDTO {
@ -130,13 +122,26 @@ func (e *eventRepository) ListEventsByUserID(
return events, nil return events, nil
} }
// ListEventsByUserID implements repo.EventRepository.
func (e *eventRepository) ListEventsByUserID(
ctx context.Context,
userID int,
) ([]*model.EventListRetrieved, error) {
eventsDTO, err := e.queries.ListEventsByUserID(ctx, int32(userID))
if err != nil {
log.ErrorLog("query error", "err", err)
return nil, err
}
return convToEventList(eventsDTO)
}
// UpdateInfo implements repo.EventRepository. // UpdateInfo implements repo.EventRepository.
func (e *eventRepository) UpdateEventByID( func (e *eventRepository) UpdateEventByID(
ctx context.Context, ctx context.Context,
event *model.EventUpdateEntity, event *model.EventUpdateEntity,
) error { ) error {
queries := sqlc.New(e.db) err := e.queries.UpdateEventByID(ctx, sqlc.UpdateEventByIDParams{
err := queries.UpdateEventByID(ctx, sqlc.UpdateEventByIDParams{
ID: int32(event.ID), ID: int32(event.ID),
Name: event.Name, Name: event.Name,
Description: sql.NullString{String: event.Description, Valid: true}, Description: sql.NullString{String: event.Description, Valid: true},

View File

@ -1,277 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./internal/howmuch/adapter/repo/sqlc/querier.go
//
// Generated by this command:
//
// mockgen -source=./internal/howmuch/adapter/repo/sqlc/querier.go -package=mock
//
// Package mock is a generated GoMock package.
package mock
import (
context "context"
reflect "reflect"
sqlc "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/repo/sqlc"
gomock "go.uber.org/mock/gomock"
)
// MockQuerier is a mock of Querier interface.
type MockQuerier struct {
ctrl *gomock.Controller
recorder *MockQuerierMockRecorder
}
// MockQuerierMockRecorder is the mock recorder for MockQuerier.
type MockQuerierMockRecorder struct {
mock *MockQuerier
}
// NewMockQuerier creates a new mock instance.
func NewMockQuerier(ctrl *gomock.Controller) *MockQuerier {
mock := &MockQuerier{ctrl: ctrl}
mock.recorder = &MockQuerierMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockQuerier) EXPECT() *MockQuerierMockRecorder {
return m.recorder
}
// DeleteExpense mocks base method.
func (m *MockQuerier) DeleteExpense(ctx context.Context, id int32) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteExpense", ctx, id)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteExpense indicates an expected call of DeleteExpense.
func (mr *MockQuerierMockRecorder) DeleteExpense(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteExpense", reflect.TypeOf((*MockQuerier)(nil).DeleteExpense), ctx, id)
}
// DeleteTransactionsOfExpenseID mocks base method.
func (m *MockQuerier) DeleteTransactionsOfExpenseID(ctx context.Context, expenseID int32) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteTransactionsOfExpenseID", ctx, expenseID)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteTransactionsOfExpenseID indicates an expected call of DeleteTransactionsOfExpenseID.
func (mr *MockQuerierMockRecorder) DeleteTransactionsOfExpenseID(ctx, expenseID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTransactionsOfExpenseID", reflect.TypeOf((*MockQuerier)(nil).DeleteTransactionsOfExpenseID), ctx, expenseID)
}
// GetEventByID mocks base method.
func (m *MockQuerier) GetEventByID(ctx context.Context, id int32) (sqlc.GetEventByIDRow, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetEventByID", ctx, id)
ret0, _ := ret[0].(sqlc.GetEventByIDRow)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetEventByID indicates an expected call of GetEventByID.
func (mr *MockQuerierMockRecorder) GetEventByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEventByID", reflect.TypeOf((*MockQuerier)(nil).GetEventByID), ctx, id)
}
// GetExpenseByID mocks base method.
func (m *MockQuerier) GetExpenseByID(ctx context.Context, id int32) (sqlc.GetExpenseByIDRow, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetExpenseByID", ctx, id)
ret0, _ := ret[0].(sqlc.GetExpenseByIDRow)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetExpenseByID indicates an expected call of GetExpenseByID.
func (mr *MockQuerierMockRecorder) GetExpenseByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExpenseByID", reflect.TypeOf((*MockQuerier)(nil).GetExpenseByID), ctx, id)
}
// GetUserByEmail mocks base method.
func (m *MockQuerier) GetUserByEmail(ctx context.Context, email string) (sqlc.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserByEmail", ctx, email)
ret0, _ := ret[0].(sqlc.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserByEmail indicates an expected call of GetUserByEmail.
func (mr *MockQuerierMockRecorder) GetUserByEmail(ctx, email any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByEmail", reflect.TypeOf((*MockQuerier)(nil).GetUserByEmail), ctx, email)
}
// GetUserByID mocks base method.
func (m *MockQuerier) GetUserByID(ctx context.Context, id int32) (sqlc.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserByID", ctx, id)
ret0, _ := ret[0].(sqlc.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserByID indicates an expected call of GetUserByID.
func (mr *MockQuerierMockRecorder) GetUserByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByID", reflect.TypeOf((*MockQuerier)(nil).GetUserByID), ctx, id)
}
// InsertEvent mocks base method.
func (m *MockQuerier) InsertEvent(ctx context.Context, arg sqlc.InsertEventParams) (sqlc.Event, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertEvent", ctx, arg)
ret0, _ := ret[0].(sqlc.Event)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertEvent indicates an expected call of InsertEvent.
func (mr *MockQuerierMockRecorder) InsertEvent(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertEvent", reflect.TypeOf((*MockQuerier)(nil).InsertEvent), ctx, arg)
}
// InsertExpense mocks base method.
func (m *MockQuerier) InsertExpense(ctx context.Context, arg sqlc.InsertExpenseParams) (sqlc.Expense, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertExpense", ctx, arg)
ret0, _ := ret[0].(sqlc.Expense)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertExpense indicates an expected call of InsertExpense.
func (mr *MockQuerierMockRecorder) InsertExpense(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertExpense", reflect.TypeOf((*MockQuerier)(nil).InsertExpense), ctx, arg)
}
// InsertParticipation mocks base method.
func (m *MockQuerier) InsertParticipation(ctx context.Context, arg sqlc.InsertParticipationParams) (sqlc.Participation, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertParticipation", ctx, arg)
ret0, _ := ret[0].(sqlc.Participation)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertParticipation indicates an expected call of InsertParticipation.
func (mr *MockQuerierMockRecorder) InsertParticipation(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertParticipation", reflect.TypeOf((*MockQuerier)(nil).InsertParticipation), ctx, arg)
}
// InsertTransaction mocks base method.
func (m *MockQuerier) InsertTransaction(ctx context.Context, arg sqlc.InsertTransactionParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertTransaction", ctx, arg)
ret0, _ := ret[0].(error)
return ret0
}
// InsertTransaction indicates an expected call of InsertTransaction.
func (mr *MockQuerierMockRecorder) InsertTransaction(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertTransaction", reflect.TypeOf((*MockQuerier)(nil).InsertTransaction), ctx, arg)
}
// InsertUser mocks base method.
func (m *MockQuerier) InsertUser(ctx context.Context, arg sqlc.InsertUserParams) (sqlc.User, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertUser", ctx, arg)
ret0, _ := ret[0].(sqlc.User)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertUser indicates an expected call of InsertUser.
func (mr *MockQuerierMockRecorder) InsertUser(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertUser", reflect.TypeOf((*MockQuerier)(nil).InsertUser), ctx, arg)
}
// ListEventsByUserID mocks base method.
func (m *MockQuerier) ListEventsByUserID(ctx context.Context, userID int32) ([]sqlc.ListEventsByUserIDRow, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListEventsByUserID", ctx, userID)
ret0, _ := ret[0].([]sqlc.ListEventsByUserIDRow)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListEventsByUserID indicates an expected call of ListEventsByUserID.
func (mr *MockQuerierMockRecorder) ListEventsByUserID(ctx, userID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEventsByUserID", reflect.TypeOf((*MockQuerier)(nil).ListEventsByUserID), ctx, userID)
}
// ListExpensesByEventID mocks base method.
func (m *MockQuerier) ListExpensesByEventID(ctx context.Context, id int32) ([]sqlc.Expense, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListExpensesByEventID", ctx, id)
ret0, _ := ret[0].([]sqlc.Expense)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListExpensesByEventID indicates an expected call of ListExpensesByEventID.
func (mr *MockQuerierMockRecorder) ListExpensesByEventID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListExpensesByEventID", reflect.TypeOf((*MockQuerier)(nil).ListExpensesByEventID), ctx, id)
}
// ListExpensesByEventIDByUserID mocks base method.
func (m *MockQuerier) ListExpensesByEventIDByUserID(ctx context.Context, id int32) ([]sqlc.Expense, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListExpensesByEventIDByUserID", ctx, id)
ret0, _ := ret[0].([]sqlc.Expense)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListExpensesByEventIDByUserID indicates an expected call of ListExpensesByEventIDByUserID.
func (mr *MockQuerierMockRecorder) ListExpensesByEventIDByUserID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListExpensesByEventIDByUserID", reflect.TypeOf((*MockQuerier)(nil).ListExpensesByEventIDByUserID), ctx, id)
}
// UpdateEventByID mocks base method.
func (m *MockQuerier) UpdateEventByID(ctx context.Context, arg sqlc.UpdateEventByIDParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateEventByID", ctx, arg)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateEventByID indicates an expected call of UpdateEventByID.
func (mr *MockQuerierMockRecorder) UpdateEventByID(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEventByID", reflect.TypeOf((*MockQuerier)(nil).UpdateEventByID), ctx, arg)
}
// UpdateExpenseByID mocks base method.
func (m *MockQuerier) UpdateExpenseByID(ctx context.Context, arg sqlc.UpdateExpenseByIDParams) (sqlc.Expense, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateExpenseByID", ctx, arg)
ret0, _ := ret[0].(sqlc.Expense)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateExpenseByID indicates an expected call of UpdateExpenseByID.
func (mr *MockQuerierMockRecorder) UpdateExpenseByID(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateExpenseByID", reflect.TypeOf((*MockQuerier)(nil).UpdateExpenseByID), ctx, arg)
}

View File

@ -19,27 +19,6 @@ type Querier interface {
InsertExpense(ctx context.Context, arg InsertExpenseParams) (Expense, error) InsertExpense(ctx context.Context, arg InsertExpenseParams) (Expense, error)
InsertParticipation(ctx context.Context, arg InsertParticipationParams) (Participation, error) InsertParticipation(ctx context.Context, arg InsertParticipationParams) (Participation, error)
InsertTransaction(ctx context.Context, arg InsertTransactionParams) error InsertTransaction(ctx context.Context, arg InsertTransactionParams) error
// MIT License
//
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
InsertUser(ctx context.Context, arg InsertUserParams) (User, error) InsertUser(ctx context.Context, arg InsertUserParams) (User, error)
ListEventsByUserID(ctx context.Context, userID int32) ([]ListEventsByUserIDRow, error) ListEventsByUserID(ctx context.Context, userID int32) ([]ListEventsByUserIDRow, error)
ListExpensesByEventID(ctx context.Context, id int32) ([]Expense, error) ListExpensesByEventID(ctx context.Context, id int32) ([]Expense, error)

View File

@ -1,25 +1,3 @@
-- MIT License
--
-- Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in all
-- copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
-- name: InsertUser :one -- name: InsertUser :one
INSERT INTO "user" ( INSERT INTO "user" (
email, first_name, last_name, password, created_at, updated_at email, first_name, last_name, password, created_at, updated_at

View File

@ -53,7 +53,6 @@ func (q *Queries) GetUserByID(ctx context.Context, id int32) (User, error) {
} }
const insertUser = `-- name: InsertUser :one const insertUser = `-- name: InsertUser :one
INSERT INTO "user" ( INSERT INTO "user" (
email, first_name, last_name, password, created_at, updated_at email, first_name, last_name, password, created_at, updated_at
) VALUES ( $1, $2, $3, $4, $5, $6 ) ) VALUES ( $1, $2, $3, $4, $5, $6 )
@ -69,27 +68,6 @@ type InsertUserParams struct {
UpdatedAt time.Time UpdatedAt time.Time
} }
// MIT License
//
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
func (q *Queries) InsertUser(ctx context.Context, arg InsertUserParams) (User, error) { func (q *Queries) InsertUser(ctx context.Context, arg InsertUserParams) (User, error) {
row := q.db.QueryRowContext(ctx, insertUser, row := q.db.QueryRowContext(ctx, insertUser,
arg.Email, arg.Email,

View File

@ -31,18 +31,17 @@ import (
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/repo/sqlc" "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/repo/sqlc"
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model" "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model"
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo" "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo"
"github.com/jackc/pgx/v5"
) )
type userRepository struct { type userRepository struct {
db *sql.DB querier sqlc.Querier
} }
const insertTimeout = 1 * time.Second const insertTimeout = 1 * time.Second
func NewUserRepository(db *sql.DB) repo.UserRepository { func NewUserRepository(db *sql.DB) repo.UserRepository {
return &userRepository{ return &userRepository{
db: db, querier: sqlc.New(db),
} }
} }
@ -66,7 +65,7 @@ func (ur *userRepository) Create(
tx, ok := transaction.(*sql.Tx) tx, ok := transaction.(*sql.Tx)
if !ok { if !ok {
return nil, errors.New("transaction is not a pgx.Tx") return nil, errors.New("transaction is not a *sql.Tx")
} }
queries := sqlc.New(tx) queries := sqlc.New(tx)
@ -89,9 +88,8 @@ func (ur *userRepository) Create(
// GetByEmail if not found, return nil for user but not error. // GetByEmail if not found, return nil for user but not error.
func (ur *userRepository) GetByEmail(ctx context.Context, email string) (*model.UserEntity, error) { func (ur *userRepository) GetByEmail(ctx context.Context, email string) (*model.UserEntity, error) {
queries := sqlc.New(ur.db) userDB, err := ur.querier.GetUserByEmail(ctx, email)
userDB, err := queries.GetUserByEmail(ctx, email) if errors.Is(err, sql.ErrNoRows) {
if errors.Is(err, pgx.ErrNoRows) {
// No query error, but user not found // No query error, but user not found
return nil, nil return nil, nil
} else if err != nil { } else if err != nil {
@ -110,9 +108,8 @@ func (ur *userRepository) GetByEmail(ctx context.Context, email string) (*model.
} }
func (ur *userRepository) GetByID(ctx context.Context, id int) (*model.UserEntity, error) { func (ur *userRepository) GetByID(ctx context.Context, id int) (*model.UserEntity, error) {
queries := sqlc.New(ur.db) userDB, err := ur.querier.GetUserByID(ctx, int32(id))
userDB, err := queries.GetUserByID(ctx, int32(id)) if errors.Is(err, sql.ErrNoRows) {
if errors.Is(err, pgx.ErrNoRows) {
// No query error, but user not found // No query error, but user not found
return nil, nil return nil, nil
} else if err != nil { } else if err != nil {

View File

@ -22,7 +22,9 @@
package repo package repo
import "context" import (
"context"
)
type DBRepository interface { type DBRepository interface {
Transaction( Transaction(

View File

@ -29,7 +29,11 @@ import (
) )
type UserRepository interface { type UserRepository interface {
Create(ctx context.Context, transaction interface{}, u *model.UserEntity) (*model.UserEntity, error) Create(
ctx context.Context,
transaction interface{},
u *model.UserEntity,
) (*model.UserEntity, error)
GetByEmail(ctx context.Context, email string) (*model.UserEntity, error) GetByEmail(ctx context.Context, email string) (*model.UserEntity, error)
GetByID(ctx context.Context, id int) (*model.UserEntity, error) GetByID(ctx context.Context, id int) (*model.UserEntity, error)
} }

View File

@ -22,7 +22,9 @@
package repomock package repomock
import "context" import (
"context"
)
type TestDBRepository struct{} type TestDBRepository struct{}