Skip to content

Commit

Permalink
Merge pull request #98 from sev-2/feature/paginate
Browse files Browse the repository at this point in the history
enhance functionality
  • Loading branch information
toopay authored Mar 3, 2025
2 parents dc497cf + 40d667a commit 0c758d7
Show file tree
Hide file tree
Showing 29 changed files with 1,296 additions and 102 deletions.
21 changes: 16 additions & 5 deletions controller.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package raiden

import (
"context"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -305,7 +306,7 @@ func (rc RestController) Patch(ctx Context) error {
return err
}

if err1 := Validate(model); err1 != nil {
if err1 := Validate(ctx.RequestContext(), model); err1 != nil {
return err1
}

Expand All @@ -328,7 +329,7 @@ func (rc RestController) Post(ctx Context) error {
return err
}

if err1 := Validate(model); err1 != nil {
if err1 := Validate(ctx.RequestContext(), model); err1 != nil {
return err1
}

Expand All @@ -343,7 +344,7 @@ func (rc RestController) Put(ctx Context) error {
return err
}

if err1 := Validate(model); err1 != nil {
if err1 := Validate(ctx.RequestContext(), model); err1 != nil {
return err1
}

Expand Down Expand Up @@ -562,7 +563,11 @@ func MarshallAndValidate(ctx *fasthttp.RequestCtx, controller any) error {
}

// validate marshalled payload
if err := Validate(payloadPtr); err != nil {
reqContext := context.WithValue(
context.Background(),
MethodContextKey, string(ctx.Request.Header.Method()),
)
if err := Validate(reqContext, payloadPtr); err != nil {
return err
}

Expand Down Expand Up @@ -602,8 +607,14 @@ func setPayloadValue(fieldValue reflect.Value, value string) error {
return fmt.Errorf("%s : must be integer value", fieldValue.Type().Name())
}
fieldValue.SetInt(int64(intValue))
case reflect.Ptr:
// Handle pointer types
if fieldValue.IsNil() {
fieldValue.Set(reflect.New(fieldValue.Type().Elem())) // Allocate new value
}
return setPayloadValue(fieldValue.Elem(), value)
default:
return fmt.Errorf("%s : unsupported field type %s", fieldValue.Type().Name(), fieldValue.Kind())
fieldValue.SetZero()
}

return nil
Expand Down
23 changes: 23 additions & 0 deletions controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,29 @@ func TestMarshallAndValidate(t *testing.T) {

}

func TestMarshallAndValidate_ByMethod(t *testing.T) {
ctx := newMockCtx()
type Request struct {
Search string `query:"q"`
Resource string `json:"resource" validate:"requiredForMethod=Post"`
}
type Controller struct {
raiden.ControllerBase
Payload *Request
}
controller := &Controller{}

ctx.Request.Header.SetMethod(fasthttp.MethodGet)
ctx.SetBodyString("{\"resource\":\"\"}")

err := raiden.MarshallAndValidate(ctx.RequestContext(), controller)
assert.NoError(t, err)

ctx.Request.Header.SetMethod(fasthttp.MethodPost)
err = raiden.MarshallAndValidate(ctx.RequestContext(), controller)
assert.Error(t, err)
}

func TestController_PassDataRestPost(t *testing.T) {
var reqCtx fasthttp.RequestCtx
context := raiden.Ctx{
Expand Down
26 changes: 9 additions & 17 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"errors"
"fmt"
"reflect"
"strconv"
"strings"
"time"

"github.com/sev-2/raiden/pkg/logger"
Expand All @@ -15,7 +13,6 @@ import (

var (
headerContentTypeJson = []byte("application/json")
httpClientInstance Client
DefaultTimeout = time.Duration(20000) * time.Millisecond
Logger = logger.HcLog().Named("supabase.client")
)
Expand Down Expand Up @@ -43,29 +40,20 @@ type DefaultResponse struct {
Message string `json:"message"`
}

func getClient() Client {
var DefaultGetClientFn = func() Client {
maxIdleConnDuration := time.Hour * 1

httpClientInstance = &fasthttp.Client{
return &fasthttp.Client{
ReadTimeout: DefaultTimeout,
WriteTimeout: DefaultTimeout,
MaxIdleConnDuration: maxIdleConnDuration,
NoDefaultUserAgentHeader: true,
DisableHeaderNamesNormalizing: true,
DisablePathNormalizing: true,
MaxConnWaitTimeout: DefaultTimeout,
Dial: (&fasthttp.TCPDialer{
Concurrency: 4096,
DNSCacheDuration: time.Hour,
}).Dial,
}

return httpClientInstance
}

func SetClient(c Client) {
httpClientInstance = c
}
var GetClientFn = DefaultGetClientFn

func SendRequest(method string, url string, body []byte, timeout time.Duration, reqInterceptor RequestInterceptor, resInterceptor ResponseInterceptor) (rawBody []byte, err error) {
reqTimeout := DefaultTimeout
Expand Down Expand Up @@ -94,7 +82,7 @@ func SendRequest(method string, url string, body []byte, timeout time.Duration,
Logger.Trace("request", "headers", string(req.Header.Header()))
Logger.Trace("request", "body", string(req.Body()))

err = getClient().DoTimeout(req, resp, reqTimeout)
err = GetClientFn().DoTimeout(req, resp, reqTimeout)
if err != nil {
logger.HcLog().Error("[SendRequest][DoTimeout]", "err-type", reflect.TypeOf(err).String(), "err-msg", err.Error())
return
Expand All @@ -115,7 +103,11 @@ func SendRequest(method string, url string, body []byte, timeout time.Duration,

statusCode := resp.StatusCode()

if !strings.HasPrefix(strconv.Itoa(statusCode), "2") {
Logger.Trace("response", "statusCode", statusCode)
Logger.Trace("response", "header", resp.Header.String())
Logger.Trace("response", "body", string(resp.Body()))

if statusCode > 399 {
err = fmt.Errorf("invalid HTTP response code: %d", statusCode)
if resp.Body() != nil && len(resp.Body()) > 0 {
Logger.Error(string(resp.Body()))
Expand Down
22 changes: 6 additions & 16 deletions pkg/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,29 @@ import (
"time"

"github.com/sev-2/raiden/pkg/client"
"github.com/sev-2/raiden/pkg/mock"
"github.com/stretchr/testify/assert"
"github.com/valyala/fasthttp"
)

type MockClient struct {
DoFn func(*fasthttp.Request, *fasthttp.Response) error
DoTimeoutFn func(*fasthttp.Request, *fasthttp.Response, time.Duration) error
}

func (m *MockClient) Do(req *fasthttp.Request, rest *fasthttp.Response) error {
return m.DoFn(req, rest)
}

func (m *MockClient) DoTimeout(req *fasthttp.Request, rest *fasthttp.Response, timeout time.Duration) error {
return m.DoTimeoutFn(req, rest, timeout)
}

func TestSendRequest(t *testing.T) {
t.Parallel()

c := MockClient{
c := mock.MockClient{
DoTimeoutFn: func(r1 *fasthttp.Request, r2 *fasthttp.Response, d time.Duration) error {
r2.SetBodyRaw([]byte("{ \"message\": \"hello from home\" }"))
return nil
},
}

client.SetClient(&c)
client.GetClientFn = func() client.Client {
return &c
}

type Response struct {
Message string `json:"message"`
}

rs, _ := client.Get[Response]("http://localhost:8080", 1000000, nil, nil)
assert.Equal(t, "", rs.Message)
assert.Equal(t, "hello from home", rs.Message)
}
4 changes: 4 additions & 0 deletions pkg/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ func (q Query) Single(model interface{}) error {
return nil
}

func (q Query) GetQueryURI() string {
return buildQueryURI(q)
}

func (q Query) GetUrl() string {
urlQuery := buildQueryURI(q)

Expand Down
10 changes: 9 additions & 1 deletion pkg/generator/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,15 @@ func MapTableAttributes(projectName string, table objects.Table, mapDataType map
importPackageName = "encoding/json"
}

if column.Type == "postgres.Point" || column.Type == "*postgres.Point" {
// custom type
postgresCustomTypes := map[string]bool{
"postgres.Point": true,
"*postgres.Point": true,
"postgres.DateTime": true,
"*postgres.DateTime": true,
}

if postgresCustomTypes[column.Type] {
importPackageName = "github.com/sev-2/raiden/pkg/postgres"
}

Expand Down
4 changes: 0 additions & 4 deletions pkg/generator/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ func (r *{{.Name | ToGoIdentifier }}) Enums() []string {
return {{ .Enums }}
}
func (r *{{.Name | ToGoIdentifier }}) Attributes() []string {
return {{ .Attributes }}
}
func (r *{{.Name | ToGoIdentifier }}) Comment() *string {
return {{ .Comment }}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/generator/type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestGenerateTypes(t *testing.T) {
Schema: "public",
Format: "",
Enums: []string{"test_1", "test_2"},
Attributes: []string{},
Attributes: []objects.TypeAttribute{},
Comment: nil,
},
}
Expand Down
20 changes: 20 additions & 0 deletions pkg/mock/fasthttp_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package mock

import (
"time"

"github.com/valyala/fasthttp"
)

type MockClient struct {
DoFn func(*fasthttp.Request, *fasthttp.Response) error
DoTimeoutFn func(*fasthttp.Request, *fasthttp.Response, time.Duration) error
}

func (m *MockClient) Do(req *fasthttp.Request, rest *fasthttp.Response) error {
return m.DoFn(req, rest)
}

func (m *MockClient) DoTimeout(req *fasthttp.Request, rest *fasthttp.Response, timeout time.Duration) error {
return m.DoTimeoutFn(req, rest, timeout)
}
13 changes: 13 additions & 0 deletions pkg/paginate/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package paginate

import (
"context"
)

type Item map[string]any

type Driver interface {
Paginate(ctx context.Context, statement string, page, limit int, withCount bool) (data []Item, cont int, err error)
CursorPaginateNext(ctx context.Context, statement string, cursorRefColumn string, cursor any, limit int, withCount bool) (data []Item, count int, prevCursor any, nextCursor any, err error)
CursorPaginatePrev(ctx context.Context, statement string, cursorRefColumn string, cursor any, limit int, withCount bool) (data []Item, count int, prevCursor any, nextCursor any, err error)
}
Loading

0 comments on commit 0c758d7

Please sign in to comment.