Skip to content

Commit

Permalink
- Now server does not store rates for equivalent currencies on bulk s…
Browse files Browse the repository at this point in the history
…ymbols requests. fix #1
  • Loading branch information
netandreus committed Sep 13, 2021
1 parent d96aa3b commit 3454cd5
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ Generate API docs in folder "api"
$HOME/go/bin/swag init --output=./api
```

You can test API here: ```http://localhost/swagger/index.html```
You can test API here: ```http://localhost:9090/swagger/index.html```

## Godoc
You can run ```Go Documentation Server``` with actual version of documentation with this command:
Expand Down
1 change: 1 addition & 0 deletions configs/config.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ providers:
rates_generated_time: 23:59
supported_currencies: ["AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BRL", "BSD", "BTC", "BTN", "BWP", "BYN", "BYR", "BZD", "CAD", "CDF", "CHF", "CLF", "CLP", "CNY", "COP", "CRC", "CUC", "CUP", "CVE", "CZK", "DJF", "DKK", "DOP", "DZD", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GGP", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "IMP", "INR", "IQD", "IRR", "ISK", "JEP", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL", "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "STD", "SVC", "SYP", "SZL", "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU", "UZS", "VEF", "VND", "VUV", "WST", "XAF", "XAG", "XAU", "XCD", "XDR", "XOF", "XPF", "YER", "ZAR", "ZMK", "ZMW", "ZWL"]
historical_preload: false
historical_start_date: "2000-05-31"
api_key: xxxx
15 changes: 9 additions & 6 deletions internal/pkg/cache/store/MySQLStore.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Package cache_store use for custom store for caching historical currency rates
package cache_store
// Package cachestore use for custom store for caching historical currency rates
package cachestore

import (
"encoding/json"
"github.com/eko/gocache/store"
"github.com/netandreus/go-forex-rates/internal/pkg/custom_errors"
"github.com/netandreus/go-forex-rates/internal/pkg/customerror"
"github.com/netandreus/go-forex-rates/internal/pkg/entity"
"github.com/netandreus/go-forex-rates/internal/pkg/model"
"github.com/netandreus/go-forex-rates/internal/pkg/util"
Expand Down Expand Up @@ -117,7 +117,7 @@ func (store *MySQLStore) loadByKey(serviceRequest model.RatesRequest) (string, e

// Latest data does not stored in database
if serviceRequest.Endpoint == util.EndpointLatest {
return "", custom_errors.NewNotFoundError("Value not found in MySQLCache store")
return "", customerror.NewNotFoundError("Value not found in MySQLCache store")
}

// Remove base currency from symbols
Expand All @@ -137,11 +137,11 @@ func (store *MySQLStore) loadByKey(serviceRequest model.RatesRequest) (string, e
Where("rate_date = ?", serviceRequest.Date.Format(util.DateFormatEu)).
Find(&entities)
if result.Error != nil {
return "", custom_errors.NewDatabaseError(result.Error.Error())
return "", customerror.NewDatabaseError(result.Error.Error())
}
symbolsCount := int64(len(symbols))
if result.RowsAffected < symbolsCount {
return "", custom_errors.NewNotFoundError("Value not found in MySQLCache store")
return "", customerror.NewNotFoundError("Value not found in MySQLCache store")
}
// Provider generated time
providerGeneratedTime = entities[0].ProviderGeneratedTime
Expand All @@ -166,6 +166,9 @@ func (store *MySQLStore) loadByKey(serviceRequest model.RatesRequest) (string, e
// saveByKey uses internally for save to database
func (store *MySQLStore) saveByKey(key model.RatesRequest, value model.RatesResponse) error {
for quotedCurrency, rate := range value.Rates {
if key.BaseCurrency == quotedCurrency {
continue
}
entity := &entity.CurrencyRate{
Endpoint: key.Endpoint,
BaseCurrency: key.BaseCurrency, // Base currency
Expand Down
18 changes: 18 additions & 0 deletions internal/pkg/customerror/BadRequestError.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package customerror

// BadRequestError represents bad RatesRequest error
type BadRequestError struct {
message string
}

// Error returns error message
func (m *BadRequestError) Error() string {
return m.message
}

// NewBadRequestError error constructor
func NewBadRequestError(message string) *BadRequestError {
return &BadRequestError{
message: message,
}
}
18 changes: 18 additions & 0 deletions internal/pkg/customerror/DatabaseError.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package customerror

// DatabaseError represents database error
type DatabaseError struct {
message string
}

// Error returns error message
func (m *DatabaseError) Error() string {
return m.message
}

// NewDatabaseError error constructor
func NewDatabaseError(message string) *DatabaseError {
return &DatabaseError{
message: message,
}
}
18 changes: 18 additions & 0 deletions internal/pkg/customerror/NotFoundError.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package customerror

// NotFoundError is rates not found error
type NotFoundError struct {
message string
}

// Error returns error message
func (m *NotFoundError) Error() string {
return m.message
}

// NewNotFoundError error constructor
func NewNotFoundError(message string) *NotFoundError {
return &NotFoundError{
message: message,
}
}
6 changes: 5 additions & 1 deletion internal/pkg/model/FailedApiResponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type ApiError struct {
Info string `json:"info"`
}

// FailedApiResponse response, when error occured
// FailedApiResponse response, when error occurred
type FailedApiResponse struct {
// Success Returns true or false depending on whether or not your API request has succeeded.
Success bool `json:"success"`
Expand All @@ -26,19 +26,23 @@ func NewFailedApiResponse(code int, info string) *FailedApiResponse {
}
}

// GetSuccess returns Success value
func (a *FailedApiResponse) GetSuccess() bool {
return a.Success
}

// SetSuccess sets Success value
func (a *FailedApiResponse) SetSuccess(success bool) *FailedApiResponse {
a.Success = success
return a
}

// GetError returns Error value
func (a *FailedApiResponse) GetError() ApiError {
return a.Error
}

// SetError sets Error value
func (a *FailedApiResponse) SetError(e ApiError) *FailedApiResponse {
a.Error = e
return a
Expand Down
9 changes: 5 additions & 4 deletions internal/pkg/provider/emirates/Provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"encoding/json"
"errors"
"github.com/PuerkitoBio/goquery"
"github.com/netandreus/go-forex-rates/internal/pkg/custom_errors"
"github.com/netandreus/go-forex-rates/internal/pkg/customerror"
"github.com/netandreus/go-forex-rates/internal/pkg/entity"
"github.com/netandreus/go-forex-rates/internal/pkg/model"
"github.com/netandreus/go-forex-rates/internal/pkg/provider"
Expand All @@ -24,6 +24,7 @@ import (
// Code emirates provider code
const Code = "emirates"

// ApiResponse is Emirates service http api response
type ApiResponse struct {
// HTML table in json field
Table string `json:"table"`
Expand Down Expand Up @@ -100,7 +101,7 @@ func (p Provider) GetHistoricalRates(serviceRequest model.RatesRequest) (model.R
} else {
serviceResponse.Rates = make(map[string]float64)
serviceResponse.Timestamp = providerGeneratedTime.Unix()
return serviceResponse, custom_errors.NewBadRequestError("base currency should be AED, or symbols should be [AED]")
return serviceResponse, customerror.NewBadRequestError("base currency should be AED, or symbols should be [AED]")
}
}

Expand Down Expand Up @@ -184,8 +185,8 @@ func (p Provider) filterRates(rates map[string]float64, baseCurrency string, sym
// fetchHistoricalRatesAllSymbols - fetches directRates and reverseRates. Return normalized (scale=6) rates
func (p Provider) fetchHistoricalRatesAllSymbols(date string) (map[string]float64, map[string]float64, time.Time, error) {
var (
directRates = make(map[string]float64)
reverseRates = make(map[string]float64)
directRates map[string]float64
reverseRates map[string]float64
providerDate time.Time
err error
resp *http.Response
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/provider/fixer/Provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func New(db *gorm.DB, config *model.ApplicationConfig) *Provider {
func (p Provider) GetHistoricalRates(serviceRequest model.RatesRequest) (model.RatesResponse, error) {
var (
err error
rates = make(map[string]float64)
rates map[string]float64
providerGeneratedTime time.Time
resp *http.Response
body []byte
Expand Down Expand Up @@ -81,7 +81,7 @@ func (p Provider) GetLatestRates(serviceRequest model.RatesRequest) (model.Rates
var (
serviceResponse model.RatesResponse
err error
rates = make(map[string]float64)
rates map[string]float64
providerGeneratedTime time.Time
resp *http.Response
body []byte
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/util/constants.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package util

// All project constants
const (
DateFormatEu string = "2006-01-02"
DateFormatRu = "02-01-2006"
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/util/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"
)

// ToFixed rounds passed num to target precision.
func ToFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output
Expand Down

0 comments on commit 3454cd5

Please sign in to comment.