func handleEntries(w http.ResponseWriter, r *http.Request) {
	ctx := context.Background()
	filter := fmt.Sprintf(`logName = "projects/%s/logs/testlog"`, *projectID)
	it := client.Entries(ctx, logadmin.Filter(filter))
	var entries []*logging.Entry
	nextTok, err := iterator.NewPager(it, 5, r.URL.Query().Get("pageToken")).NextPage(&entries)
	if err != nil {
		http.Error(w, fmt.Sprintf("problem getting the next page: %v", err), http.StatusInternalServerError)
		return
	}
	data := struct {
		Entries []*logging.Entry
		Next    string
	}{
		entries,
		nextTok,
	}
	var buf bytes.Buffer
	if err := pageTemplate.Execute(&buf, data); err != nil {
		http.Error(w, fmt.Sprintf("problem executing page template: %v", err), http.StatusInternalServerError)
	}
	if _, err := buf.WriteTo(w); err != nil {
		log.Printf("writing response: %v", err)
	}
}
Example #2
0
// Test the iterator's behavior when used with iterator.Pager.
func testPaging(vWant reflect.Value, create func() interface{}, next func(interface{}) (interface{}, error)) (string, bool) {
	// Test page sizes that are smaller, equal to, and greater than the length
	// of the expected sequence.
	for _, pageSize := range []int{1, 2, vWant.Len(), vWant.Len() + 10} {
		wantPages := wantedPages(vWant, pageSize)
		// Test the Pager in two ways.
		// First, by creating a single Pager and calling NextPage in a loop,
		// ignoring the page token except for detecting the end of the
		// iteration.
		it := create().(iterator.Pageable)
		pager := iterator.NewPager(it, pageSize, "")
		msg, ok := testPager(fmt.Sprintf("ignore page token, pageSize %d", pageSize),
			vWant.Type(), wantPages,
			func(_ string, pagep interface{}) (string, error) {
				return pager.NextPage(pagep)
			})
		if !ok {
			return msg, false
		}
		// Second, by creating a new Pager for each page, passing in the page
		// token from the previous page, as would be done in a web handler.
		it = create().(iterator.Pageable)
		msg, ok = testPager(fmt.Sprintf("use page token, pageSize %d", pageSize),
			vWant.Type(), wantPages,
			func(pageToken string, pagep interface{}) (string, error) {
				return iterator.NewPager(it, pageSize, pageToken).NextPage(pagep)
			})
		if !ok {
			return msg, false
		}
	}
	return "", true
}
Example #3
0
// Verify that, for an iterator that uses PageInfo.next to implement its Next
// method, using Next and NextPage together result in an error.
func TestNextWithNextPage(t *testing.T) {
	client := &Client{&service{end: 11}}
	var items []int

	// Calling Next before NextPage.
	it := client.Items(ctx)
	it.Next()
	_, err := iterator.NewPager(it, 1, "").NextPage(&items)
	if err == nil {
		t.Error("NextPage after Next: got nil, want error")
	}
	_, err = it.Next()
	if err == nil {
		t.Error("Next after NextPage: got nil, want error")
	}

	// Next between two calls to NextPage.
	it = client.Items(ctx)
	p := iterator.NewPager(it, 1, "")
	p.NextPage(&items)
	_, err = it.Next()
	if err == nil {
		t.Error("Next after NextPage: got nil, want error")
	}
	_, err = p.NextPage(&items)
	if err == nil {
		t.Error("second NextPage after Next: got nil, want error")
	}
}
Example #4
0
// Verify that we turn various potential reflection panics into errors.
func TestNextPageReflectionErrors(t *testing.T) {
	client := &Client{&service{end: 1}}
	p := iterator.NewPager(client.Items(ctx), 1, "")

	// Passing the nil interface value.
	_, err := p.NextPage(nil)
	if err == nil {
		t.Error("nil: got nil, want error")
	}

	// Passing a non-slice.
	_, err = p.NextPage(17)
	if err == nil {
		t.Error("non-slice: got nil, want error")
	}

	// Passing a slice of the wrong type.
	var bools []bool
	_, err = p.NextPage(&bools)
	if err == nil {
		t.Error("wrong type: got nil, want error")
	}

	// Using a slice of the right type, but not passing a pointer to it.
	var ints []int
	_, err = p.NextPage(ints)
	if err == nil {
		t.Error("not a pointer: got nil, want error")
	}
}
Example #5
0
// The example demonstrates how to use a Pager to request a page from a given token.
func Example_pageToken() {
	const pageSize = 5
	const pageToken = "1337"
	p := iterator.NewPager(Primes(0), pageSize, pageToken)

	var items []int
	nextPage, err := p.NextPage(&items)
	if err != nil {
		log.Fatalf("Iterator paging failed: %v", err)
	}
	fmt.Printf("Primes: %v\nToken:  %q\n", items, nextPage)
	// Output:
	// Primes: [1361 1367 1373 1381 1399]
	// Token:  "1400"
}
Example #6
0
// This example demonstrates how to use a Pager to page through an iterator in a loop.
func Example_pageLoop() {
	const pageSize = 25
	ctx := context.Background()
	p := iterator.NewPager(client.Items(ctx), pageSize, "" /* start from the beginning */)
	for {
		var items []int
		pageToken, err := p.NextPage(&items)
		if err != nil {
			// TODO: handle error.
		}
		fmt.Println(items)
		if pageToken == "" {
			break
		}
	}
}
Example #7
0
func TestPager(t *testing.T) {
	const pageSize = 4
	for _, svc := range []service{
		{end: 0},
		{end: 3},
		{end: 3, zeroes: true},
		{end: 11},
		{end: 11, max: 2},
		{end: 11, zeroes: true},
		{end: 11, max: 2, zeroes: true},
	} {
		var want [][]int
		switch svc.end {
		case 0:
			want = nil
		case 3:
			want = [][]int{{0, 1, 2}}
		case 11:
			want = [][]int{{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10}}
		default:
			t.Fatalf("unexpected svc.end %d", svc.end)
		}
		client := &Client{&svc}
		it := client.Items(ctx)
		p := iterator.NewPager(it, pageSize, "")
		var got [][]int
		for {
			var items []int
			tok, err := p.NextPage(&items)
			if err != nil {
				t.Fatalf("%v: %v", svc, err)
			}
			if tok != "" || len(items) != 0 { // edge case: 0-length sequence
				got = append(got, items)
			}
			if tok == "" {
				break
			}
		}
		if !reflect.DeepEqual(got, want) {
			t.Errorf("%v: got %v, want %v", svc, got, want)
		}
	}
}
Example #8
0
// This example demonstrates how to use a Pager to page through an iterator in a loop.
func Example_pageLoop() {
	// Find all primes up to 42, in pages of size 5.
	const max = 42
	const pageSize = 5
	p := iterator.NewPager(Primes(max), pageSize, "" /* start from the beginning */)
	for page := 0; ; page++ {
		var items []int
		pageToken, err := p.NextPage(&items)
		if err != nil {
			log.Fatalf("Iterator paging failed: %v", err)
		}
		fmt.Printf("Page %d: %v\n", page, items)
		if pageToken == "" {
			break
		}
	}
	// Output:
	// Page 0: [2 3 5 7 11]
	// Page 1: [13 17 19 23 29]
	// Page 2: [31 37 41]
}
Example #9
0
// This example demonstrates how to use Pager to support
// pagination on a web site.
func Example_webHandler(w http.ResponseWriter, r *http.Request) {
	const pageSize = 25
	it := client.Items(ctx)
	var items []int
	pageToken, err := iterator.NewPager(it, pageSize, r.URL.Query().Get("pageToken")).NextPage(&items)
	if err != nil {
		http.Error(w, fmt.Sprintf("getting next page: %v", err), http.StatusInternalServerError)
	}
	data := struct {
		Items []int
		Next  string
	}{
		items,
		pageToken,
	}
	var buf bytes.Buffer
	if err := pageTemplate.Execute(&buf, data); err != nil {
		http.Error(w, fmt.Sprintf("executing page template: %v", err), http.StatusInternalServerError)
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if _, err := buf.WriteTo(w); err != nil {
		log.Printf("writing response: %v", err)
	}
}