aboutsummaryrefslogtreecommitdiff
path: root/container_iterator.go
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2018-02-16 16:41:18 +0100
committerStefan Majewsky <majewsky@gmx.net>2018-02-16 16:41:18 +0100
commit6be5f143bf7abd39129145d310980c8ab3c47203 (patch)
tree88c76325cfcf045bf4a48231d0e419c9b90b8f42 /container_iterator.go
parent403359114bf971f037e2737b43e2734a89df9f0a (diff)
downloadgo-schwift-6be5f143bf7abd39129145d310980c8ab3c47203.tar.gz
prepare ContainerIterator for sharing code with ObjectIterator
Diffstat (limited to 'container_iterator.go')
-rw-r--r--container_iterator.go119
1 files changed, 27 insertions, 92 deletions
diff --git a/container_iterator.go b/container_iterator.go
index 71c17be..8c04be6 100644
--- a/container_iterator.go
+++ b/container_iterator.go
@@ -19,13 +19,21 @@
package schwift
import (
- "encoding/json"
"fmt"
- "strconv"
- "strings"
"time"
)
+//ContainerInfo is a result type returned by ContainerIterator for detailed
+//container listings. The metadata in this type is a subset of Container.Headers(),
+//but since it is returned as part of the detailed container listing, it can be
+//obtained without making additional HEAD requests on the container(s).
+type ContainerInfo struct {
+ Container *Container
+ ObjectCount uint64
+ BytesUsed uint64
+ LastModified time.Time
+}
+
//ContainerIterator iterates over the accounts in a container. It is typically
//constructed with the Account.Containers() method. For example:
//
@@ -61,55 +69,14 @@ type ContainerIterator struct {
//Options may contain additional query parameters for the GET request.
Options *RequestOptions
- marker string
- eof bool
+ base *iteratorBase
}
-//ContainerInfo is a result type returned by ContainerIterator for detailed
-//container listings. The metadata in this type is a subset of Container.Headers(),
-//but since it is returned as part of the detailed container listing, it can be
-//obtained without making additional HEAD requests on the container(s).
-type ContainerInfo struct {
- Container *Container
- ObjectCount uint64
- BytesUsed uint64
- LastModified time.Time
-}
-
-func (i ContainerIterator) request(limit int, detailed bool) Request {
- r := Request{
- Method: "GET",
- Headers: headersToHTTP(i.Headers),
- Options: cloneRequestOptions(i.Options),
+func (i *ContainerIterator) getBase() *iteratorBase {
+ if i.base == nil {
+ i.base = &iteratorBase{i: i}
}
-
- if i.Prefix != "" {
- r.Options.Values.Set("prefix", i.Prefix)
- }
-
- if i.marker == "" {
- r.Options.Values.Del("marker")
- } else {
- r.Options.Values.Set("marker", i.marker)
- }
-
- if limit < 0 {
- r.Options.Values.Del("limit")
- } else {
- r.Options.Values.Set("limit", strconv.FormatUint(uint64(limit), 10))
- }
-
- if detailed {
- r.Headers.Set("Accept", "application/json")
- r.Options.Values.Set("format", "json")
- r.ExpectStatusCodes = []int{200}
- } else {
- r.Headers.Set("Accept", "text/plain")
- r.Options.Values.Set("format", "plain")
- r.ExpectStatusCodes = []int{200, 204}
- }
-
- return r
+ return i.base
}
//NextPage queries Swift for the next page of container names. If limit is
@@ -122,47 +89,21 @@ func (i ContainerIterator) request(limit int, detailed bool) Request {
//This method offers maximal flexibility, but most users will prefer the
//simpler interfaces offered by Collect() and Foreach().
func (i *ContainerIterator) NextPage(limit int) ([]*Container, error) {
- if i.eof {
- return nil, nil
- }
- resp, err := i.request(limit, false).Do(i.Account.client)
- if err != nil {
- return nil, err
- }
-
- buf, err := collectResponseBody(resp)
+ names, err := i.getBase().nextPage(limit)
if err != nil {
return nil, err
}
- bufStr := strings.TrimSuffix(string(buf), "\n")
- var result []*Container
- if bufStr != "" {
- names := strings.Split(bufStr, "\n")
- result = make([]*Container, len(names))
- for idx, name := range names {
- result[idx] = i.Account.Container(name)
- }
- }
- if len(result) == 0 {
- i.eof = true
- i.marker = ""
- } else {
- i.eof = false
- i.marker = result[len(result)-1].Name()
+ result := make([]*Container, len(names))
+ for idx, name := range names {
+ result[idx] = i.Account.Container(name)
}
return result, nil
}
//NextPageDetailed is like NextPage, but includes basic metadata.
func (i *ContainerIterator) NextPageDetailed(limit int) ([]ContainerInfo, error) {
- if i.eof {
- return nil, nil
- }
- resp, err := i.request(limit, true).Do(i.Account.client)
- if err != nil {
- return nil, err
- }
+ b := i.getBase()
var document []struct {
BytesUsed uint64 `json:"bytes"`
@@ -170,14 +111,14 @@ func (i *ContainerIterator) NextPageDetailed(limit int) ([]ContainerInfo, error)
LastModifiedStr string `json:"last_modified"`
Name string `json:"name"`
}
- err = json.NewDecoder(resp.Body).Decode(&document)
- closeErr := resp.Body.Close()
- if err == nil {
- err = closeErr
- }
+ err := b.nextPageDetailed(limit, &document)
if err != nil {
return nil, err
}
+ if len(document) == 0 {
+ b.setMarker("") //indicate EOF to iteratorBase
+ return nil, nil
+ }
result := make([]ContainerInfo, len(document))
for idx, data := range document {
@@ -191,13 +132,7 @@ func (i *ContainerIterator) NextPageDetailed(limit int) ([]ContainerInfo, error)
}
}
- if len(result) == 0 {
- i.eof = true
- i.marker = ""
- } else {
- i.eof = false
- i.marker = result[len(result)-1].Container.Name()
- }
+ b.setMarker(result[len(result)-1].Container.Name())
return result, nil
}