github.com/stripe/stripe-go/v76@v76.25.0/search_iter.go (about)

     1  package stripe
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/stripe/stripe-go/v76/form"
     7  )
     8  
     9  //
    10  // Public constants
    11  //
    12  
    13  // Contains constants for the names of parameters used for pagination in search APIs.
    14  const (
    15  	Page = "page"
    16  )
    17  
    18  //
    19  // Public types
    20  //
    21  
    22  // SearchIter provides a convenient interface
    23  // for iterating over the elements
    24  // returned from paginated search API calls.
    25  // Successive calls to the Next method
    26  // will step through each item in the search results,
    27  // fetching pages of items as needed.
    28  // Iterators are not thread-safe, so they should not be consumed
    29  // across multiple goroutines.
    30  type SearchIter struct {
    31  	cur             interface{}
    32  	err             error
    33  	formValues      *form.Values
    34  	searchContainer SearchContainer
    35  	searchParams    SearchParams
    36  	meta            *SearchMeta
    37  	query           SearchQuery
    38  	values          []interface{}
    39  }
    40  
    41  // Current returns the most recent item
    42  // visited by a call to Next.
    43  func (it *SearchIter) Current() interface{} {
    44  	return it.cur
    45  }
    46  
    47  // Err returns the error, if any,
    48  // that caused the SearchIter to stop.
    49  // It must be inspected
    50  // after Next returns false.
    51  func (it *SearchIter) Err() error {
    52  	return it.err
    53  }
    54  
    55  // SearchResult returns the current search result container which the iterator is currently using.
    56  // Objects will change as new API calls are made to continue pagination.
    57  func (it *SearchIter) SearchResult() SearchContainer {
    58  	return it.searchContainer
    59  }
    60  
    61  // Meta returns the search metadata.
    62  func (it *SearchIter) Meta() *SearchMeta {
    63  	return it.meta
    64  }
    65  
    66  // Next advances the SearchIter to the next item in the search results,
    67  // which will then be available
    68  // through the Current method.
    69  // It returns false when the iterator stops
    70  // at the end of the search results.
    71  func (it *SearchIter) Next() bool {
    72  	if len(it.values) == 0 && it.meta.HasMore && !it.searchParams.Single {
    73  		if it.meta.NextPage != nil {
    74  			it.formValues.Set(Page, *it.meta.NextPage)
    75  			it.getPage()
    76  		}
    77  	}
    78  	if len(it.values) == 0 {
    79  		return false
    80  	}
    81  	it.cur = it.values[0]
    82  	it.values = it.values[1:]
    83  	return true
    84  }
    85  
    86  func (it *SearchIter) getPage() {
    87  	it.values, it.searchContainer, it.err = it.query(it.searchParams.GetParams(), it.formValues)
    88  	it.meta = it.searchContainer.GetSearchMeta()
    89  }
    90  
    91  // SearchQuery is the function used to get search results.
    92  type SearchQuery func(*Params, *form.Values) ([]interface{}, SearchContainer, error)
    93  
    94  //
    95  // Public functions
    96  //
    97  
    98  // GetSearchIter returns a new SearchIter for a given query and its options.
    99  func GetSearchIter(container SearchParamsContainer, query SearchQuery) *SearchIter {
   100  	var searchParams *SearchParams
   101  	formValues := &form.Values{}
   102  
   103  	if container != nil {
   104  		reflectValue := reflect.ValueOf(container)
   105  
   106  		// See the comment on Call in stripe.go.
   107  		if reflectValue.Kind() == reflect.Ptr && !reflectValue.IsNil() {
   108  			searchParams = container.GetSearchParams()
   109  			form.AppendTo(formValues, container)
   110  		}
   111  	}
   112  
   113  	if searchParams == nil {
   114  		searchParams = &SearchParams{}
   115  	}
   116  	iter := &SearchIter{
   117  		formValues:   formValues,
   118  		searchParams: *searchParams,
   119  		query:        query,
   120  	}
   121  
   122  	iter.getPage()
   123  
   124  	return iter
   125  }