pilagod / gorm-cursor-paginator

A paginator doing cursor-based pagination based on GORM
https://github.com/pilagod/gorm-cursor-paginator
MIT License
188 stars 44 forks source link

How to encode cursor from given element. #59

Closed emfomy closed 5 months ago

emfomy commented 6 months ago

How to encode a cursor with given db element.

From the source code, it seems like the Paginator uses encodeCursor and getEncoderFields to generate cursor.

However, these functions are private.

What is the correct way to do so?

Or could you expose encodeCursor method?

pilagod commented 5 months ago

Does db element mean model struct? If you need to encode cursor manually, maybe you can refer to the cursor package:

import (
    "github.com/pilagod/gorm-cursor-paginator/v2/cursor"
)

Both encoder and decoder are included in there. You can check the test cases for detailed usage:

https://github.com/pilagod/gorm-cursor-paginator/blob/master/cursor/encoding_test.go

emfomy commented 5 months ago

Thanks for replying!

But how do I initialize the encoder from a paginator? The paginator uses getEncoderFields to initialize the encoder. Iā€™m finding a way to initialize the encoder without copying the code from getEncoderFields.

pilagod commented 5 months ago

For encoder, it only needs to specify the keys you want to encode on model, for instance:

type Model struct {
    Value    string
}
encoder := NewEncoder([]EncoderField{{ Key: "Value" }})

cursor, err := encoder.Encode(Model{ Value: "Hello" })

It sounds like that you want to reuse the same fields configured on paginator. In this case, why not just let paginator encode the cursor for you?

If you could provide a rough example for the situation you are encountering, I could get a better understanding to your concerns šŸ™‚

emfomy commented 5 months ago

Here is my situation:

We have a list of posts paginated by the paginator. Some of the posts contains audio.

When the client use clicked a post with audio, we want to open a new page and start playing audio.

Here we need a new API that list posts with audio, and paginated start from the clicked post.

Therefore, we want to encode the cursor of each post in the first API, and use the cursor to call the second API.

pilagod commented 5 months ago

I got your point, thanks for the details šŸ™Œ

I have came up a way that might be helpful to your situation, I think maybe we could extract constructing encoder/decoder code in paginator to a standalone, public methods.

The current version:

https://github.com/pilagod/gorm-cursor-paginator/blob/057bf3d1a93569d2486a60deab39c1028de4fd93/paginator/paginator.go#L258

to:

func (p *Paginator) GetCursorEncoder() *cursor.Encoder {
    return cursor.NewEncoder(p.getEncoderFields())
}

func (p *Paginator) encodeCursor(...) {
    encoder := p.GetCursorEncoder()
    // ...
}

and you can get the corresponding encoder/decoder from the outside of paginator like

p := NewPaginator(...)
encoder := p.GetCursorEncoder()

Do you think this refinement works for you? If it's ok, then I will take this way. šŸ™‚

emfomy commented 5 months ago

It looks great to me šŸ˜Š

pilagod commented 5 months ago

@emfomy I just did the refinement in #60, and released a new version v2.5.0. You can give it a try šŸ’Ŗ