package page_test import ( "context" "errors" "fmt" "github.com/stephenafamo/bob" "github.com/stephenafamo/bob/dialect/sqlite" sd "github.com/stephenafamo/bob/dialect/sqlite/dialect" "github.com/stephenafamo/bob/dialect/sqlite/sm" "github.com/stephenafamo/bob/expr" "github.com/stephenafamo/scan" "go.auvem.com/corestack/page" ) func Example() { ctx := context.Background() db, err := bob.Open("sqlite3", ":memory:") if err != nil { panic(err) } defer db.Close() db.SetMaxOpenConns(1) if _, err := db.ExecContext(ctx, "CREATE TABLE orders (id BIGINT PRIMARY KEY, priority BIGINT NOT NULL, tenant BIGINT NOT NULL)"); err != nil { panic(err) } if _, err := db.ExecContext(ctx, "INSERT INTO orders VALUES (1,10,7),(2,10,7),(3,5,7),(4,20,8)"); err != nil { panic(err) } type Order struct { ID int64 Priority int64 } sort := page.Sort{ID: "orders/priority/v1", Columns: []page.Column{ {Expression: expr.Quote("priority"), Direction: page.Desc}, {Expression: expr.Quote("id"), Direction: page.Asc, Unique: true}, }} // With Bob-generated models, use their column references for these expressions. // The key must independently match their order and actual stored value types. key := func(o Order) []any { return []any{o.Priority, o.ID} } p, err := page.Prepare(sort, key, page.Request{Size: 2}, page.Limits{Default: 2, Maximum: 100}) if err != nil { panic(err) } q := sqlite.Select(sm.Columns("id", "priority"), sm.From("orders"), page.Mod[*sd.SelectQuery](p)) q.Apply(sm.Where(sqlite.Quote("tenant").EQ(sqlite.Arg(int64(7))))) rows, err := bob.All(ctx, db, q, scan.StructMapper[Order]()) if err != nil { panic(err) } result, err := p.Page(rows) if err != nil { panic(err) } fmt.Println(result.Items, result.HasNext, result.HasPrevious) // Continue with Forward + result.EndCursor, or Backward + result.StartCursor. // A mismatched key returns no partial Page, including for an overflow row. bad, err := page.Prepare(sort, func(o Order) []any { return []any{o.ID} }, page.Request{}, page.Limits{Default: 2, Maximum: 100}) if err != nil { panic(err) } _, err = bad.Page(rows) var keyError *page.KeyError fmt.Println(errors.As(err, &keyError), keyError.Expected, keyError.Actual) // Output: // [{1 10} {2 10}] true false // true 2 1 }