aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--account.go6
-rw-r--r--backend.go8
-rw-r--r--bulk.go10
-rw-r--r--capabilities.go2
-rw-r--r--container.go4
-rw-r--r--container_iterator.go4
-rw-r--r--errors.go19
-rw-r--r--headers.go2
-rw-r--r--largeobject.go33
-rw-r--r--object.go24
-rw-r--r--object_iterator.go4
-rw-r--r--request.go2
12 files changed, 65 insertions, 53 deletions
diff --git a/account.go b/account.go
index 4277163..c101b54 100644
--- a/account.go
+++ b/account.go
@@ -25,7 +25,9 @@ import (
"regexp"
)
-//Account represents a Swift account.
+//Account represents a Swift account. Instances are usually obtained by
+//connecting to a backend (see package-level documentation), or by traversing
+//upwards from a container with Container.Account().
type Account struct {
backend Backend
//URL parts
@@ -57,7 +59,7 @@ func InitializeAccount(backend Backend) (*Account, error) {
}, nil
}
-//SwitchAccount returns a handle on a different account on the same server. Note
+//SwitchAccount returns a handle to a different account on the same server. Note
//that you need reseller permissions to access accounts other than that where
//you originally authenticated. This method does not check whether the account
//actually exists.
diff --git a/backend.go b/backend.go
index 50d8e4c..de07015 100644
--- a/backend.go
+++ b/backend.go
@@ -23,14 +23,15 @@ import (
)
//Backend is the interface between Schwift and the libraries providing
-//authentication for it.
+//authentication for it. Each instance of Backend represents a particular Swift
+//account.
type Backend interface {
//EndpointURL returns the endpoint URL from the Keystone catalog for the
//Swift account that this backend operates on. It should look like
- //`http://domain.tld/v1/AUTH_projectid/`.
+ //`http://domain.tld/v1/AUTH_projectid/`. The trailing slash is required.
EndpointURL() string
//Clone returns a deep clone of this backend with the endpoint URL changed to
- //the given URL.
+ //the given URL. This is used by Account.SwitchAccount().
Clone(newEndpointURL string) Backend
//Do executes the given HTTP request after adding to it the X-Auth-Token
//header containing the backend's current Keystone (or Swift auth) token. It
@@ -38,4 +39,5 @@ type Backend interface {
//is 401, it shall attempt to acquire a new auth token and restart the
//request with the new token.
Do(req *http.Request) (*http.Response, error)
+ //TODO add UserAgent argument to Do()
}
diff --git a/bulk.go b/bulk.go
index 2d61437..5d6304b 100644
--- a/bulk.go
+++ b/bulk.go
@@ -60,8 +60,7 @@ const (
//if some files could not be saved individually (e.g. because a quota was
//exceeded in the middle of the archive extraction).
//
-//If not nil, the error return value is *usually* an instance of
-//BulkError.
+//If not nil, the error return value is *usually* an instance of BulkError.
//
//This operation returns (0, ErrNotSupported) if the server does not support
//bulk-uploading.
@@ -125,7 +124,7 @@ func makeBulkObjectError(fullName string, statusCode int) BulkObjectError {
// var container *schwift.Container
//
// objects, err := container.Objects().Collect()
-// numDeleted, numNotFound, err := container.Account().BulkDelete(objects, nil, nil, nil)
+// numDeleted, numNotFound, err := container.Account().BulkDelete(objects, nil, nil)
//
//To also delete the container:
//
@@ -133,13 +132,12 @@ func makeBulkObjectError(fullName string, statusCode int) BulkObjectError {
//
// objects, err := container.Objects().Collect()
// numDeleted, numNotFound, err := container.Account().BulkDelete(
-// objects, []*schwift.Container{container}, nil, nil)
+// objects, []*schwift.Container{container}, nil)
//
//If the server does not support bulk-deletion, this function falls back to
//deleting each object and container individually, and aggregates the result.
//
-//If not nil, the error return value is *usually* an instance of
-//BulkError.
+//If not nil, the error return value is *usually* an instance of BulkError.
//
//The objects may be located in multiple containers, but they and the
//containers must all be located in the given account. (Otherwise,
diff --git a/capabilities.go b/capabilities.go
index aec9ef1..fab7784 100644
--- a/capabilities.go
+++ b/capabilities.go
@@ -25,7 +25,7 @@ package schwift
//
//All direct members of struct Capabilities, except for "Swift", are pointers.
//If any of these is nil, it indicates that the middleware corresponding to
-//that field is not supported on this server.
+//that field is not available on this server.
type Capabilities struct {
BulkDelete *struct {
MaximumDeletesPerRequest uint `json:"max_deletes_per_request"`
diff --git a/container.go b/container.go
index 80aeca3..6982efe 100644
--- a/container.go
+++ b/container.go
@@ -22,7 +22,9 @@ import (
"net/http"
)
-//Container represents a Swift container.
+//Container represents a Swift container. Instances are usually obtained by
+//traversing downwards from an account with Account.Container() or
+//Account.Containers(), or upwards from an object with Object.Container().
type Container struct {
a *Account
name string
diff --git a/container_iterator.go b/container_iterator.go
index debe475..73722e3 100644
--- a/container_iterator.go
+++ b/container_iterator.go
@@ -56,7 +56,7 @@ type ContainerInfo struct {
//To obtain any other metadata, you can call Container.Headers() on the result
//container, but this will issue a separate HEAD request for each container.
//
-//Use the "Detailed" methods only when you can use the extra metadata in struct
+//Use the "Detailed" methods only when you use the extra metadata in struct
//ContainerInfo; detailed GET requests are more expensive than simple ones that
//return only container names.
type ContainerIterator struct {
@@ -78,7 +78,7 @@ func (i *ContainerIterator) getBase() *iteratorBase {
}
//NextPage queries Swift for the next page of container names. If limit is
-//>= 0, not more than that container names will be returned at once. Note
+//>= 0, not more than that many container names will be returned at once. Note
//that the server also has a limit for how many containers to list in one
//request; the lower limit wins.
//
diff --git a/errors.go b/errors.go
index 2826df7..825e96a 100644
--- a/errors.go
+++ b/errors.go
@@ -40,15 +40,15 @@ var (
//etc. if the server does not support the requested operation.
ErrNotSupported = errors.New("operation not supported by this Swift server")
//ErrAccountMismatch is returned by operations on an account that accept
- //objects as arguments, if (some of) the provided objects are located in a
- //different account.
+ //containers/objects as arguments, if some or all of the provided
+ //containers/objects are located in a different account.
ErrAccountMismatch = errors.New("some of the given objects are not in this account")
//ErrContainerMismatch is returned by operations on a container that accept
- //objects as arguments, if (some of) the provided objects are located in a
- //different container.
+ //objects as arguments, if some or all of the provided objects are located in
+ //a different container.
ErrContainerMismatch = errors.New("some of the given objects are not in this container")
- //ErrNotLarge is returned by Object.AsLargeObject() if the object exists, but
- //is not a large object that is composed out of segments.
+ //ErrNotLarge is returned by Object.AsLargeObject() if the object does not
+ //exist, or if it is not a large object composed out of segments.
ErrNotLarge = errors.New("not a large object")
//ErrSegmentInvalid is returned by LargeObject.AddSegment() if the segment
//provided is malformed or uses features not supported by the LargeObject's
@@ -57,7 +57,8 @@ var (
)
//UnexpectedStatusCodeError is generated when a request to Swift does not yield
-//a response with the expected successful status code.
+//a response with the expected successful status code. The actual status code
+//can be checked with the Is() function; see documentation over there.
type UnexpectedStatusCodeError struct {
ExpectedStatusCodes []int
ActualResponse *http.Response
@@ -107,7 +108,7 @@ type BulkError struct {
//summary of which recoverable errors were encountered. It may be empty.
OverallError string
//ObjectErrors contains errors that occurred while working on individual
- //objects. It may be empty if no such errors occurred.
+ //objects or containers. It may be empty if no such errors occurred.
ObjectErrors []BulkObjectError
}
@@ -137,6 +138,8 @@ func (e BulkError) Error() string {
// return err
// }
// }
+//
+//It is safe to pass a nil error, in which case Is() always returns false.
func Is(err error, code int) bool {
if e, ok := err.(UnexpectedStatusCodeError); ok {
return e.ActualResponse.StatusCode == code
diff --git a/headers.go b/headers.go
index c1119ae..47a2f73 100644
--- a/headers.go
+++ b/headers.go
@@ -86,7 +86,7 @@ func (h Headers) ToHTTP() http.Header {
// hdr := NewObjectHeaders()
// hdr.ContentType().Set("image/png")
// hdr.Metadata().Set("color", "blue")
-// obj.Upload(content, hdr.ToOpts())
+// obj.Upload(content, nil, hdr.ToOpts())
//
func (h Headers) ToOpts() *RequestOptions {
return &RequestOptions{Headers: h}
diff --git a/largeobject.go b/largeobject.go
index 7771366..6628279 100644
--- a/largeobject.go
+++ b/largeobject.go
@@ -44,7 +44,7 @@ import (
//
//For .RangeLength == 0, the segment consists of all the bytes in the backing
//object, after skipping the first .RangeOffset bytes. The default
-//(.RangeOffset == 0) includes the entire contents of the backing object.
+//(.RangeOffset == 0) is to include the entire contents of the backing object.
//
//For .RangeLength > 0, the segment consists of that many bytes from the
//backing object, again after skipping the first .RangeOffset bytes.
@@ -79,13 +79,14 @@ type sloSegmentInfo struct {
DataBase64 string `json:"data,omitempty"`
}
-//LargeObjectStrategy is an enum of segmenting strategies supported by Swift.
+//LargeObjectStrategy enumerates segmenting strategies supported by Swift.
type LargeObjectStrategy int
-//NOTE: No valid value for LargeObjectStrategy has the numeric value 0. That
-//way, we can change the default strategy in a later version of Schwift, also
-//possibly depending on the server capabilities. A numeric value of 0 is
-//recognized by all functions taking a SegmentingOptions.
+//A value of 0 for LargeObjectStrategy will instruct Schwift to choose a
+//strategy itself. Right now, Schwift always chooses StaticLargeObject, but
+//this behavior may change in future versions of Schwift, esp. if new
+//strategies become available. The choice may also start to depend on the
+//capabilities advertised by the server.
const (
//StaticLargeObject is the default LargeObjectStrategy used by Schwift.
StaticLargeObject LargeObjectStrategy = iota + 1
@@ -96,16 +97,14 @@ const (
)
//SegmentingOptions describes how an object is segmented. It is passed to
-//Object.AsNewLargeObject(), and also to Object.Upload() when desired.
+//Object.AsNewLargeObject().
//
-//If Strategy is not set, a reasonable strategy is chosen. Right now, this is
-//always StaticLargeObject, but the choice may change in future relases, or may
-//start to depend on the Account.Capabilities().
+//If Strategy is not set, a reasonable strategy is chosen; see documentation on
+//LargeObjectStrategy for details.
//
-//SegmentContainer must not be nil. A value of nil will cause the consuming
-//method to panic. If the SegmentContainer is not in the same account as the
-//large object, ErrAccountMismatch is returned from the method consuming the
-//SegmentingOptions.
+//SegmentContainer must not be nil. A value of nil will cause Schwift to panic.
+//If the SegmentContainer is not in the same account as the large object,
+//ErrAccountMismatch will be returned by Schwift.
//
//If SegmentPrefix is empty, a reasonable default will be computed by
//Object.AsNewLargeObject(), using the format
@@ -407,9 +406,9 @@ func parseHTTPRange(str string) (offsetVal int64, lengthVal uint64, ok bool) {
//
//This function can be used regardless of whether the object exists or not.
//If the object exists and is a large object, this function behaves like
-//Object.AsLargeObject() followed by Truncate(), but segmenting options are
-//initialized from the method's SegmentingOptions argument rather than from the
-//existing manifest.
+//Object.AsLargeObject() followed by Truncate(), except that segmenting options
+//are initialized from the method's SegmentingOptions argument rather than from
+//the existing manifest.
func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOptions) (*LargeObject, error) {
//we only need to load the existing large object if we want to do something
//with the old segments
diff --git a/object.go b/object.go
index d44c152..8063caf 100644
--- a/object.go
+++ b/object.go
@@ -27,7 +27,9 @@ import (
"net/http"
)
-//Object represents a Swift object.
+//Object represents a Swift object. Instances are usually obtained by
+//traversing downwards from a container with Container.Object() or
+//Container.Objects().
type Object struct {
c *Container
name string
@@ -38,7 +40,7 @@ type Object struct {
//Object returns a handle to the object with the given name within this
//container. This function does not issue any HTTP requests, and therefore cannot
//ensure that the object exists. Use the Exists() function to check for the
-//container's existence.
+//object's existence.
func (c *Container) Object(name string) *Object {
return &Object{c: c, name: name}
}
@@ -49,8 +51,8 @@ func (o *Object) Container() *Container {
}
//Name returns the object name. This does not parse the name in any way; if you
-//want only the basename portion of the object name, use package path in
-//conjunction with this function. For example:
+//want only the basename portion of the object name, use package path from the
+//standard library in conjunction with this function. For example:
//
// obj := account.Container("docs").Object("2018-02-10/invoice.pdf")
// obj.Name() //returns "2018-02-10/invoice.pdf"
@@ -116,7 +118,7 @@ func (o *Object) Headers() (ObjectHeaders, error) {
//Update updates the object's headers using a POST request. To add URL
//parameters, pass a non-nil *RequestOptions.
//
-//This operation returns http.StatusNotFound if the object does not exist.
+//This operation fails with http.StatusNotFound if the object does not exist.
//
//A successful POST request implies Invalidate() since it may change metadata.
func (o *Object) Update(headers ObjectHeaders, opts *RequestOptions) error {
@@ -156,6 +158,10 @@ type UploadOptions struct {
//function that generates the object's content into an io.Writer, use
//UploadWithWriter instead.
//
+//If the object is very large and you want to upload it in segments, use
+//LargeObject.Append() instead. See documentation on type LargeObject for
+//details.
+//
//If content is a *bytes.Reader or a *bytes.Buffer instance, the Content-Length
//and Etag request headers will be computed automatically. Otherwise, it is
//highly recommended that the caller set these headers (if possible) to allow
@@ -398,13 +404,13 @@ func (o *Object) Invalidate() {
//for reading the object contents progressively, or whether you want the object
//contents collected into a byte slice or string.
//
-// reader, err := object.Download(nil, nil).AsReadCloser()
+// reader, err := object.Download(nil).AsReadCloser()
//
-// buf, err := object.Download(nil, nil).AsByteSlice()
+// buf, err := object.Download(nil).AsByteSlice()
//
-// str, err := object.Download(nil, nil).AsString()
+// str, err := object.Download(nil).AsString()
//
-//See struct DownloadedObject for details.
+//See documentation on type DownloadedObject for details.
func (o *Object) Download(opts *RequestOptions) DownloadedObject {
resp, err := Request{
Method: "GET",
diff --git a/object_iterator.go b/object_iterator.go
index 3df03dd..3fb5563 100644
--- a/object_iterator.go
+++ b/object_iterator.go
@@ -57,7 +57,7 @@ type ObjectInfo struct {
//To obtain any other metadata, you can call Object.Headers() on the result
//object, but this will issue a separate HEAD request for each object.
//
-//Use the "Detailed" methods only when you can use the extra metadata in struct
+//Use the "Detailed" methods only when you use the extra metadata in struct
//ObjectInfo; detailed GET requests are more expensive than simple ones that
//return only object names.
type ObjectIterator struct {
@@ -81,7 +81,7 @@ func (i *ObjectIterator) getBase() *iteratorBase {
}
//NextPage queries Swift for the next page of object names. If limit is
-//>= 0, not more than that object names will be returned at once. Note
+//>= 0, not more than that many object names will be returned at once. Note
//that the server also has a limit for how many objects to list in one
//request; the lower limit wins.
//
diff --git a/request.go b/request.go
index 3e089c0..2f86df2 100644
--- a/request.go
+++ b/request.go
@@ -26,7 +26,7 @@ import (
"strings"
)
-//RequestOptions is used to pass additional headers and values to aa request.
+//RequestOptions is used to pass additional headers and values to a request.
//
//When preparing a RequestOptions instance with additional headers, the
//preferred way is to create an AccountHeaders, ContainerHeaders and