diff options
| author | Stefan Majewsky <majewsky@gmx.net> | 2018-02-04 23:29:09 +0100 |
|---|---|---|
| committer | Stefan Majewsky <majewsky@gmx.net> | 2018-02-04 23:29:09 +0100 |
| commit | fafac750baa70812432020784cc5ba2cc23224cc (patch) | |
| tree | 2b0100470a44a7db1550fc7989257c35c5ac808d /container.go | |
| parent | 698cd6aaf4e4fd235d5af904376c89f8faf177f7 (diff) | |
| download | go-schwift-fafac750baa70812432020784cc5ba2cc23224cc.tar.gz | |
add Container
Diffstat (limited to 'container.go')
| -rw-r--r-- | container.go | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/container.go b/container.go new file mode 100644 index 0000000..9fcfe2b --- /dev/null +++ b/container.go @@ -0,0 +1,172 @@ +/****************************************************************************** +* +* Copyright 2018 Stefan Majewsky <majewsky@gmx.net> +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +******************************************************************************/ + +package schwift + +import ( + "net/http" +) + +//Container represents a Swift container. +type Container struct { + a *Account + name string + //cache + headers *ContainerHeaders +} + +//Container returns a handle to the container with the given name within this +//account. This function does not issue any HTTP requests, and therefore cannot +//ensure that the container exists. Use the Exists() function to check for the +//container's existence, or chain this function with the EnsureExists() +//function like so: +// +// container, err := account.Container("documents").EnsureExists() +func (a *Account) Container(name string) *Container { + return &Container{a: a, name: name} +} + +//Account returns a handle to the account this container is stored in. +func (c *Container) Account() *Account { + return c.a +} + +//Name returns the container name. +func (c *Container) Name() string { + return c.name +} + +//Exists checks if this container exists, potentially by issuing a HEAD request +//if no Headers() have been cached yet. +func (c *Container) Exists() (bool, error) { + _, err := c.Headers() + if Is(err, http.StatusNotFound) { + return false, nil + } else if err != nil { + return false, err + } + return true, nil +} + +//Headers returns the ContainerHeaders for this account. If the ContainerHeaders +//has not been cached yet, a HEAD request is issued on the account. +func (c *Container) Headers() (ContainerHeaders, error) { + if c.headers != nil { + return *c.headers, nil + } + + resp, err := Request{ + Method: "HEAD", + ContainerName: c.name, + ExpectStatusCodes: []int{204}, + }.Do(c.a.client) + if err != nil { + return ContainerHeaders{}, err + } + + var headers ContainerHeaders + err = parseHeaders(resp.Header, &headers) + if err != nil { + return ContainerHeaders{}, err + } + c.headers = &headers + return *c.headers, nil +} + +//Update updates the container using a POST request. To set arbitrary request +//headers (and to add URL parameters), pass a non-nil *RequestOptions. +// +//If you are not sure whether the container exists, use Create() instead. +// +//A successful POST request implies Invalidate() since it may change metadata. +func (c *Container) Update(headers ContainerHeaders, opts *RequestOptions) error { + _, err := Request{ + Method: "POST", + ContainerName: c.name, + Options: compileHeaders(&headers, opts), + ExpectStatusCodes: []int{204}, + }.Do(c.a.client) + if err == nil { + c.Invalidate() + } + return err +} + +//Create creates the container using a PUT request. To set arbitrary request +//headers (and to add URL parameters), pass a non-nil *RequestOptions. +// +//This function can be used regardless of whether the container exists or not. +// +//A successful PUT request implies Invalidate() since it may change metadata. +func (c *Container) Create(headers ContainerHeaders, opts *RequestOptions) error { + _, err := Request{ + Method: "PUT", + ContainerName: c.name, + Options: compileHeaders(&headers, opts), + ExpectStatusCodes: []int{201, 202}, + }.Do(c.a.client) + if err == nil { + c.Invalidate() + } + return err +} + +//Delete deletes the container using a DELETE request. To set arbitrary request +//headers (and to add URL parameters), pass a non-nil *RequestOptions. +// +//This operation fails with http.StatusConflict if the container is not empty. +// +//This operation fails with http.StatusNotFound if the container does not exist. +// +//A successful DELETE request implies Invalidate(). +func (c *Container) Delete(headers ContainerHeaders, opts *RequestOptions) error { + _, err := Request{ + Method: "DELETE", + ContainerName: c.name, + Options: compileHeaders(&headers, opts), + ExpectStatusCodes: []int{204}, + }.Do(c.a.client) + if err == nil { + c.Invalidate() + } + return err +} + +//Invalidate clears the internal cache of this Container instance. The next call +//to Headers() on this instance will issue a HEAD request on the account. +func (c *Container) Invalidate() { + c.headers = nil +} + +//EnsureExists issues a PUT request on this container. +//If the container does not exist yet, it will be created by this call. +//If the container exists already, this call does not change it. +//This function returns the same container again, because its intended use is +//with freshly constructed Container instances like so: +// +// container, err := account.Container("documents").EnsureExists() +func (c *Container) EnsureExists() (*Container, error) { + _, err := Request{ + Method: "PUT", + ContainerName: c.name, + ExpectStatusCodes: []int{201, 202}, + }.Do(c.a.client) + return c, err +} + +// TODO object listing |
