PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/nt/bptree/pager/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
nt / bptree / pager
Files
4 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/nt/bptree/pager/v0
gno
0.9

Files (4)

  • gnomod.tomltoml
  • pager.gnogno
  • example_test.gnogno
  • pager_test.gnogno
pager.gnogno
1package pager23import (4	"math"5	"net/url"6	"strconv"78	"gno.land/p/nt/bptree/rotree/v0"9	"gno.land/p/nt/ufmt/v0"10)1112// Pager is a struct that holds the B+ tree and pagination parameters.13type Pager struct {14	Tree            rotree.IReadOnlyTree15	PageQueryParam  string16	SizeQueryParam  string17	DefaultPageSize int18	Reversed        bool19}2021// Page represents a single page of results.22type Page struct {23	Items      []Item24	PageNumber int25	PageSize   int26	TotalItems int27	TotalPages int28	HasPrev    bool29	HasNext    bool30	Pager      *Pager // Reference to the parent Pager31}3233// Item represents a key-value pair in the B+ tree.34type Item struct {35	Key   string36	Value any37}3839// NewPager creates a new Pager with default values.40func NewPager(tree rotree.IReadOnlyTree, defaultPageSize int, reversed bool) *Pager {41	return &Pager{42		Tree:            tree,43		PageQueryParam:  "page",44		SizeQueryParam:  "size",45		DefaultPageSize: defaultPageSize,46		Reversed:        reversed,47	}48}4950// GetPage retrieves a page of results from the B+ tree.51func (p *Pager) GetPage(pageNumber int) *Page {52	return p.GetPageWithSize(pageNumber, p.DefaultPageSize)53}5455func (p *Pager) GetPageWithSize(pageNumber, pageSize int) *Page {56	totalItems := p.Tree.Size()57	totalPages := int(math.Ceil(float64(totalItems) / float64(pageSize)))5859	page := &Page{60		TotalItems: totalItems,61		TotalPages: totalPages,62		PageSize:   pageSize,63		Pager:      p,64	}6566	// pages without content67	if pageSize < 1 {68		return page69	}7071	// page number provided is not available72	if pageNumber < 1 {73		page.HasNext = totalPages > 074		return page75	}7677	// page number provided is outside the range of total pages78	if pageNumber > totalPages {79		page.PageNumber = pageNumber80		page.HasPrev = pageNumber > 081		return page82	}8384	startIndex := (pageNumber - 1) * pageSize85	endIndex := startIndex + pageSize86	if endIndex > totalItems {87		endIndex = totalItems88	}8990	items := []Item{}9192	if p.Reversed {93		p.Tree.ReverseIterateByOffset(startIndex, endIndex-startIndex, func(key string, value any) bool {94			items = append(items, Item{Key: key, Value: value})95			return false96		})97	} else {98		p.Tree.IterateByOffset(startIndex, endIndex-startIndex, func(key string, value any) bool {99			items = append(items, Item{Key: key, Value: value})100			return false101		})102	}103104	page.Items = items105	page.PageNumber = pageNumber106	page.HasPrev = pageNumber > 1107	page.HasNext = pageNumber < totalPages108	return page109}110111func (p *Pager) MustGetPageByPath(rawURL string) *Page {112	page, err := p.GetPageByPath(rawURL)113	if err != nil {114		panic("invalid path")115	}116	return page117}118119// GetPageByPath retrieves a page of results based on the query parameters in the URL path.120func (p *Pager) GetPageByPath(rawURL string) (*Page, error) {121	pageNumber, pageSize, err := p.ParseQuery(rawURL)122	if err != nil {123		return nil, err124	}125	return p.GetPageWithSize(pageNumber, pageSize), nil126}127128// Picker generates the Markdown UI for the page Picker129func (p *Page) Picker(path string) string {130	pageNumber := p.PageNumber131	pageNumber = max(pageNumber, 1)132133	if p.TotalPages <= 1 {134		return ""135	}136137	u, _ := url.Parse(path)138	query := u.Query()139140	// Remove existing page query parameter141	query.Del(p.Pager.PageQueryParam)142143	// Encode remaining query parameters144	baseQuery := query.Encode()145	if baseQuery != "" {146		baseQuery = "&" + baseQuery147	}148	md := ""149150	if p.HasPrev {151		md += ufmt.Sprintf("[%d](?%s=%d%s) | ", 1, p.Pager.PageQueryParam, 1, baseQuery)152153		if p.PageNumber > 4 {154			md += "… | "155		}156157		if p.PageNumber > 3 {158			md += ufmt.Sprintf("[%d](?%s=%d%s) | ", p.PageNumber-2, p.Pager.PageQueryParam, p.PageNumber-2, baseQuery)159		}160161		if p.PageNumber > 2 {162			md += ufmt.Sprintf("[%d](?%s=%d%s) | ", p.PageNumber-1, p.Pager.PageQueryParam, p.PageNumber-1, baseQuery)163		}164	}165166	if p.PageNumber > 0 && p.PageNumber <= p.TotalPages {167		md += ufmt.Sprintf("**%d**", p.PageNumber)168	} else {169		md += ufmt.Sprintf("_%d_", p.PageNumber)170	}171172	if p.HasNext {173		if p.PageNumber < p.TotalPages-1 {174			md += ufmt.Sprintf(" | [%d](?%s=%d%s)", p.PageNumber+1, p.Pager.PageQueryParam, p.PageNumber+1, baseQuery)175		}176177		if p.PageNumber < p.TotalPages-2 {178			md += ufmt.Sprintf(" | [%d](?%s=%d%s)", p.PageNumber+2, p.Pager.PageQueryParam, p.PageNumber+2, baseQuery)179		}180181		if p.PageNumber < p.TotalPages-3 {182			md += " | …"183		}184185		md += ufmt.Sprintf(" | [%d](?%s=%d%s)", p.TotalPages, p.Pager.PageQueryParam, p.TotalPages, baseQuery)186	}187188	return md189}190191// ParseQuery parses the URL to extract the page number and page size.192func (p *Pager) ParseQuery(rawURL string) (int, int, error) {193	u, err := url.Parse(rawURL)194	if err != nil {195		return 1, p.DefaultPageSize, err196	}197198	query := u.Query()199	pageNumber := 1200	pageSize := p.DefaultPageSize201202	if p.PageQueryParam != "" {203		if pageStr := query.Get(p.PageQueryParam); pageStr != "" {204			pageNumber, err = strconv.Atoi(pageStr)205			if err != nil || pageNumber < 1 {206				pageNumber = 1207			}208		}209	}210211	if p.SizeQueryParam != "" {212		if sizeStr := query.Get(p.SizeQueryParam); sizeStr != "" {213			pageSize, err = strconv.Atoi(sizeStr)214			if err != nil || pageSize < 1 {215				pageSize = p.DefaultPageSize216			}217		}218	}219220	return pageNumber, pageSize, nil221}222223func max(a, b int) int {224	if a > b {225		return a226	}227	return b228}229

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.