You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

105 lines
2.9 KiB

  1. // Copyright 2018 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package firestore
  15. import (
  16. "context"
  17. vkit "cloud.google.com/go/firestore/apiv1"
  18. "google.golang.org/api/iterator"
  19. pb "google.golang.org/genproto/googleapis/firestore/v1"
  20. )
  21. // DocumentRefIterator is an interator over DocumentRefs.
  22. type DocumentRefIterator struct {
  23. client *Client
  24. it *vkit.DocumentIterator
  25. pageInfo *iterator.PageInfo
  26. nextFunc func() error
  27. items []*DocumentRef
  28. err error
  29. }
  30. func newDocumentRefIterator(ctx context.Context, cr *CollectionRef, tid []byte) *DocumentRefIterator {
  31. client := cr.c
  32. req := &pb.ListDocumentsRequest{
  33. Parent: cr.parentPath,
  34. CollectionId: cr.ID,
  35. ShowMissing: true,
  36. Mask: &pb.DocumentMask{}, // empty mask: we want only the ref
  37. }
  38. if tid != nil {
  39. req.ConsistencySelector = &pb.ListDocumentsRequest_Transaction{tid}
  40. }
  41. it := &DocumentRefIterator{
  42. client: client,
  43. it: client.c.ListDocuments(withResourceHeader(ctx, client.path()), req),
  44. }
  45. it.pageInfo, it.nextFunc = iterator.NewPageInfo(
  46. it.fetch,
  47. func() int { return len(it.items) },
  48. func() interface{} { b := it.items; it.items = nil; return b })
  49. return it
  50. }
  51. // PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
  52. func (it *DocumentRefIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }
  53. // Next returns the next result. Its second return value is iterator.Done if there
  54. // are no more results. Once Next returns Done, all subsequent calls will return
  55. // Done.
  56. func (it *DocumentRefIterator) Next() (*DocumentRef, error) {
  57. if err := it.nextFunc(); err != nil {
  58. return nil, err
  59. }
  60. item := it.items[0]
  61. it.items = it.items[1:]
  62. return item, nil
  63. }
  64. func (it *DocumentRefIterator) fetch(pageSize int, pageToken string) (string, error) {
  65. if it.err != nil {
  66. return "", it.err
  67. }
  68. return iterFetch(pageSize, pageToken, it.it.PageInfo(), func() error {
  69. docProto, err := it.it.Next()
  70. if err != nil {
  71. return err
  72. }
  73. docRef, err := pathToDoc(docProto.Name, it.client)
  74. if err != nil {
  75. return err
  76. }
  77. it.items = append(it.items, docRef)
  78. return nil
  79. })
  80. }
  81. // GetAll returns all the DocumentRefs remaining from the iterator.
  82. func (it *DocumentRefIterator) GetAll() ([]*DocumentRef, error) {
  83. var drs []*DocumentRef
  84. for {
  85. dr, err := it.Next()
  86. if err == iterator.Done {
  87. break
  88. }
  89. if err != nil {
  90. return nil, err
  91. }
  92. drs = append(drs, dr)
  93. }
  94. return drs, nil
  95. }