Class: CloudKit::Store

Inherits:
Object show all
Includes:
ResponseHelpers, Util
Defined in:
lib/cloudkit/store.rb

Overview

A functional storage interface with HTTP semantics and pluggable adapters.

Instance Method Summary collapse

Methods included from Util

#erb, #r, #unquote

Methods included from ResponseHelpers

#allow, #data_required, #etag_required, #internal_server_error, #invalid_entity_type, #json_create_response, #json_error, #json_error_response, #json_meta_response, #json_metadata, #response, #status_404, #status_405, #status_410, #status_412, #status_422

Constructor Details

#initialize(options) ⇒ Store

Initialize a new Store. All resources in a Store are automatically versioned.

Options

  • :collections - Array of resource collections to manage.

Example

store = CloudKit::Store.new(:collections => [:foos, :bars])

See also: Response



19
20
21
22
# File 'lib/cloudkit/store.rb', line 19

def initialize(options)
  CloudKit.setup_storage_adapter unless CloudKit.storage_adapter
  @collections = options[:collections]
end

Instance Method Details

#delete(uri, options = {}) ⇒ Object

Delete the resource specified by the URI. Requires the :etag option.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/cloudkit/store.rb', line 109

def delete(uri, options={})
  methods = methods_for_uri(uri)
  return status_405(methods) unless methods.include?('DELETE')
  return invalid_entity_type unless @collections.include?(uri.collection_type)
  return etag_required       unless options[:etag]
  resource = CloudKit::Resource.first(options.excluding(:etag).merge(:uri => uri.string))
  return status_404 unless (resource && (resource.remote_user == options[:remote_user]))
  return status_410 if resource.deleted?
  return status_412 if resource.etag != options[:etag]

  resource.delete
  archived_resource = resource.previous_version
  return json_meta_response(archived_resource.uri.string, archived_resource.etag, resource.last_modified)
end

#get(uri, options = {}) ⇒ Object

Retrieve a resource or collection of resources based on a URI.

Parameters

  • uri - URI of the resource or collection to retrieve.

  • options - See below.

Options

  • :remote_user - Optional. Scopes the dataset if provided.

  • :limit - Optional. Default is unlimited. Limit the number of records returned by a collection request.

  • :offset - Optional. Start the list of resources in a collection at offset (0-based).

  • :any - Optional. Not a literal “:any”, but any key or keys that are top level JSON keys. This is a starting point for future JSONPath/JSONQuery support.

URI Types

/cloudkit-meta
/{collection}
/{collection}/_resolved
/{collection}/{uuid}
/{collection}/{uuid}/versions
/{collection}/{uuid}/versions/_resolved
/{collection}/{uuid}/versions/{etag}

Examples

get('/cloudkit-meta')
get('/foos')
get('/foos', :remote_user => 'coltrane')
get('/foos', :limit => 100, :offset => 200)
get('/foos/123')
get('/foos/123/versions')
get('/foos/123/versions/abc')

See also: REST API



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/cloudkit/store.rb', line 56

def get(uri, options={})
  return invalid_entity_type                        if !valid_collection_type?(uri.collection_type)
  return meta                                       if uri.meta_uri?
  return resource_collection(uri, options)          if uri.resource_collection_uri?
  return resolved_resource_collection(uri, options) if uri.resolved_resource_collection_uri?
  return resource(uri, options)                     if uri.resource_uri?
  return version_collection(uri, options)           if uri.version_collection_uri?
  return resolved_version_collection(uri, options)  if uri.resolved_version_collection_uri?
  return resource_version(uri, options)             if uri.resource_version_uri?
  status_404
end

#head(uri, options = {}) ⇒ Object

Retrieve the same items as the get method, minus the content/body. Using this method on a single resource URI performs a slight optimization due to the way CloudKit stores its ETags and Last-Modified information on write.



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/cloudkit/store.rb', line 72

def head(uri, options={})
  return invalid_entity_type unless @collections.include?(uri.collection_type)
  if uri.resource_uri? || uri.resource_version_uri?
    # ETag and Last-Modified are already stored for single items, so a slight
    # optimization can be made for HEAD requests.
    result = CloudKit::Resource.first(options.merge(:uri => uri.string))
    return status_404.head unless result
    return status_410.head if result.deleted?
    return response(200, '', result.etag, result.last_modified)
  else
    get(uri, options).head
  end
end

#http_methodsObject

Return the list of HTTP methods supported by this Store.



182
183
184
# File 'lib/cloudkit/store.rb', line 182

def http_methods
  ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS']
end

#implements?(http_method) ⇒ Boolean

Return true if this store implements a given HTTP method.

Returns:

  • (Boolean)


