diff --git a/.gitignore b/.gitignore index ef64353..e7bc754 100644 --- a/.gitignore +++ b/.gitignore @@ -29,8 +29,6 @@ _testmain.go *.exe *.test *.prof +*.log # .Dockerfile - -logs.log -querys.log \ No newline at end of file diff --git a/go.mod b/go.mod index ce5a720..49fad85 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ go 1.19 require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-gonic/gin v1.7.7 + github.com/go-co-op/gocron v1.20.1 github.com/go-pg/pg/v10 v10.10.6 github.com/google/uuid v1.3.0 github.com/joho/godotenv v1.4.0 @@ -26,12 +27,14 @@ require ( github.com/mattn/go-isatty v0.0.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/ugorji/go/codec v1.2.6 // indirect github.com/vmihailenco/bufpool v0.1.11 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/protobuf v1.26.0 // indirect diff --git a/go.sum b/go.sum index d59347c..f56977a 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/go-co-op/gocron v1.20.1 h1:wCGabII3xf/NrrYeOzJ4voLBBtA5k7Rb99+7l/iiu+g= +github.com/go-co-op/gocron v1.20.1/go.mod h1:UqVyvM90I1q/R1qGEX6cBORI6WArLuEgYlbncLMvzRM= github.com/go-pg/pg/v10 v10.10.6 h1:1vNtPZ4Z9dWUw/TjJwOfFUbF5nEq1IkR6yG8Mq/Iwso= github.com/go-pg/pg/v10 v10.10.6/go.mod h1:GLmFXufrElQHf5uzM3BQlcfwV3nsgnHue5uzjQ6Nqxg= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= @@ -100,6 +102,8 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= @@ -109,7 +113,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -152,6 +156,8 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/pkg/api/routes.go b/pkg/api/routes.go index 8307cd2..fa1cbbf 100644 --- a/pkg/api/routes.go +++ b/pkg/api/routes.go @@ -1,12 +1,16 @@ package api import ( + "log" + "time" "wallet-api/pkg/controller" + "wallet-api/pkg/job" "wallet-api/pkg/middleware" "wallet-api/pkg/utl/common" "wallet-api/pkg/utl/configs" "github.com/gin-gonic/gin" + "github.com/go-co-op/gocron" "github.com/go-pg/pg/v10" "go.uber.org/dig" ) @@ -22,6 +26,10 @@ Initializes web api controllers and its corresponding routes. */ func Routes(s *gin.Engine, db *pg.DB) { c := dig.New() + + scheduler := gocron.NewScheduler(time.UTC) + scheduler.SetMaxConcurrentJobs(3, 1) + defer scheduler.StartAsync() ver := s.Group(configs.Prefix) routeGroups := &common.RouteGroups{ @@ -46,5 +54,13 @@ func Routes(s *gin.Engine, db *pg.DB) { c.Provide(func() *pg.DB { return db }) + c.Provide(func() *gocron.Scheduler { + return scheduler + }) + c.Provide(func() *log.Logger { + return log.Default() + }) controller.InitializeControllers(c) + job.InitializeJobs(c) + } diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 25fbb9e..ae22f1e 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -2,13 +2,14 @@ package controller import ( "fmt" - "go.uber.org/dig" "strconv" "strings" "wallet-api/pkg/model" "wallet-api/pkg/service" "wallet-api/pkg/utl/common" + "go.uber.org/dig" + "github.com/gin-gonic/gin" ) @@ -21,17 +22,18 @@ Initializes Dependency Injection modules and registers controllers *dig.Container: Dig Container */ func InitializeControllers(c *dig.Container) { - service.InitializeServices(c) + controllerContainer := c.Scope("controller") + service.InitializeServices(controllerContainer) - c.Invoke(NewApiController) - c.Invoke(NewUserController) - c.Invoke(NewWalletController) - c.Invoke(NewWalletHeaderController) - c.Invoke(NewTransactionController) - c.Invoke(NewTransactionStatusController) - c.Invoke(NewTransactionTypeController) - c.Invoke(NewSubscriptionController) - c.Invoke(NewSubscriptionTypeController) + controllerContainer.Invoke(NewApiController) + controllerContainer.Invoke(NewUserController) + controllerContainer.Invoke(NewWalletController) + controllerContainer.Invoke(NewWalletHeaderController) + controllerContainer.Invoke(NewTransactionController) + controllerContainer.Invoke(NewTransactionStatusController) + controllerContainer.Invoke(NewTransactionTypeController) + controllerContainer.Invoke(NewSubscriptionController) + controllerContainer.Invoke(NewSubscriptionTypeController) } diff --git a/pkg/job/currency.go b/pkg/job/currency.go new file mode 100644 index 0000000..8596ed9 --- /dev/null +++ b/pkg/job/currency.go @@ -0,0 +1,52 @@ +package job + +import ( + "context" + "log" + "wallet-api/pkg/service" + "wallet-api/pkg/utl/common" + + "github.com/go-co-op/gocron" +) + +type CurrencyController struct { + service *service.CurrencyService + logger *log.Logger + scheduler *gocron.Scheduler +} + +/* +NewCurrencyJob + +Initializes CurrencyJob. + + Args: + *services.CurrencyService: Currency service + *gin.RouterGroup: Gin Router Group + Returns: + *CurrencyJob: Job for "Currency" route interactions +*/ +func NewCurrencyJob(as *service.CurrencyService, scheduler *gocron.Scheduler, logger *log.Logger) *CurrencyController { + currencyScheduler := scheduler.Tag("currency") + + wc := &CurrencyController{ + service: as, + logger: logger, + scheduler: currencyScheduler, + } + + _, err := currencyScheduler.Every(1).Days().Do(wc.Sync) + common.CheckError(err) + currencyScheduler.StartAsync() + + log.Println("CurrencyJob started") + + return wc +} + +func (wc *CurrencyController) Sync() { + wc.logger.Println("CurrencyJob: Syncing currencies") + ctx := context.Background() + wc.service.Sync(ctx) + wc.logger.Println("CurrencyJob: Syncing currencies done") +} diff --git a/pkg/job/job.go b/pkg/job/job.go new file mode 100644 index 0000000..551e06b --- /dev/null +++ b/pkg/job/job.go @@ -0,0 +1,33 @@ +package job + +import ( + "log" + "os" + "wallet-api/pkg/service" + "wallet-api/pkg/utl/common" + + "go.uber.org/dig" +) + +/* +InitializeJobs + +Initializes Dependency Injection modules and registers Jobs + + Args: + *dig.Container: Dig Container +*/ +func InitializeJobs(c *dig.Container) { + file, err := os.OpenFile("job.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) + common.CheckError(err) + logger := log.New(file, "Job: ", log.Ldate|log.Ltime|log.Lshortfile) + + jobContainer := c.Scope("job") + jobContainer.Provide(func() *log.Logger { + return logger + }) + + service.InitializeServices(jobContainer) + + jobContainer.Invoke(NewCurrencyJob) +} diff --git a/pkg/migrate/10_create_table_transaction_status.go b/pkg/migrate/10_create_table_transaction_status.go index edb8232..dbb2011 100644 --- a/pkg/migrate/10_create_table_transaction_status.go +++ b/pkg/migrate/10_create_table_transaction_status.go @@ -27,7 +27,7 @@ func CreateTableTransactionStatus(db *pg.Tx) error { for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ - IfNotExists: false, + IfNotExists: true, FKConstraints: true, }) if err != nil { diff --git a/pkg/migrate/11_populate_transaction_status.go b/pkg/migrate/11_populate_transaction_status copy.go similarity index 100% rename from pkg/migrate/11_populate_transaction_status.go rename to pkg/migrate/11_populate_transaction_status copy.go diff --git a/pkg/migrate/12_create_table_currencies.go b/pkg/migrate/12_create_table_currencies.go new file mode 100644 index 0000000..2146146 --- /dev/null +++ b/pkg/migrate/12_create_table_currencies.go @@ -0,0 +1,40 @@ +package migrate + +import ( + "fmt" + "log" + "wallet-api/pkg/model" + + "github.com/go-pg/pg/v10" + "github.com/go-pg/pg/v10/orm" +) + +/* +CreateTableCurrencies + +Creates Currencies table if it does not exist. + + Args: + *pg.DB: Postgres database client + Returns: + error: Returns if there is an error with table creation +*/ +func CreateTableCurrencies(db *pg.Tx) error { + models := []interface{}{ + (*model.Currency)(nil), + } + + for _, model := range models { + err := db.Model(model).CreateTable(&orm.CreateTableOptions{ + IfNotExists: true, + FKConstraints: true, + }) + if err != nil { + log.Printf("Error creating table \"currencies\": %s", err) + return err + } else { + fmt.Println("Table \"currencies\" created successfully") + } + } + return nil +} diff --git a/pkg/migrate/3_create_table_wallets.go b/pkg/migrate/3_create_table_wallets.go index c03f296..669a5de 100644 --- a/pkg/migrate/3_create_table_wallets.go +++ b/pkg/migrate/3_create_table_wallets.go @@ -27,7 +27,7 @@ func CreateTableWallets(db *pg.Tx) error { for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ - IfNotExists: false, + IfNotExists: true, FKConstraints: true, }) if err != nil { diff --git a/pkg/migrate/4_create_table_transaction_types.go b/pkg/migrate/4_create_table_transaction_types.go index 1dd561e..d2ab3bd 100644 --- a/pkg/migrate/4_create_table_transaction_types.go +++ b/pkg/migrate/4_create_table_transaction_types.go @@ -27,7 +27,7 @@ func CreateTableTransactionTypes(db *pg.Tx) error { for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ - IfNotExists: false, + IfNotExists: true, FKConstraints: true, }) if err != nil { diff --git a/pkg/migrate/5_create_table_transactions.go b/pkg/migrate/5_create_table_transactions.go index 6cab613..e931f7d 100644 --- a/pkg/migrate/5_create_table_transactions.go +++ b/pkg/migrate/5_create_table_transactions.go @@ -27,7 +27,7 @@ func CreateTableTransactions(db *pg.Tx) error { for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ - IfNotExists: false, + IfNotExists: true, FKConstraints: true, }) if err != nil { diff --git a/pkg/migrate/6_create_table_subscription_types.go b/pkg/migrate/6_create_table_subscription_types.go index 3dd306c..bbc6e60 100644 --- a/pkg/migrate/6_create_table_subscription_types.go +++ b/pkg/migrate/6_create_table_subscription_types.go @@ -27,7 +27,7 @@ func CreateTableSubscriptionTypes(db *pg.Tx) error { for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ - IfNotExists: false, + IfNotExists: true, FKConstraints: true, }) if err != nil { diff --git a/pkg/migrate/7_create_table_subscriptions.go b/pkg/migrate/7_create_table_subscriptions.go index 9cc857a..34cafba 100644 --- a/pkg/migrate/7_create_table_subscriptions.go +++ b/pkg/migrate/7_create_table_subscriptions.go @@ -26,7 +26,7 @@ func CreateTableSubscriptions(db *pg.Tx) error { for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ - IfNotExists: false, + IfNotExists: true, FKConstraints: true, }) if err != nil { diff --git a/pkg/migrate/migrate.go b/pkg/migrate/migrate.go index 25b549b..a3fa26d 100644 --- a/pkg/migrate/migrate.go +++ b/pkg/migrate/migrate.go @@ -48,12 +48,19 @@ func Start(conn *pg.DB, version string) []error { CreateTableTransactions, }, } + migration005 := Migration{ + Version: "005", + Migrations: []interface{}{ + CreateTableCurrencies, + }, + } migrationsMap := []Migration{ migration001, migration002, migration003, migration004, + migration005, } var errors []error diff --git a/pkg/model/currency.go b/pkg/model/currency.go new file mode 100644 index 0000000..8f48d70 --- /dev/null +++ b/pkg/model/currency.go @@ -0,0 +1,63 @@ +package model + +import ( + "encoding/json" + "math" +) + +type Currency struct { + tableName struct{} `pg:"currencies,alias:currencies"` + BaseModel + Rate float32 `json:"rate", pg:"rate,default:0"` + Name string `json:"name", pg:"name,unique"` +} + +type CurrencyEdit struct { + tableName struct{} `pg:"currencies,alias:currencies"` + Id string `json:"id" form:"id"` + Rate json.Number `json:"rate", form:"rate"` + Name string `json:"name", form:"name"` +} + +type NewCurrencyBody struct { + Rate json.Number `json:"rate", form:"rate"` + Name string `json:"name", form:"name"` +} + +type ExchangeBody struct { + Base string `json:"base"` + Rates interface{} `json:"rates"` +} + +type Rate struct { + Code string `json:"code"` + Rate float64 `json:"rate"` +} + +func (body *CurrencyEdit) ToCurrency() *Currency { + rate, _ := body.Rate.Float64() + tm := new(Currency) + tm.Id = body.Id + tm.Rate = float32(math.Round(rate*100) / 100) + tm.Name = body.Name + + return tm +} + +func (body *NewCurrencyBody) ToCurrency() *Currency { + rate, _ := body.Rate.Float64() + tm := new(Currency) + tm.Init() + tm.Rate = float32(math.Round(rate*100) / 100) + tm.Name = body.Name + return tm +} + +func (body *ExchangeBody) Unmarshal(resp *[]interface{}) *ExchangeBody { + body.Base = (*resp)[3].(string) + // body.Rates = []Rate{} + // for k, v := range (*resp)[5].(map[string]interface{}) { + // body.Rates = append(body.Rates, Rate{Code: k, Rate: v.(float64)}) + // } + return body +} diff --git a/pkg/repository/currency.go b/pkg/repository/currency.go new file mode 100644 index 0000000..537f23c --- /dev/null +++ b/pkg/repository/currency.go @@ -0,0 +1,84 @@ +package repository + +import ( + "context" + "log" + "time" + "wallet-api/pkg/model" + + "github.com/go-pg/pg/v10" +) + +type CurrencyRepository struct { + db *pg.DB + logger *log.Logger +} + +func NewCurrencyRepository(db *pg.DB, logger *log.Logger) *CurrencyRepository { + return &CurrencyRepository{ + db: db, + logger: logger, + } +} + +/* +GetFirst + +Gets first row from Currency table. + + Args: + context.Context: Application context + Returns: + model.CurrencyModel: Currency object from database. +*/ +func (as CurrencyRepository) Sync(ctx context.Context, rate *model.Rate, tx *pg.Tx) *model.Currency { + currency := new(model.Currency) + currency.Name = rate.Code + + any := tx.Model(currency).Where("name = ?", rate.Code).First() + currency.Rate = float32(rate.Rate) + if any != nil { + currency.Init() + _, err := tx.Model(currency).Insert() + if err != nil { + as.logger.Println(err) + return nil + } + } else { + currency.DateUpdated = time.Now() + _, err := tx.Model(currency).WherePK().Update() + if err != nil { + as.logger.Println(err) + return nil + } + } + return currency +} + +/* +GetFirst + +Gets first row from Currency table. + + Args: + context.Context: Application context + Returns: + model.CurrencyModel: Currency object from database. +*/ +func (as CurrencyRepository) SyncBulk(ctx context.Context, rates *[]model.Rate) *[]model.Currency { + tx, _ := as.db.BeginContext(ctx) + defer tx.Rollback() + + currencies := new([]model.Currency) + + for _, r := range *rates { + currency := as.Sync(ctx, &r, tx) + if currency != nil { + *currencies = append(*currencies, *currency) + } + } + + tx.Commit() + + return currencies +} diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index 348275d..c6d844a 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -1,10 +1,11 @@ package repository import ( - "go.uber.org/dig" "wallet-api/pkg/model" "wallet-api/pkg/utl/common" + "go.uber.org/dig" + "github.com/go-pg/pg/v10" ) @@ -16,7 +17,7 @@ Initializes Dependency Injection modules for repositories Args: *dig.Container: Dig Container */ -func InitializeRepositories(c *dig.Container) { +func InitializeRepositories(c *dig.Scope) { c.Provide(NewApiRepository) c.Provide(NewSubscriptionRepository) c.Provide(NewSubscriptionTypeRepository) @@ -25,6 +26,7 @@ func InitializeRepositories(c *dig.Container) { c.Provide(NewTransactionTypeRepository) c.Provide(NewUserRepository) c.Provide(NewWalletRepository) + c.Provide(NewCurrencyRepository) } /* diff --git a/pkg/service/currency.go b/pkg/service/currency.go new file mode 100644 index 0000000..ff313eb --- /dev/null +++ b/pkg/service/currency.go @@ -0,0 +1,50 @@ +package service + +import ( + "context" + "log" + "wallet-api/pkg/model" + "wallet-api/pkg/repository" + "wallet-api/pkg/utl/common" +) + +type CurrencyService struct { + repository *repository.CurrencyRepository + logger *log.Logger +} + +func NewCurrencyService(repository *repository.CurrencyRepository, logger *log.Logger) *CurrencyService { + return &CurrencyService{ + repository: repository, + logger: logger, + } +} + +/* +GetFirst + +Gets first row from Currency table. + + Args: + context.Context: Application context + Returns: + model.CurrencyModel: Currency object from database. +*/ +func (as CurrencyService) Sync(ctx context.Context) { + resp, err := common.Fetch[model.ExchangeBody]("GET", "https://api.exchangerate-api.com/v4/latest/euro") + if err != nil { + as.logger.Println(err) + return + } + m := resp.Rates.(map[string]interface{}) + + rates := new([]model.Rate) + + for k, v := range m { + rate := new(model.Rate) + rate.Code = k + rate.Rate = v.(float64) + *rates = append(*rates, *rate) + } + as.repository.SyncBulk(ctx, rates) +} diff --git a/pkg/service/service.go b/pkg/service/service.go index 7eaa3cc..d59f9e9 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -14,7 +14,7 @@ Initializes Dependency Injection modules for services Args: *dig.Container: Dig Container */ -func InitializeServices(c *dig.Container) { +func InitializeServices(c *dig.Scope) { repository.InitializeRepositories(c) c.Provide(NewApiService) @@ -25,4 +25,5 @@ func InitializeServices(c *dig.Container) { c.Provide(NewTransactionTypeService) c.Provide(NewUserService) c.Provide(NewWalletService) + c.Provide(NewCurrencyService) } diff --git a/pkg/utl/common/common.go b/pkg/utl/common/common.go index f7a0b0c..68eab0b 100644 --- a/pkg/utl/common/common.go +++ b/pkg/utl/common/common.go @@ -1,12 +1,16 @@ package common import ( - "github.com/gin-gonic/gin" + "encoding/json" + "io" "log" "net" + "net/http" "os" "regexp" "strings" + + "github.com/gin-gonic/gin" ) type RouteGroups struct { @@ -61,3 +65,24 @@ func Find[T any](lst *[]T, callback func(item *T) bool) *T { } return nil } + +func Fetch[T any](method string, url string) (*T, error) { + req, err := http.NewRequest(method, url, nil) + if err != nil { + return nil, err + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + data := new(T) + err = json.Unmarshal(body, data) + if err != nil { + return nil, err + } + return data, nil +}