diff --git a/golang/config/initializers.config.go b/golang/config/initializers.config.go index ec38af3..645c0bb 100644 --- a/golang/config/initializers.config.go +++ b/golang/config/initializers.config.go @@ -38,7 +38,7 @@ func InitLogger(appName string) { zerolog.SetGlobalLevel(zerolog.DebugLevel) } - if utils.IsLocalEnv() { + if utils.IsLocalEnv() || utils.IsDevelopmentEnv() { log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) } else { writer := &loggers.InfoDebugWriter{ diff --git a/golang/gql/float32.gqlScalar.go b/golang/gql/float32.gqlScalar.go index ec77e5e..8e568f4 100644 --- a/golang/gql/float32.gqlScalar.go +++ b/golang/gql/float32.gqlScalar.go @@ -5,6 +5,8 @@ import ( "fmt" "math" "strconv" + + "github.com/rs/zerolog/log" ) type Float32 float32 @@ -19,7 +21,7 @@ func (f *Float32) UnmarshalGraphQL(input interface{}) error { case float32: *f = Float32(v) case float64: - if v < -math.MaxFloat64 || v > math.MaxFloat64 { + if v < -math.MaxFloat32 || v > math.MaxFloat32 { return fmt.Errorf("value out of range for float32") } *f = Float32(v) @@ -32,9 +34,14 @@ func (f *Float32) UnmarshalGraphQL(input interface{}) error { case int32: *f = Float32(v) case int64: - if v < math.MinInt64 || v > math.MaxInt64 { + if float64(v) < -math.MaxFloat32 || float64(v) > math.MaxFloat32 { return fmt.Errorf("value out of range for float32") } + + if v < -16777216 || v > 16777216 { + log.Warn().Int64("value", v).Msg("Warning: value may lose precision in float32") + } + *f = Float32(v) case uint8: *f = Float32(v) @@ -43,9 +50,14 @@ func (f *Float32) UnmarshalGraphQL(input interface{}) error { case uint32: *f = Float32(v) case uint64: - if v > ^uint64(0) { + if float64(v) > float64(math.MaxFloat32) { return fmt.Errorf("value out of range for float32") } + + if v > 16777216 { + log.Warn().Uint64("value", v).Msg("Warning: value may lose precision in float32") + } + *f = Float32(v) case json.Number: val, err := v.Float64() diff --git a/golang/gql/metadata.payload.go b/golang/gql/metadata.payload.go new file mode 100644 index 0000000..2923c5c --- /dev/null +++ b/golang/gql/metadata.payload.go @@ -0,0 +1,45 @@ +package gql + +import ( + "github.com/BehemothLtd/behemoth-pkg/golang/pagination" +) + +type MetadataPayload struct { + Metadata pagination.Metadata +} + +func (mt *MetadataPayload) Total() *Uint32 { + return (*Uint32)(&mt.Metadata.Total) +} + +func (mt *MetadataPayload) PerPage() *Uint32 { + return (*Uint32)(&mt.Metadata.PerPage) +} + +func (mt *MetadataPayload) Page() *Uint32 { + return (*Uint32)(&mt.Metadata.Page) +} + +func (mt *MetadataPayload) Pages() *Uint32 { + return (*Uint32)(&mt.Metadata.Pages) +} + +func (mt *MetadataPayload) Count() *Uint32 { + return (*Uint32)(&mt.Metadata.Count) +} + +func (mt *MetadataPayload) Next() *Uint32 { + return (*Uint32)(&mt.Metadata.Next) +} + +func (mt *MetadataPayload) Prev() *Uint32 { + return (*Uint32)(&mt.Metadata.Prev) +} + +func (mt *MetadataPayload) From() *Uint32 { + return (*Uint32)(&mt.Metadata.From) +} + +func (mt *MetadataPayload) To() *Uint32 { + return (*Uint32)(&mt.Metadata.To) +} diff --git a/golang/gql/pagy.input.go b/golang/gql/pagy.input.go new file mode 100644 index 0000000..711093a --- /dev/null +++ b/golang/gql/pagy.input.go @@ -0,0 +1,32 @@ +package gql + +import ( + "github.com/BehemothLtd/behemoth-pkg/golang/pagination" +) + +type PagyInput struct { + PerPage *int32 + Page *int32 +} + +// ToPaginationInput converts PagyInput to models.PaginationData. +func ToPaginationInput[T any](input *PagyInput) pagination.PaginationData[T] { + paginationInput := pagination.PaginationData[T]{ + Metadata: pagination.Metadata{ + Page: 1, + PerPage: 10, + }, + } + + if input != nil { + if input.Page != nil && *input.Page >= 1 { + paginationInput.Metadata.Page = uint32(*input.Page) + } + + if input.PerPage != nil && *input.PerPage >= 1 { + paginationInput.Metadata.PerPage = uint32(*input.PerPage) + } + } + + return paginationInput +} diff --git a/golang/pagination/pagination.go b/golang/pagination/pagination.go index 0ccfb5c..e421b41 100644 --- a/golang/pagination/pagination.go +++ b/golang/pagination/pagination.go @@ -24,12 +24,12 @@ type Metadata struct { To uint32 } -type PaginationData struct { +type PaginationData[T any] struct { Metadata Metadata - Collection interface{} + Collection T } -func Paginate(ctx context.Context, db *gorm.DB, p *PaginationData, tableName string) (func(db *gorm.DB) *gorm.DB, error) { +func Paginate[T any](ctx context.Context, db *gorm.DB, p *PaginationData[T], tableName string) (func(db *gorm.DB) *gorm.DB, error) { log.Debug().Ctx(ctx).Msg("pagination.Paginate") // Create a new session to avoid side effects @@ -37,7 +37,9 @@ func Paginate(ctx context.Context, db *gorm.DB, p *PaginationData, tableName str // Calculate the total number of records var totalRecords uint32 - dbClone.Select(fmt.Sprintf("COUNT(DISTINCT %s.id)", tableName)).Scan(&totalRecords) + if err := dbClone.Select(fmt.Sprintf("COUNT(DISTINCT %s.id)", tableName)).Scan(&totalRecords).Error; err != nil { + return nil, err + } // Update pagination metadata p.Metadata.Total = totalRecords