177
178
179
# File 'lib/cloudkit/store.rb', line 177

def implements?(http_method)
  http_methods.include?(http_method.upcase)
end

#meta_methodsObject

Return the list of methods allowed for the cloudkit-meta URI.



142
143
144
# File 'lib/cloudkit/store.rb', line 142

def meta_methods
  @meta_methods ||= http_methods.excluding('POST', 'PUT', 'DELETE')
end

#methods_for_uri(uri) ⇒ Object

Return a list of allowed methods for a given URI.



131
132
133
134
135
136
137
138
139
# File 'lib/cloudkit/store.rb', line 131

def methods_for_uri(uri)
  return meta_methods                         if uri.meta_uri?
  return resource_collection_methods          if uri.resource_collection_uri?
  return resolved_resource_collection_methods if uri.resolved_resource_collection_uri?
  return resource_methods                     if uri.resource_uri?
  return version_collection_methods           if uri.version_collection_uri?
  return resolved_version_collection_methods  if uri.resolved_version_collection_uri?
  return resource_version_methods             if uri.resource_version_uri?
end

#options(uri) ⇒ Object

Build a response containing the allowed methods for a given URI.



125
126
127
128
# File 'lib/cloudkit/store.rb', line 125

def options(uri)
  methods = methods_for_uri(uri)
  allow(methods)
end

#post(uri, options = {}) ⇒ Object

Create a resource in a given collection.



100
101
102
103
104
105
106
# File 'lib/cloudkit/store.rb', line 100

def post(uri, options={})
  methods = methods_for_uri(uri)
  return status_405(methods) unless methods.include?('POST')
  return invalid_entity_type unless @collections.include?(uri.collection_type)
  return data_required       unless options[:json]
  create_resource(uri, options)
end

#put(uri, options = {}) ⇒ Object

Update or create a resource at the specified URI. If the resource already exists, an :etag option is required.



88
89
90
91
92
93
94
95
96
97
# File 'lib/cloudkit/store.rb', line 88

def put(uri, options={})
  methods = methods_for_uri(uri)
  return status_405(methods) unless methods.include?('PUT')
  return invalid_entity_type unless @collections.include?(uri.collection_type)
  return data_required       unless options[:json]
  current_resource = resource(uri, options.excluding(:json, :etag, :remote_user))
  return update_resource(uri, options) if current_resource.status == 200
  return current_resource if current_resource.status == 410
  create_resource(uri, options)
end

#resolve_uris(uris) ⇒ Object

Return an array containing the response for each URI in a list.



187
188
189
190
191
192
193
# File 'lib/cloudkit/store.rb', line 187

def resolve_uris(uris) # TODO - remove if no longer needed
  result = []
  uris.each do |uri|
    result << get(uri)
  end
  result
end

#resolved_resource_collection_methodsObject

Return the list of methods allowed on a resolved resource collection.



152
153
154
# File 'lib/cloudkit/store.rb', line 152

def resolved_resource_collection_methods
  @resolved_resource_collection_methods ||= http_methods.excluding('POST', 'PUT', 'DELETE')
end

#resolved_version_collection_methodsObject

Return the list of methods allowed on a resolved version history collection.



167
168
169
# File 'lib/cloudkit/store.rb', line 167

def resolved_version_collection_methods
  @resolved_version_collection_methods ||= http_methods.excluding('POST', 'PUT', 'DELETE')
end

#resource_collection_methodsObject

Return the list of methods allowed for a resource collection.



147
148
149
# File 'lib/cloudkit/store.rb', line 147

def resource_collection_methods
  @resource_collection_methods ||= http_methods.excluding('PUT', 'DELETE')
end

#resource_methodsObject

Return the list of methods allowed on an individual resource.



157
158
159
# File 'lib/cloudkit/store.rb', line 157

def resource_methods
  @resource_methods ||= http_methods.excluding('POST')
end

#resource_version_methodsObject

Return the list of methods allowed on a resource version.



172
173
174
# File 'lib/cloudkit/store.rb', line 172

def resource_version_methods
  @resource_version_methods ||= http_methods.excluding('POST', 'PUT', 'DELETE')
end

#storage_adapterObject



195
196
197
# File 'lib/cloudkit/store.rb', line 195

def storage_adapter
  CloudKit.storage_adapter
end

#versionObject

Return the version number of this Store.



200
# File 'lib/cloudkit/store.rb', line 200

def version; 1; end

#version_collection_methodsObject

Return the list of methods allowed on a version history collection.



162
163
164
# File 'lib/cloudkit/store.rb', line 162

def version_collection_methods
  @version_collection_methods ||= http_methods.excluding('POST', 'PUT', 'DELETE')
end